/*=============================================================================#
 # Copyright (c) 2005, 2020 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.ltk.ui.wizards;

import java.util.Iterator;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImSet;

import org.eclipse.statet.ecommons.ui.SharedMessages;
import org.eclipse.statet.ecommons.ui.components.StatusInfo;
import org.eclipse.statet.ecommons.ui.util.LayoutUtils;
import org.eclipse.statet.ecommons.ui.workbench.ContainerSelectionComposite;
import org.eclipse.statet.ecommons.ui.workbench.ContainerSelectionComposite.ContainerFilter;


/**
 * Standard main page for a wizard that creates a file resource.
 * <p>
 * This page may be used by clients as-is; it may be also be subclassed to suit.
 * </p>
 * <p>
 * Subclasses may override
 * <ul>
 *   <li><code>getInitialContents</code></li>
 *   <li><code>getNewFileLabel</code></li>
 * </ul>
 * </p>
 * <p>
 * Subclasses may extend
 * <ul>
 *   <li><code>handleEvent</code></li>
 * </ul>
 * </p>
 */
public abstract class NewElementWizardPage extends WizardPage {
	
	
	protected static class ProjectNatureContainerFilter extends ContainerFilter {
		
		private final ImSet<String> natureIds;
		
		public ProjectNatureContainerFilter(final ImSet<String> natureIds) {
			this.natureIds= natureIds;
		}
		
		public ProjectNatureContainerFilter(final String natureId) {
			this.natureIds= ImCollections.newSet(natureId);
		}
		
		@Override
		public boolean select(final IContainer container) {
			try {
				final IProject project= container.getProject();
				for (final String natureId : this.natureIds) {
					if (!project.hasNature(natureId)) {
						return false;
					}
				}
				return true;
			}
			catch (final CoreException e) {
				return false;
			}
		}
		
	}
	
	
	public class ResourceGroup implements Listener {
		
		private static final int SIZING_CONTAINER_GROUP_HEIGHT= 250;
		private static final String DIALOGSETTING_ENABLEFILTER= "org.eclipse.statet.base.NewElementWizard.ContainerFilter"; //$NON-NLS-1$
		
		
		private final String resourceNameDefaultSuffix;
		private final ContainerFilter containerFilter;
		
		private ContainerSelectionComposite containerGroup;
		private Text resourceNameControl;
		
		private IPath containerFullPath;
		private String resourceName;
		private boolean resourceNameEdited;
		
		
		public ResourceGroup(final String defaultResourceNameExtension,
				final ContainerFilter containerFilter) {
			this.resourceNameDefaultSuffix= defaultResourceNameExtension;
			this.containerFilter= containerFilter;
		}
		
		
		public void createGroup(final Composite parent) {
			final Composite composite= new Composite(parent, SWT.NONE);
			composite.setLayout(LayoutUtils.newCompositeGrid(2));
			
			// resource and container group
			this.containerGroup= new ContainerSelectionComposite(
					composite, true, false,
					null, SIZING_CONTAINER_GROUP_HEIGHT );
			this.containerGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
			
			this.containerGroup.setListener(this);
			boolean enableFilter= true;
			if (getDialogSettings().get(DIALOGSETTING_ENABLEFILTER) != null) {
				enableFilter= getDialogSettings().getBoolean(DIALOGSETTING_ENABLEFILTER);
			}
			this.containerGroup.setToggleFilter(this.containerFilter, enableFilter);
			
			{	final Label label= new Label(composite, SWT.LEFT);
				label.setText(getNewFileLabel());
				label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
				
				final Text input= new Text(composite, SWT.SINGLE | SWT.BORDER);
				input.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
				this.resourceNameControl= input;
				this.resourceNameControl.addListener(SWT.Modify, this);
			}
			
			composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
			
			initFields();
		}
		
