/*******************************************************************************
 * Copyright (c) 2000, 2018 IBM Corporation and others.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 * 
 * SPDX-License-Identifier: EPL-2.0
 *
 *******************************************************************************/
package org.eclipse.dltk.ui.wizards;

import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

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.Assert;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.dltk.compiler.util.Util;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.core.environment.EnvironmentChangedListener;
import org.eclipse.dltk.core.environment.EnvironmentManager;
import org.eclipse.dltk.core.environment.IEnvironment;
import org.eclipse.dltk.core.environment.IEnvironmentChangedListener;
import org.eclipse.dltk.core.environment.IFileHandle;
import org.eclipse.dltk.internal.corext.util.Messages;
import org.eclipse.dltk.internal.ui.wizards.NewWizardMessages;
import org.eclipse.dltk.internal.ui.wizards.dialogfields.ComboDialogField;
import org.eclipse.dltk.internal.ui.wizards.dialogfields.DialogField;
import org.eclipse.dltk.internal.ui.wizards.dialogfields.IDialogFieldListener;
import org.eclipse.dltk.internal.ui.wizards.dialogfields.IStringButtonAdapter;
import org.eclipse.dltk.internal.ui.wizards.dialogfields.LayoutUtil;
import org.eclipse.dltk.internal.ui.wizards.dialogfields.SelectionButtonDialogField;
import org.eclipse.dltk.internal.ui.wizards.dialogfields.StringButtonDialogField;
import org.eclipse.dltk.internal.ui.wizards.dialogfields.StringDialogField;
import org.eclipse.dltk.internal.ui.workingsets.WorkingSetIDs;
import org.eclipse.dltk.launching.IInterpreterInstall;
import org.eclipse.dltk.launching.IInterpreterInstallType;
import org.eclipse.dltk.launching.InterpreterStandin;
import org.eclipse.dltk.launching.ScriptRuntime;
import org.eclipse.dltk.ui.DLTKUILanguageManager;
import org.eclipse.dltk.ui.DLTKUIPlugin;
import org.eclipse.dltk.ui.IDLTKUILanguageToolkit;
import org.eclipse.dltk.ui.dialogs.ControlStatus;
import org.eclipse.dltk.ui.dialogs.StatusInfo;
import org.eclipse.dltk.ui.environment.IEnvironmentUI;
import org.eclipse.dltk.ui.viewsupport.BasicElementLabels;
import org.eclipse.dltk.ui.wizards.IProjectWizardInitializer.IProjectWizardState;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.dialogs.PreferencesUtil;
import org.eclipse.ui.dialogs.WorkingSetConfigurationBlock;

/**
 * The first page of the <code>SimpleProjectWizard</code>.
 *
 * @since 2.0
 */