		/**
		 * Returns the label to display in the file name specification visual
		 * component group.
		 * <p>
		 * Subclasses may reimplement.
		 * </p>
		 * 
		 * @return the label to display in the file name specification visual
		 *     component group
		 */
		protected String getNewFileLabel() {
			return LTKWizardsMessages.ResourceGroup_NewFile_label;
		}
		
		/**
		 * Sets the initial contents of the container name entry field, based upon
		 * either a previously-specified initial value or the ability to determine
		 * such a value.
		 */
		protected void initFields() {
			IPath path= null;
			
			if (this.containerFullPath != null) {
				path= this.containerFullPath;
			}
			else {
				final Iterator<?> it= NewElementWizardPage.this.resourceSelection.iterator();
				if (it.hasNext()) {
					final Object object= it.next();
					IResource selectedResource= null;
					if (object instanceof IResource) {
						selectedResource= (IResource) object;
					} else if (object instanceof IAdaptable) {
						selectedResource= ((IAdaptable) object).getAdapter(IResource.class);
					}
					if (selectedResource != null) {
						if (selectedResource.getType() == IResource.FILE) {
							selectedResource= selectedResource.getParent();
						}
						if (selectedResource.isAccessible()) {
							path= selectedResource.getFullPath();
						}
					}
				}
			}
			if (path != null) {
				this.containerGroup.selectContainer(path);
			}
			
			if (this.resourceName != null) {
				this.resourceNameControl.setText(this.resourceName);
			}
		}
		
		@Override
		public void handleEvent(final Event event) {
			this.containerFullPath= this.containerGroup.getContainerFullPath();
			final String name=  this.resourceNameControl.getText();
			if (!this.resourceNameEdited && event.widget == this.resourceNameControl
					&& name.length() > 0 && !name.equals(this.resourceName)) {
				this.resourceNameEdited= true;
			}
			this.resourceName= name;
			
			validatePage();
		}
		
//		/**
//		 * Sets the value of this page's container name field, or stores
//		 * it for future use if this page's controls do not exist yet.
//		 * 
//		 * @param path the full path to the container
//		 */
//		public void setContainerFullPath(IPath path) {
//			if (fResourceGroup != null)
//				fResourceGroup.setContainerFullPath(path); // update resourceName?
//			else
//				fContainerFullPath= path;
//		}
//		
//		/**
//		 * Sets the value of this page's file name field, or stores
//		 * it for future use if this page's controls do not exist yet.
//		 * 
//		 * @param value new file name
//		 */
//		public void setFileName(String value) {
//			if (fResourceGroup != null)
//				fResourceGroup.setResource(value); // update resourceName?
//			else
//				resourceName= value;
//		}
		 
		/**
		 * Returns the current full path of the containing resource as entered or
		 * selected by the user, or its anticipated initial value.
		 * 
		 * @return the container's full path, anticipated initial value,
		 *     or <code>null</code> if no path is known
		 */
		public IPath getContainerFullPath() {
			return this.containerFullPath;
		}
		
		/**
		 * Returns the current file name as entered by the user, or its anticipated
		 * initial value.
		 * 
		 * @return the file name, its anticipated initial value, or <code>null</code>
		 *     if no file name is known
		 */
		public String getResourceName() {
			String name= this.resourceName;
			if (!name.endsWith(this.resourceNameDefaultSuffix)) {
				name += this.resourceNameDefaultSuffix;
			}
			
			return name;
		}
		
		public void setFocus() {
			this.resourceNameControl.setFocus();
		}
		
		/**
		 * 
		 * @return true, if ok
		 */
		public IStatus validate() {
			// don't attempt to validate controls until they have been created
			if (this.containerGroup == null) {
				return null;
			}
			
			final IStatus containerSelectionStatus= ContainerSelectionComposite.validate(this.containerFullPath);
			if (containerSelectionStatus.matches(IStatus.ERROR)) {
				return containerSelectionStatus;
			}
			
			final IStatus resourceNameStatus= validateResourceName(this.resourceName);
			if (resourceNameStatus == null || resourceNameStatus.matches(IStatus.ERROR)) {
				return resourceNameStatus;
			}
			
			final IPath path= this.containerGroup.getContainerFullPath().append(getResourceName());
			
			// no warnings
			return validateFullResourcePath(path);
		}
		
		protected IStatus validateResourceName(final String resourceName) {
			if (resourceName == null || resourceName.trim().isEmpty()) {
				if (this.resourceNameEdited) {
					return new StatusInfo(IStatus.ERROR, NLS.bind(
							LTKWizardsMessages.ResourceGroup_error_EmptyName,
							SharedMessages.Resources_File));
				}
				else {
					return null;
				}
			}
			
			if (!(new Path("")).isValidSegment(resourceName)) {
				return new StatusInfo(IStatus.ERROR, NLS.bind(
						LTKWizardsMessages.ResourceGroup_error_InvalidFilename,
						resourceName));
			}
			
			return new StatusInfo();
		}
		
		/**
		 * Returns a <code>boolean</code> indicating whether the specified resource
		 * path represents a valid new resource in the workbench.  An error message
		 * is stored for future reference if the path  does not represent a valid
		 * new resource path.
		 * 
		 * @param resourcePath the path to validate
		 * @return IStatus indicating validity of the resource path
		 */
		protected IStatus validateFullResourcePath(final IPath resourcePath) {
			final IWorkspace workspace= ResourcesPlugin.getWorkspace();
			
			final IStatus result= workspace.validatePath(resourcePath.toString(), IResource.FILE);
			if (!result.isOK()) {
				return result;
			}
			
			if ( // !allowExistingResources && 
					workspace.getRoot().getFolder(resourcePath).exists()
					|| workspace.getRoot().getFile(resourcePath).exists()) {
				return new StatusInfo(IStatus.ERROR,
						LTKWizardsMessages.ResourceGroup_error_ResourceExists );
			}
			
			return new StatusInfo();
		}
		
		
		public void saveSettings() {
			getDialogSettings().put(DIALOGSETTING_ENABLEFILTER, this.containerGroup.getToggleFilterSetting());
		}
	}
	
	
	/** the current resource selection */
	protected IStructuredSelection resourceSelection;
	
	
	/**
	 * Creates a new file creation wizard page. If the initial resource selection
	 * contains exactly one container resource then it will be used as the default
	 * container resource.
	 * 
	 * @param pageName the name of the page
	 * @param selection the current resource selection
	 */
	public NewElementWizardPage(final String pageName, final IStructuredSelection selection) {
		super(pageName);
		setPageComplete(false);
		
		this.resourceSelection= selection;
	}
	
	
	@Override
	public void createControl(final Composite parent) {
		initializeDialogUnits(parent);
		
		final Composite composite= new Composite(parent, SWT.NONE);
		composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		composite.setLayout(LayoutUtils.newContentGrid());
		
		createContents(composite);
		
//		validatePage();
		// Show description on opening
		setErrorMessage(null);
		setMessage(null);
		setControl(composite);
	}
	
	
	/**
	 * Subclasses should ADDHELP
	 * 
	 * @param layouter
	 */
	protected abstract void createContents(final Composite parent);
	
	
	/**
	 * Returns whether this page's controls currently all contain valid values.
	 * 
	 * @return <code>true</code> if all controls are valid, and
	 *     <code>false</code> if at least one is invalid
	 */
	protected void validatePage() {
		updateStatus(new StatusInfo());
	}
	
	/**
	 * Updates the status line and the OK button according to the given status
	 * 
	 * @param status status to apply
	 */
	protected void updateStatus(IStatus status) {
		if (status != null) {
			setPageComplete(!status.matches(IStatus.ERROR));
		}
		else {
			setPageComplete(false);
			status= new StatusInfo();
		}
		final Control control= getControl();
		if (control != null && control.isVisible()) {
			StatusInfo.applyToStatusLine(this, status);
		}
	}
	
}