public abstract class ProjectWizardFirstPage extends WizardPage
		implements ILocationGroup, IProjectWizardPage {

	/**
	 * @since 2.0
	 */
	public static final String ATTR_EXTERNAL_BROWSE_LOCATION = DLTKUIPlugin.PLUGIN_ID
			+ ".external.browse.location."; //$NON-NLS-1$

	/**
	 * Request a project name. Fires an event whenever the text field is
	 * changed, regardless of its content.
	 */
	public final class NameGroup extends Observable
			implements IDialogFieldListener {
		protected final StringDialogField fNameField;

		public NameGroup(Composite composite, String initialName) {
			final Composite nameComposite = new Composite(composite, SWT.NONE);
			nameComposite.setFont(composite.getFont());
			nameComposite
					.setLayout(initGridLayout(new GridLayout(2, false), false));
			nameComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
			// text field for project name
			fNameField = new StringDialogField();
			fNameField.setLabelText(
					NewWizardMessages.ScriptProjectWizardFirstPage_NameGroup_label_text);
			fNameField.setDialogFieldListener(this);
			setName(initialName);
			fNameField.doFillIntoGrid(nameComposite, 2);
			LayoutUtil.setHorizontalGrabbing(fNameField.getTextControl(null));
		}

		protected void fireEvent() {
			setChanged();
			notifyObservers();
		}

		public String getName() {
			return fNameField.getText().trim();
		}

		public void postSetFocus() {
			fNameField.postSetFocusOnDialogField(getShell().getDisplay());
		}

		public void setName(String name) {
			fNameField.setText(name);
		}

		@Override
		public void dialogFieldChanged(DialogField field) {
			fireEvent();
		}
	}

	/**
	 * Request a location. Fires an event whenever the checkbox or the location
	 * field is changed, regardless of whether the change originates from the
	 * user or has been invoked programmatically.
	 */
	public class LocationGroup extends Observable
			implements Observer, IStringButtonAdapter, IDialogFieldListener {
		protected final SelectionButtonDialogField fWorkspaceRadio;
		protected final SelectionButtonDialogField fExternalRadio;
		protected final StringButtonDialogField fLocation;
		protected final ComboDialogField fEnvironment;
		private IEnvironment[] environments;

		private String fPreviousExternalLocation;
		private static final String DIALOGSTORE_LAST_EXTERNAL_LOC = DLTKUIPlugin.PLUGIN_ID
				+ ".last.external.project"; //$NON-NLS-1$
		private static final String DIALOGSTORE_LAST_EXTERNAL_ENVIRONMENT = DLTKUIPlugin.PLUGIN_ID
				+ ".last.external.environment"; //$NON-NLS-1$

		public LocationGroup() {
			fPreviousExternalLocation = Util.EMPTY_STRING;

			fWorkspaceRadio = new SelectionButtonDialogField(SWT.RADIO);
			fWorkspaceRadio.setDialogFieldListener(this);
			fWorkspaceRadio.setLabelText(
					NewWizardMessages.ScriptProjectWizardFirstPage_LocationGroup_workspace_desc);

			fExternalRadio = new SelectionButtonDialogField(SWT.RADIO);
			fExternalRadio.setDialogFieldListener(this);
			fExternalRadio.setLabelText(
					NewWizardMessages.ScriptProjectWizardFirstPage_LocationGroup_external_desc);

			fLocation = new StringButtonDialogField(this);
			fLocation.setDialogFieldListener(this);
			fLocation.setLabelText(
					NewWizardMessages.ScriptProjectWizardFirstPage_LocationGroup_locationLabel_desc);
			fLocation.setButtonLabel(
					NewWizardMessages.ScriptProjectWizardFirstPage_LocationGroup_browseButton_desc);

			fEnvironment = new ComboDialogField(SWT.DROP_DOWN | SWT.READ_ONLY);
			fEnvironment.setLabelText(
					NewWizardMessages.ProjectWizardFirstPage_host);
			fEnvironment.setDialogFieldListener(this);
			fEnvironment.setDialogFieldListener(field -> updateInterpreters());
		}

		public void createControls(Composite composite) {
			final int numColumns = 3;
			final Group group = new Group(composite, SWT.NONE);
			group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
			group.setLayout(
					initGridLayout(new GridLayout(numColumns, false), true));
			group.setText(
					NewWizardMessages.ScriptProjectWizardFirstPage_LocationGroup_title);
			createModeControls(group, numColumns);
			createEnvironmentControls(group, numColumns);
			createLocationControls(group, numColumns);
		}

		/**
		 * @since 2.0
		 */
		protected void initialize() {
			fWorkspaceRadio.setSelection(true);
			fExternalRadio.setSelection(false);
		}

		/**
		 * @since 2.0
		 */
		@Deprecated
		protected final void createControls(Composite group, int numColumns) {
		}

		/**
		 * @since 2.0
		 */
		protected void createModeControls(Composite group, int numColumns) {
			fWorkspaceRadio.doFillIntoGrid(group, numColumns);
			fExternalRadio.doFillIntoGrid(group, numColumns);
		}

		/**
		 * @since 2.0
		 */
		protected void createEnvironmentControls(Composite group,
				int numColumns) {
			environmentChangedListener = new EnvironmentChangedListener() {
				@Override
				public void environmentsModified() {
					Display.getDefault().asyncExec(() -> {
						try {
							initEnvironments(false);
						} catch (Exception e) {
							if (DLTKCore.DEBUG) {
								e.printStackTrace();
							}
						}
					});
				}
			};
			EnvironmentManager
					.addEnvironmentChangedListener(environmentChangedListener);
			initEnvironments(true);
			fEnvironment.doFillIntoGrid(group, numColumns);
			LayoutUtil
					.setHorizontalGrabbing(fEnvironment.getComboControl(null));
		}

		/**
		 * @since 2.0
		 */
		protected void createLocationControls(Composite group, int numColumns) {
			fLocation.doFillIntoGrid(group, numColumns);
			LayoutUtil.setHorizontalGrabbing(fLocation.getTextControl(null));
		}

		private IEnvironmentChangedListener environmentChangedListener = null;

		private void initEnvironments(boolean initializeWithLocal) {
			final IEnvironment selection;
			if (!initializeWithLocal && environments != null) {
				final int index = fEnvironment.getSelectionIndex();
				if (index >= 0 && index < environments.length) {
					selection = environments[index];
				} else {
					selection = null;
				}
			} else {
				selection = null;
			}
			environments = EnvironmentManager.getEnvironments(false);
			final String[] items = new String[environments.length];
			int selectionIndex = 0;
			for (int i = 0; i < items.length; i++) {
				final IEnvironment env = environments[i];
				items[i] = env.getName();
				if (selection == null ? env.isLocal() : selection.equals(env)) {
					selectionIndex = i;
				}
			}
			fEnvironment.setItems(items);
			fEnvironment.selectItem(selectionIndex);
		}

		protected void fireEvent() {
			setChanged();
			notifyObservers();
		}

		private void updateInterpreters() {
			handlePossibleInterpreterChange();
		}

		protected String getDefaultPath(String name) {
			return Platform.getLocation().append(name).toOSString();
		}

		@Override
		public void update(Observable o, Object arg) {
			if (!canChangeEnvironment()) {
				selectLocalEnvironment();
			}
			if (!canChangeLocation()) {
				fLocation.setText(getDefaultPath(fNameGroup.getName()));
			}
			fireEvent();
		}

		private void selectLocalEnvironment() {
			setEnvironment(EnvironmentManager.getLocalEnvironment());
		}

		/**
		 * @since 2.0
		 */
		protected void setEnvironment(final IEnvironment env) {
			if (environments == null) {
				return;
			}
			for (int i = 0; i < environments.length; ++i) {
				if (env.equals(environments[i])) {
					if (fEnvironment.getSelectionIndex() != i) {
						fEnvironment.selectItem(i);
					}
					break;
				}
			}
		}

		public IPath getLocation() {
			if (isInWorkspace()) {
				return Platform.getLocation();
			}
			return new Path(fLocation.getText().trim());
		}

		public boolean isInWorkspace() {
			return fWorkspaceRadio.isSelected();
		}

		public boolean isExternalProject() {
			return fExternalRadio.isSelected();
		}

		/**
		 * @since 2.0
		 */
		protected boolean canChangeLocation() {
			return isExternalProject();
		}

		/**
		 * @since 2.0
		 */
		protected boolean canChangeEnvironment() {
			return isExternalProject();
		}

		public IEnvironment getEnvironment() {
			if (canChangeEnvironment()) {
				final int index = fEnvironment.getSelectionIndex();
				if (index >= 0 && index < environments.length) {
					return environments[index];
				}
			}
			return EnvironmentManager.getLocalEnvironment();
		}

		@Override
		public void changeControlPressed(DialogField field) {
			final IEnvironment environment = getEnvironment();
			final IEnvironmentUI environmentUI = environment
					.getAdapter(IEnvironmentUI.class);
			if (environmentUI != null) {
				String directoryName = fLocation.getText().trim();
				if (directoryName.length() == 0) {
					final String prevLocation = loadLastExternalLocation(
							environment);
					if (prevLocation != null) {
						directoryName = prevLocation;
					}
				}
				final String selectedDirectory = environmentUI
						.selectFolder(getShell(), directoryName);

				if (selectedDirectory != null) {
					fLocation.setText(selectedDirectory);
					saveLastExternalLocation(environment, selectedDirectory);
				}
			}
		}

		/**
		 * @since 2.0
		 */
		protected String loadLastExternalLocation(IEnvironment environment) {
			final String browseLocation = getWizardState().getString(
					ATTR_EXTERNAL_BROWSE_LOCATION + environment.getId());
			if (browseLocation != null && browseLocation.length() != 0) {
				return browseLocation;
			}
			IDialogSettings ds = DLTKUIPlugin.getDefault().getDialogSettings();
			final String savedEnvId = ds
					.get(DIALOGSTORE_LAST_EXTERNAL_ENVIRONMENT);
			if (savedEnvId == null || savedEnvId.equals(environment.getId())) {
				return ds.get(DIALOGSTORE_LAST_EXTERNAL_LOC);
			}
			return null;
		}

		/**
		 * @since 2.0
		 */
		protected void saveLastExternalLocation(final IEnvironment environment,
				final String directory) {
			IDialogSettings ds = DLTKUIPlugin.getDefault().getDialogSettings();
			ds.put(DIALOGSTORE_LAST_EXTERNAL_LOC, directory);
			ds.put(DIALOGSTORE_LAST_EXTERNAL_ENVIRONMENT, environment.getId());
		}

		protected static final int ANY = 0;
		protected static final int WORKSPACE = 1;
		protected static final int EXTERNAL = 2;

		protected boolean isModeField(DialogField field, int kind) {
			switch (kind) {
			case ANY:
				return field == fWorkspaceRadio || field == fExternalRadio;
			case WORKSPACE:
				return field == fWorkspaceRadio;
			case EXTERNAL:
				return field == fExternalRadio;
			default:
				return false;
			}
		}

		@Override
		public void dialogFieldChanged(DialogField field) {
			if (isModeField(field, ANY)) {
				if (field instanceof SelectionButtonDialogField) {
					if (!((SelectionButtonDialogField) field)
							.getSelectionButton().getSelection()) {
						return;
					}
				}
				refreshControls();
			}

			fireEvent();
		}

		/**
		 * @since 2.0
		 */
		protected void refreshControls() {
			final boolean wasLocationEnabled = fLocation.isEnabled();
			fLocation.setEnabled(canChangeLocation());
			fEnvironment.setEnabled(canChangeEnvironment());
			if (!canChangeEnvironment()) {
				selectLocalEnvironment();
			}
			if (canChangeLocation() != wasLocationEnabled) {
				if (wasLocationEnabled) {
					fPreviousExternalLocation = fLocation.getText();
					fLocation.setText(getDefaultPath(fNameGroup.getName()));
				} else {
					IEnvironment environment = this.getEnvironment();
					if (environment != null && environment.isLocal()) {
						fLocation.setText(fPreviousExternalLocation);
					} else {
						fLocation.setText(""); //$NON-NLS-1$
					}
				}
			}
			updateInterpreters();
		}

		protected void dispose() {
			if (environmentChangedListener != null) {
				EnvironmentManager.removeEnvironmentChangedListener(
						environmentChangedListener);
				environmentChangedListener = null;
			}
		}

		public IStatus validate(IProject handle) {
			final String location = getLocation().toOSString();
			// check whether location is empty
			if (location.length() == 0) {
				return new StatusInfo(IStatus.WARNING,
						NewWizardMessages.ScriptProjectWizardFirstPage_Message_enterLocation);
			}
			// check whether the location is a syntactically correct path
			if (!Path.EMPTY.isValidPath(location)) {
				return new StatusInfo(IStatus.ERROR,
						NewWizardMessages.ScriptProjectWizardFirstPage_Message_invalidDirectory);
			}
			final IPath projectPath = Path.fromOSString(location);
			final IEnvironment environment = getEnvironment();
			// check whether the location has the workspace as prefix
			if (!isInWorkspace() && environment.isLocal()
					&& Platform.getLocation().isPrefixOf(projectPath)) {
				return new StatusInfo(IStatus.ERROR,
						NewWizardMessages.ScriptProjectWizardFirstPage_Message_cannotCreateInWorkspace);
			}
			if (!isInWorkspace() && environment.isLocal()) {
				// If we do not place the contents in the workspace validate the
				// location.
				final IStatus locationStatus = DLTKUIPlugin.getWorkspace()
						.validateProjectLocation(handle, projectPath);
				if (!locationStatus.isOK()) {
					return new StatusInfo(IStatus.ERROR,
							locationStatus.getMessage());
				}
			}
			return Status.OK_STATUS;
		}

	}

	protected interface IInterpreterGroup {

		/**
		 * @return
		 */
		IInterpreterInstall getSelectedInterpreter();

		/**
		 *
		 */
		void handlePossibleInterpreterChange();

		/**
		 * @since 2.0
		 */
		boolean isInterpreterPresent();

		/**
		 * Returns the control to be decorated if error occurs
		 *
		 * @since 2.0
		 */
		Control getDecorationTarget();

	}

	protected abstract class AbstractInterpreterGroup extends Observable
			implements Observer, SelectionListener, IDialogFieldListener,
			IInterpreterGroup {

		protected final SelectionButtonDialogField fUseDefaultInterpreter;
		protected final SelectionButtonDialogField fUseProjectInterpreter;
		protected final ComboDialogField fInterpreterCombo;
		private final Group fGroup;
		private String[] fComplianceLabels;
		private final Link fPreferenceLink;
		private IInterpreterInstall[] fInstalledInterpreters;
		private boolean interpretersPresent;

		public AbstractInterpreterGroup(Composite composite) {
			fGroup = new Group(composite, SWT.NONE);
			fGroup.setFont(composite.getFont());
			fGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
			final GridLayout groupLayout = initGridLayout(
					new GridLayout(3, false), true);
			groupLayout.marginHeight /= 2;
			fGroup.setLayout(groupLayout);
			fGroup.setText(
					NewWizardMessages.ScriptProjectWizardFirstPage_InterpreterEnvironmentGroup_title);

			fUseDefaultInterpreter = new SelectionButtonDialogField(SWT.RADIO);
			fUseDefaultInterpreter.setLabelText(getDefaultInterpreterLabel());
			fUseDefaultInterpreter.doFillIntoGrid(fGroup, 2);
			fUseDefaultInterpreter.setDialogFieldListener(this);

			fPreferenceLink = new Link(fGroup, SWT.NONE);
			fPreferenceLink.setFont(fGroup.getFont());
			fPreferenceLink.setText(
					NewWizardMessages.ScriptProjectWizardFirstPage_InterpreterEnvironmentGroup_link_description);
			fPreferenceLink.setLayoutData(
					new GridData(GridData.END, GridData.CENTER, false, false));
			fPreferenceLink.addSelectionListener(this);

			fUseProjectInterpreter = new SelectionButtonDialogField(SWT.RADIO);
			fUseProjectInterpreter.setLabelText(
					NewWizardMessages.ScriptProjectWizardFirstPage_InterpreterEnvironmentGroup_specific_compliance);
			fUseProjectInterpreter.doFillIntoGrid(fGroup, 1);
			fUseProjectInterpreter.setDialogFieldListener(this);

			fInterpreterCombo = new ComboDialogField(SWT.READ_ONLY);
			fillInstalledInterpreters(fInterpreterCombo);
			fInterpreterCombo.setDialogFieldListener(this);

			Combo comboControl = fInterpreterCombo.getComboControl(fGroup);
			GridData gridData = new GridData(GridData.BEGINNING,
					GridData.CENTER, true, false);
			gridData.minimumWidth = 100;
			comboControl.setLayoutData(gridData); // make sure column 2 is
			// grabing (but no fill)
			comboControl.setVisibleItemCount(20);

			// DialogField.createEmptySpace(fGroup);

			fUseDefaultInterpreter.setSelection(true);
			fInterpreterCombo.setEnabled(fUseProjectInterpreter.isSelected());
		}

		protected final IEnvironment getEnvironment() {
			return fLocationGroup.getEnvironment();
		}

		private void fillInstalledInterpreters(ComboDialogField comboField) {
			String selectedItem = null;
			int selectionIndex = -1;
			if (fUseProjectInterpreter.isSelected()) {
				selectionIndex = comboField.getSelectionIndex();
				if (selectionIndex != -1) {// paranoia
					selectedItem = comboField.getItems()[selectionIndex];
				}
			}

			fInstalledInterpreters = getWorkspaceInterpeters();

			selectionIndex = -1;// find new index
			fComplianceLabels = new String[fInstalledInterpreters.length];
			for (int i = 0; i < fInstalledInterpreters.length; i++) {
				fComplianceLabels[i] = fInstalledInterpreters[i].getName();
				if (selectedItem != null
						&& fComplianceLabels[i].equals(selectedItem)) {
					selectionIndex = i;
				}
			}
			comboField.setItems(fComplianceLabels);
			if (selectionIndex == -1) {
				fInterpreterCombo.selectItem(getDefaultInterpreterName());
			} else {
				fInterpreterCombo.selectItem(selectedItem);
			}
			interpretersPresent = (fInstalledInterpreters.length > 0);
		}

		private IInterpreterInstall[] getWorkspaceInterpeters() {
			List<IInterpreterInstall> standins = new ArrayList<>();
			IInterpreterInstallType[] types = ScriptRuntime
					.getInterpreterInstallTypes(getCurrentLanguageNature());
			IEnvironment environment = getEnvironment();
			for (int i = 0; i < types.length; i++) {
				IInterpreterInstallType type = types[i];
				IInterpreterInstall[] installs = type.getInterpreterInstalls();
				for (int j = 0; j < installs.length; j++) {
					IInterpreterInstall install = installs[j];
					String envId = install.getEnvironmentId();
					if (envId != null && envId.equals(environment.getId())) {
						standins.add(new InterpreterStandin(install));
					}
				}
			}
			return standins.toArray(new IInterpreterInstall[standins.size()]);
		}

		private String getDefaultInterpreterName() {
			IInterpreterInstall inst = ScriptRuntime
					.getDefaultInterpreterInstall(getCurrentLanguageNature(),
							getEnvironment());
			if (inst != null) {
				return inst.getName();
			}
			return "undefined"; //$NON-NLS-1$
		}

		private String getDefaultInterpreterLabel() {
			return Messages.format(
					NewWizardMessages.ScriptProjectWizardFirstPage_InterpreterEnvironmentGroup_default_compliance,
					getDefaultInterpreterName());
		}

		@Override
		public void update(Observable o, Object arg) {
			updateEnableState();
		}

		private void updateEnableState() {
			if (fDetectGroup == null)
				return;
			final boolean detect = fDetectGroup.mustDetect()
					&& interpretersPresent;
			fUseDefaultInterpreter.setEnabled(!detect);
			fUseProjectInterpreter.setEnabled(!detect);
			fInterpreterCombo
					.setEnabled(!detect && fUseProjectInterpreter.isSelected());
			fPreferenceLink.setEnabled(!detect);
			fGroup.setEnabled(!detect);
		}

		@Override
		public void widgetSelected(SelectionEvent e) {
			widgetDefaultSelected(e);
		}

		/**
		 * Shows window with appropriate language preference page.
		 *
		 */
		void showInterpreterPreferencePage() {
			final String pageId = getIntereprtersPreferencePageId();
			if (pageId == null)
				return;
			PreferencesUtil.createPreferenceDialogOn(getShell(), pageId,
					new String[] { pageId }, null).open();
		}

		protected String getIntereprtersPreferencePageId() {
			final IDLTKUILanguageToolkit languageToolkit = DLTKUILanguageManager
					.getLanguageToolkit(getCurrentLanguageNature());
			if (languageToolkit != null) {
				return languageToolkit.getInterpreterPreferencePage();
			}
			return null;
		}

		protected final String getCurrentLanguageNature() {
			return getScriptNature();
		}

		@Override
		public void widgetDefaultSelected(SelectionEvent e) {
			showInterpreterPreferencePage();
			handlePossibleInterpreterChange();
			updateEnableState();
			// fDetectGroup.handlePossibleJInterpreterChange();
		}

		@Override
		public void handlePossibleInterpreterChange() {
			refreshInterpreters();
		}

		private void refreshInterpreters() {
			fUseDefaultInterpreter.setLabelText(getDefaultInterpreterLabel());
			fillInstalledInterpreters(fInterpreterCombo);
			setChanged();
			notifyObservers();
		}

		@Override
		public void dialogFieldChanged(DialogField field) {
			if (field == fUseDefaultInterpreter
					|| field == fUseProjectInterpreter) {
				setChanged();
				notifyObservers();
			}
			updateEnableState();
			// fDetectGroup.handlePossibleInterpreterChange();
		}

		public boolean isUseSpecific() {
			return fUseProjectInterpreter.isSelected();
		}

		@Override
		public IInterpreterInstall getSelectedInterpreter() {
			if (fUseProjectInterpreter.isSelected()) {
				int index = fInterpreterCombo.getSelectionIndex();
				if (index >= 0 && index < fComplianceLabels.length) { // paranoia
					return fInstalledInterpreters[index];
				}
			}
			return null;
		}

		/**
		 * @since 2.0
		 */
		@Override
		public boolean isInterpreterPresent() {
			return interpretersPresent;
		}

		/**
		 * @since 2.0
		 */
		@Override
		public Control getDecorationTarget() {
			if (fUseDefaultInterpreter.isSelected()) {
				return fUseDefaultInterpreter.getSelectionButton();
			}
			return fUseProjectInterpreter.getSelectionButton();
		}
	}

	/**
	 * @since 2.0
	 */
	protected enum DefaultInterpreterGroupOption {
		NONE
	}

	/**
	 * @since 2.0
	 */
	protected class DefaultInterpreterGroup extends AbstractInterpreterGroup {

		/**
		 * @param composite
		 */
		public DefaultInterpreterGroup(Composite composite,
				DefaultInterpreterGroupOption... options) {
			this(composite, Arrays.asList(options));
		}

		private DefaultInterpreterGroup(Composite composite,
				List<DefaultInterpreterGroupOption> options) {
			super(composite);
		}

	}

	/**
	 * @since 2.0
	 */
	protected interface IWorkingSetGroup {

		/**
		 * Create child control.
		 *
		 * @param composite
		 */
		void createControl(Composite composite);

		/**
		 * @return
		 */
		IWorkingSet[] getSelectedWorkingSets();

		/**
		 * @param workingSets
		 */
		void setWorkingSets(IWorkingSet[] workingSets);

	}

	private static final class WorkingSetGroup implements IWorkingSetGroup {

		private final WorkingSetConfigurationBlock fWorkingSetBlock;

		public WorkingSetGroup() {
			String[] workingSetIds = new String[] { WorkingSetIDs.SCRIPT,
					WorkingSetIDs.RESOURCE };
			fWorkingSetBlock = new WorkingSetConfigurationBlock(workingSetIds,
					DLTKUIPlugin.getDefault().getDialogSettings());
		}

		@Override
		public void createControl(Composite composite) {
			Group workingSetGroup = new Group(composite, SWT.NONE);
			workingSetGroup.setFont(composite.getFont());
			workingSetGroup.setText(
					NewWizardMessages.ProjectWizardFirstPage_WorkingSets_group);
			workingSetGroup
					.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
			workingSetGroup.setLayout(new GridLayout(1, false));
			fWorkingSetBlock.createContent(workingSetGroup);
		}

		@Override
		public void setWorkingSets(IWorkingSet[] workingSets) {
			fWorkingSetBlock.setWorkingSets(workingSets);
		}

		@Override
		public IWorkingSet[] getSelectedWorkingSets() {
			return fWorkingSetBlock.getSelectedWorkingSets();
		}
	}

	/**
	 * Show a warning when the project location contains files.
	 */
	protected final class DetectGroup extends Observable
			implements Observer, SelectionListener {
		private final Link fHintText;
		private Label fIcon;
		private boolean fDetect;

		public DetectGroup(Composite parent) {
			Composite composite = new Composite(parent, SWT.WRAP);
			composite.setLayoutData(
					new GridData(SWT.FILL, SWT.TOP, true, false));
			GridLayout layout = new GridLayout(2, false);
			layout.marginHeight = 0;
			layout.marginWidth = 0;
			layout.horizontalSpacing = 10;
			composite.setLayout(layout);

			fIcon = new Label(composite, SWT.LEFT);
			GridData gd = new GridData(SWT.LEFT, SWT.CENTER, false, false);
			fIcon.setLayoutData(gd);

			fHintText = new Link(composite, SWT.WRAP);
			fHintText.setFont(parent.getFont());
			fHintText.addSelectionListener(this);
			gd = new GridData(GridData.FILL, SWT.FILL, true, true);
			gd.widthHint = convertWidthInCharsToPixels(50);
			gd.heightHint = convertHeightInCharsToPixels(3);
			fHintText.setLayoutData(gd);
			if (supportInterpreter()) {
				handlePossibleInterpreterChange();
			}
		}

		private boolean isValidProjectName(String name) {
			if (name.length() == 0) {
				return false;
			}
			final IWorkspace workspace = DLTKUIPlugin.getWorkspace();
			return workspace.validateName(name, IResource.PROJECT).isOK()
					&& workspace.getRoot().findMember(name) == null;
		}

		private boolean computeDetectState() {
			IPath location = fLocationGroup.getLocation();
			if (fLocationGroup.isInWorkspace()) {
				if (!isValidProjectName(getProjectName())) {
					return false;
				}
				final IEnvironment environment = EnvironmentManager
						.getLocalEnvironment();
				final IFileHandle directory = environment
						.getFile(location.append(getProjectName()));
				return directory.isDirectory();
			}
			IEnvironment environment = fLocationGroup.getEnvironment();
			if (!location.isEmpty()) {
				final IFileHandle directory = environment.getFile(location);
				return directory.isDirectory();
			}
			return false;
		}

		@Override
		public void update(Observable o, Object arg) {
			if (o instanceof LocationGroup) {
				final boolean oldDetectState = fDetect;
				fDetect = computeDetectState();
				if (oldDetectState != fDetect) {
					setChanged();
					notifyObservers();
					if (fDetect) {
						fIcon.setImage(
								Dialog.getImage(Dialog.DLG_IMG_MESSAGE_INFO));
						fIcon.setVisible(true);
						fHintText.setVisible(true);
						fHintText.setText(
								NewWizardMessages.ScriptProjectWizardFirstPage_DetectGroup_message);
						fHintText.getParent().layout();
					} else {
						fIcon.setVisible(false);
						fHintText.setVisible(false);
					}
					if (supportInterpreter()) {
						handlePossibleInterpreterChange();
					}

				}
			}
		}

		public boolean mustDetect() {
			return fDetect;
		}

		@Override
		public void widgetSelected(SelectionEvent e) {
			widgetDefaultSelected(e);
		}

		@Override
		public void widgetDefaultSelected(SelectionEvent e) {
			if (DLTKCore.DEBUG) {
				System.err.println(
						"DetectGroup show compilancePreferencePage..."); //$NON-NLS-1$
			}
			if (supportInterpreter()) {
				handlePossibleInterpreterChange();
			}
		}
	}

	/**
	 * Validates project fields. Returns {@link IStatus} or <code>null</code> if
	 * there are no any problems.
	 *
	 * @return
	 */
	protected IStatus validateProject() {
		final String name = fNameGroup.getName();
		// check whether the project name field is empty
		if (name.length() == 0) {
			return new StatusInfo(IStatus.OK,
					NewWizardMessages.ScriptProjectWizardFirstPage_Message_enterProjectName);
		}
		// check whether the project name is valid
		final IWorkspace workspace = DLTKUIPlugin.getWorkspace();
		final IStatus nameStatus = workspace.validateName(name,
				IResource.PROJECT);
		if (!nameStatus.isOK()) {
			return nameStatus;
		}
		// check whether project already exists
		final IProject handle = getProjectHandle();
		if (handle.exists()) {
			return new StatusInfo(IStatus.ERROR,
					NewWizardMessages.ScriptProjectWizardFirstPage_Message_projectAlreadyExists);
		}
		IPath projectLocation = workspace.getRoot().getLocation().append(name);
		if (projectLocation.toFile().exists()) {
			try {
				// correct casing
				String canonicalPath = projectLocation.toFile()
						.getCanonicalPath();
				projectLocation = new Path(canonicalPath);
			} catch (IOException e) {
				DLTKUIPlugin.log(e);
			}
			String existingName = projectLocation.lastSegment();
			if (!existingName.equals(fNameGroup.getName())) {
				return new StatusInfo(IStatus.ERROR, NLS.bind(
						NewWizardMessages.ScriptProjectWizardFirstPage_Message_invalidProjectNameForWorkspaceRoot,
						BasicElementLabels.getResourceName(existingName)));
			}
		}
		return null;
	}

	/**
	 * Tests if valid project is specified.
	 *
	 * @return
	 */
	protected boolean isValidProject() {
		return validateProject() == null;
	}

	private ControlDecorationManager fDecorationManager;

	/**
	 * Validate this page and show appropriate warnings and error
	 * NewWizardMessages.
	 */
	private final class Validator implements Observer {
		@Override
		public void update(Observable o, Object arg) {
			final IControlDecorationManager manager = fDecorationManager
					.beginReporting();
			try {
				validate(manager, o, arg);
			} finally {
				manager.commit();
			}
		}

		private void validate(IControlDecorationManager decorations,
				Observable o, Object arg) {
			IStatus projectStatus = validateProject();
			if (projectStatus == null) {
				decorations.hide(fNameGroup.fNameField.getTextControl());
				projectStatus = fLocationGroup.validate(getProjectHandle());
				if (projectStatus.isOK()) {
					projectStatus = null;
				}
				if (projectStatus != null) {
					if (projectStatus instanceof ControlStatus) {
						final ControlStatus cStatus = (ControlStatus) projectStatus;
						decorations.show(cStatus.getControl(), cStatus);
					} else {
						decorations.show(
								fLocationGroup.fLocation.getTextControl(),
								projectStatus);
					}
				}
			} else {
				decorations.show(fNameGroup.fNameField.getTextControl(),
						projectStatus);
			}
			if (projectStatus != null) {
				if (projectStatus.getSeverity() != IStatus.ERROR) {
					setErrorMessage(null);
					setMessage(projectStatus.getMessage());
				} else {
					setErrorMessage(projectStatus.getMessage());
				}
				setPageComplete(false);
				return;
			}
			if (supportInterpreter() && interpeterRequired()) {
				if (!fInterpreterGroup.isInterpreterPresent()) {
					setErrorMessage(
							NewWizardMessages.ProjectWizardFirstPage_atLeastOneInterpreterMustBeConfigured);
					setPageComplete(false);
					decorations.show(fInterpreterGroup.getDecorationTarget(),
							new StatusInfo(IStatus.ERROR,
									NewWizardMessages.ProjectWizardFirstPage_atLeastOneInterpreterMustBeConfigured));
					return;
				}
			}
			setPageComplete(true);
			setErrorMessage(null);
			setMessage(null);
		}
	}

	protected NameGroup fNameGroup;
	protected LocationGroup fLocationGroup;
	// private LayoutGroup fLayoutGroup;
	// private InterpreterEnvironmentGroup fInterpreterEnvironmentGroup;
	protected DetectGroup fDetectGroup;
	private Validator fValidator;
	protected String fInitialName;
	private IWorkingSetGroup fWorkingSetGroup;

	/**
	 * @since 2.0
	 */
	public static final String PAGE_NAME = "ProjectWizardFirstPage"; //$NON-NLS-1$

	/**
	 * Create a new <code>SimpleProjectFirstPage</code>.
	 */
	public ProjectWizardFirstPage() {
		super(PAGE_NAME);
		setPageComplete(false);
		setTitle(NewWizardMessages.ScriptProjectWizardFirstPage_page_title);
		setDescription(
				NewWizardMessages.ScriptProjectWizardFirstPage_page_description);
		fInitialName = ""; //$NON-NLS-1$
	}

	public void setName(String name) {
		fInitialName = name;
		if (fNameGroup != null) {
			fNameGroup.setName(name);
		}
	}

	/**
	 * Return true if some interpreters are available for selection.
	 *
	 * @return true if interpreters are available for selection
	 */
	public boolean isInterpretersPresent() {
		return fInterpreterGroup.isInterpreterPresent();
	}

	/**
	 * @since 2.0
	 */
	@Override
	public final String getScriptNature() {
		return ((ProjectWizard) getWizard()).getScriptNature();
	}

	protected boolean interpeterRequired() {
		return true;
	}

	protected boolean supportInterpreter() {
		return true;
	}

	protected IInterpreterGroup createInterpreterGroup(Composite parent) {
		return new DefaultInterpreterGroup(parent);
	}

	protected IInterpreterGroup getInterpreterGroup() {
		return fInterpreterGroup;
	}

	protected void handlePossibleInterpreterChange() {
		if (fInterpreterGroup != null) {
			fInterpreterGroup.handlePossibleInterpreterChange();
		}
	}

	protected Observable getInterpreterGroupObservable() {
		if (fInterpreterGroup instanceof Observable) {
			return (Observable) fInterpreterGroup;
		}
		return null;
	}

	/**
	 * @since 2.0
	 */
	@Override
	public IInterpreterInstall getInterpreter() {
		return fInterpreterGroup != null
				? fInterpreterGroup.getSelectedInterpreter()
				: null;
	}

	private IInterpreterGroup fInterpreterGroup;

	@Override
	public void createControl(Composite parent) {
		initializeDialogUnits(parent);
		final Composite composite = new Composite(parent, SWT.NULL);
		composite.setFont(parent.getFont());
		composite.setLayout(initGridLayout(new GridLayout(1, false), true));
		composite.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
		// create UI elements
		fNameGroup = new NameGroup(composite, fInitialName);
		fLocationGroup = createLocationGroup();
		fLocationGroup.createControls(composite);
		fLocationGroup.initialize();
		fLocationGroup.refreshControls();

		// fInterpreterEnvironmentGroup= new
		// InterpreterEnvironmentGroup(composite);
		// ProjectWizardFirstPage.AbstractInterpreterGroup interpGroup = null;
		if (supportInterpreter()) {
			fInterpreterGroup = createInterpreterGroup(composite);
		} else {
			fInterpreterGroup = null;
		}
		createCustomGroups(composite);
		// fLayoutGroup= new LayoutGroup(composite);
		getWorkingSetGroup().createControl(composite);
		fDetectGroup = new DetectGroup(composite);

		// establish connections
		fNameGroup.addObserver(fLocationGroup);
		// fDetectGroup.addObserver(fLayoutGroup);
		// fDetectGroup.addObserver(fInterpreterEnvironmentGroup);
		fLocationGroup.addObserver(fDetectGroup);
		// initialize all elements
		fNameGroup.notifyObservers();
		// create and connect validator
		fValidator = new Validator();
		fDecorationManager = new ControlDecorationManager();
		Observable interpreterGroupObservable = getInterpreterGroupObservable();
		if (supportInterpreter() && interpreterGroupObservable != null) {
			// fDetectGroup.addObserver(getInterpreterGroupObservable());
			interpreterGroupObservable.addObserver(fValidator);
			handlePossibleInterpreterChange();
		}
		fNameGroup.addObserver(fValidator);
		fLocationGroup.addObserver(fValidator);

		setControl(composite);
		Dialog.applyDialogFont(composite);
		if (DLTKCore.DEBUG) {
			System.err.println("Add help support here..."); //$NON-NLS-1$
		}
		// PlatformUI.getWorkbench().getHelpSystem().setHelp(composite,
		// IDLTKHelpContextIds.NEW_JAVAPROJECT_WIZARD_PAGE);
		final IProjectWizardState state = getWizardState();
		if (state.getProjectName() != null) {
			setName(state.getProjectName());
		}
	}

	/**
	 * @since 2.0
	 */
	protected final IWorkingSetGroup getWorkingSetGroup() {
		if (fWorkingSetGroup == null) {
			fWorkingSetGroup = createWorkingSetGroup();
		}
		return fWorkingSetGroup;
	}

	/**
	 * @since 2.0
	 */
	protected IWorkingSetGroup createWorkingSetGroup() {
		return new WorkingSetGroup();
	}

	/**
	 * @since 2.0
	 */
	protected WorkingSetDetector createWorkingSetDetector() {
		return new WorkingSetDetector();
	}

	protected LocationGroup createLocationGroup() {
		return new LocationGroup();
	}

	protected void createCustomGroups(Composite composite) {
	}

	/**
	 * Returns the current project location path as entered by the user, or its
	 * anticipated initial value. Note that if the default has been returned the
	 * path in a project description used to create a project should not be set.
	 *
	 * @return the project location path or its anticipated initial value.
	 */
	@Override
	public URI getLocationURI() {
		IEnvironment environment = getEnvironment();
		return environment.getURI(fLocationGroup.getLocation());
	}

	@Override
	public IEnvironment getEnvironment() {
		return fLocationGroup.getEnvironment();
	}

	@Override
	public IPath getLocation() {
		return fLocationGroup.getLocation();
	}

	/**
	 * Creates a project resource handle for the current project name field
	 * value.
	 * <p>
	 * This method does not create the project resource; this is the
	 * responsibility of <code>IProject::create</code> invoked by the new
	 * project resource wizard.
	 * </p>
	 *
	 * @return the new project resource handle
	 */
	@Override
	public IProject getProjectHandle() {
		return ResourcesPlugin.getWorkspace().getRoot()
				.getProject(fNameGroup.getName());
	}

	@Override
	public boolean isInWorkspace() {
		return fLocationGroup.isInWorkspace();
	}

	@Override
	public String getProjectName() {
		return fNameGroup.getName();
	}

	@Override
	public boolean getDetect() {
		return isExistingLocation();
	}

	/**
	 * @since 2.0
	 */
	@Override
	public boolean isExistingLocation() {
		return fDetectGroup.mustDetect();
	}

	@Override
	public boolean isSrc() {
		return false;
		// return true;//fLayoutGroup.isSrcBin();
	}

	@Override
	public void setVisible(boolean visible) {
		super.setVisible(visible);
		if (visible) {
			fNameGroup.postSetFocus();
		}
	}

	@Override
	public void dispose() {
		fDecorationManager.dispose();
		fLocationGroup.dispose();
		super.dispose();
	}

	/**
	 * Initialize a grid layout with the default Dialog settings.
	 */
	protected GridLayout initGridLayout(GridLayout layout, boolean margins) {
		layout.horizontalSpacing = convertHorizontalDLUsToPixels(
				IDialogConstants.HORIZONTAL_SPACING);
		layout.verticalSpacing = convertVerticalDLUsToPixels(
				IDialogConstants.VERTICAL_SPACING);
		if (margins) {
			layout.marginWidth = convertHorizontalDLUsToPixels(
					IDialogConstants.HORIZONTAL_MARGIN);
			layout.marginHeight = convertVerticalDLUsToPixels(
					IDialogConstants.VERTICAL_MARGIN);
		} else {
			layout.marginWidth = 0;
			layout.marginHeight = 0;
		}
		return layout;
	}

	/**
	 * Returns the working sets to which the new project should be added.
	 *
	 * @return the selected working sets to which the new project should be
	 *         added
	 * @since 2.0
	 */
	public IWorkingSet[] getWorkingSets() {
		return getWorkingSetGroup().getSelectedWorkingSets();
	}

	/**
	 * Sets the working sets to which the new project should be added.
	 *
	 * @param workingSets
	 *                        the initial selected working sets
	 * @since 2.0
	 */
	public void setWorkingSets(IWorkingSet[] workingSets) {
		Assert.isLegal(workingSets != null);
		getWorkingSetGroup().setWorkingSets(workingSets);
	}

	/**
	 * @since 2.0
	 */
	@Override
	public void initProjectWizardPage() {
		final IProjectWizard wizard = (IProjectWizard) getWizard();
		setWorkingSets(createWorkingSetDetector().detect(wizard.getSelection(),
				wizard.getWorkbench()));
	}

	/**
	 * @since 2.0
	 */
	@Override
	public void updateProjectWizardPage() {
		// empty
	}

	/**
	 * @since 2.0
	 */
	@Override
	public void resetProjectWizardPage() {
		// empty
	}

	/**
	 * @since 2.0
	 */
	protected final IProjectWizardState getWizardState() {
		return ((ProjectWizard) getWizard()).getWizardState();
	}

}
