package it.mice.voila.wizard.plugin;

import java.io.File;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.dialogs.IDialogPage;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

/**
 * The "New" wizard page allows setting the container for the new file as well
 * as the file name. The page will only accept file name without the extension
 * OR with the extension that matches the expected one (mpe).
 */

public class NewProjectWizardStackPage extends WizardPage {
	private Text projectName;

	private Text projectDescription;

	private Button useDefaulLocation;

	private Label labelLocation;

	private Label info;

	private Button buttonLocation;

	private Text folderText;

	private Text basePackageName;

	private String bundlePrefixKey;

	private IConfigurationElement stackConfig;

	private IConfigurationElement archetypeConfig;

	/**
	 * Constructor for SampleNewWizardPage.
	 * 
	 * @param pageName
	 */
	public NewProjectWizardStackPage(ISelection selection, String bundlePrefixKey) {
		super("projectPage", "",
				ActivatorPlugin.imageDescriptorFromPlugin(ActivatorPlugin.PLUGIN_ID, "/icons/wizard.gif"));

		this.bundlePrefixKey = bundlePrefixKey;
	}

	public String getBundlePrefixKey() {
		return bundlePrefixKey;
	}

	public void setBundlePrefixKey(IConfigurationElement config, IConfigurationElement stackConfig) {
		this.bundlePrefixKey = config.getAttribute("wizardConfigurationId");
		initialize(config, stackConfig);
	}

	/**
	 * @see IDialogPage#createControl(Composite)
	 */
	public void createControl(Composite parent) {

		Composite masterContainer = new Composite(parent, SWT.NULL);
		GridLayout masterLayout = new GridLayout();
		masterContainer.setLayout(masterLayout);
		masterLayout.numColumns = 1;
		masterLayout.verticalSpacing = 9;

		Composite container = new Composite(masterContainer, SWT.NULL);
		GridLayout layout = new GridLayout();
		container.setLayout(layout);
		layout.numColumns = 3;
		layout.verticalSpacing = 9;

		createProjectName(container);
		createProjectDescription(container);
		createOption(container);
		createLocation(container);
		createBasePackageName(container);
		createInfoLabel(masterContainer);

		initialize(null, null);
		setControl(masterContainer);
	}

	private void createInfoLabel(Composite masterContainer) {
		info = new Label(masterContainer, SWT.WRAP | SWT.BORDER);
		GridData gd = new GridData(GridData.FILL_BOTH);
		info.setLayoutData(gd);
		info.setText(""); //$NON-NLS-1$
	}

	private void createProjectName(Composite container) {
		Label label = new Label(container, SWT.NULL);
		label.setText(Policy.bind("Label.ProjectName")); //$NON-NLS-1$

		projectName = new Text(container, SWT.BORDER | SWT.SINGLE);
		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
		projectName.setLayoutData(gd);
		projectName.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				dialogChanged();
			}
		});

		label = new Label(container, SWT.NULL);
		label.setText(""); //$NON-NLS-1$
	}

	private void createProjectDescription(Composite container) {
		Label label = new Label(container, SWT.NULL);
		label.setText(Policy.bind("Label.ProjectDescription")); //$NON-NLS-1$

		projectDescription = new Text(container, SWT.BORDER | SWT.SINGLE);
		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
		projectDescription.setLayoutData(gd);
		projectDescription.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				dialogChanged();
			}
		});

		label = new Label(container, SWT.NULL);
		label.setText(""); //$NON-NLS-1$
	}

	private void createBasePackageName(Composite container) {
		Label label = new Label(container, SWT.NULL);
		label.setText(Policy.bind("Label.BasePackageName")); //$NON-NLS-1$

		basePackageName = new Text(container, SWT.BORDER | SWT.SINGLE);
		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
		basePackageName.setLayoutData(gd);

		label = new Label(container, SWT.NULL);
		label.setText(""); //$NON-NLS-1$
	}

	private void createOption(Composite container) {
		Label label = new Label(container, SWT.NULL);
		label.setText(Policy.bind("Label.UseDefaultLocation")); //$NON-NLS-1$

		useDefaulLocation = new Button(container, SWT.CHECK);
		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
		useDefaulLocation.setLayoutData(gd);
		useDefaulLocation.setText(""); //$NON-NLS-1$
		useDefaulLocation.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				dialogChanged();
			}
		});
		label = new Label(container, SWT.NULL);
		label.setText(""); //$NON-NLS-1$
	}

	private void createLocation(Composite container) {
		labelLocation = new Label(container, SWT.NULL);
		labelLocation.setText(Policy.bind("Label.Location")); //$NON-NLS-1$

		folderText = new Text(container, SWT.BORDER | SWT.SINGLE);
		GridData gdLocation = new GridData(GridData.FILL_HORIZONTAL);
		folderText.setLayoutData(gdLocation);
		// folderText.setEnabled(false);
		folderText.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				dialogChanged();
			}
		});

		buttonLocation = new Button(container, SWT.PUSH);
		buttonLocation.setText(Policy.bind("Label.Browse")); //$NON-NLS-1$
		// buttonLocation.setEnabled(false);
		buttonLocation.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				handleBrowseFolder();
			}
		});
	}

	/**
	 * Tests if the current workbench selection is a suitable container to use.
	 * 
	 * @param stackConfig
	 */
	private void initialize(IConfigurationElement config, IConfigurationElement stackConfig) {

		if (config != null) {
			setTitle(config.getAttribute("wizardTitle"));
			setDescription(config.getAttribute("wizardDescription"));
			projectName.setText(config.getAttribute("wizardProjectName"));
			projectDescription.setText(config.getAttribute("wizardProjectDescription"));
			basePackageName.setText(config.getAttribute("wizardBasePackage"));
			useDefaulLocation.setSelection(true);
			this.stackConfig = stackConfig;
			this.archetypeConfig = config;
		} else {
			String defaultText = "Default text used";
			setTitle(defaultText);
			setDescription(defaultText);
			projectName.setText(defaultText);
			projectDescription.setText(defaultText);
			basePackageName.setText(defaultText);
			useDefaulLocation.setSelection(true);
			this.stackConfig = null;
			this.archetypeConfig = null;
		}

		dialogChanged();
	}

	/**
	 * Uses the standard container selection dialog to choose the new value for the
	 * container field.
	 */
	private void handleBrowseFolder() {
		DirectoryDialog dialog = new DirectoryDialog(getShell());
		dialog.setMessage(Policy.bind("Message.SelectDestination")); //$NON-NLS-1$
		String selectedPath = dialog.open();
		if (selectedPath != null) {
			folderText.setText(selectedPath);
		}
	}

	/**
	 * Ensures that both text fields are set.
	 */

	private void dialogChanged() {
		if (useDefaulLocation.getSelection()) {
			String defaultLocation = ResourcesPlugin.getWorkspace().getRoot().getLocation().toString() + "/" //$NON-NLS-1$
					+ getProjectName();
			if (!folderText.getText().equals(defaultLocation))
				folderText.setText(defaultLocation);
		}
		labelLocation.setEnabled(!useDefaulLocation.getSelection());
		buttonLocation.setEnabled(!useDefaulLocation.getSelection());
		folderText.setEnabled(!useDefaulLocation.getSelection());
		basePackageName.setText("it.micegroup." + projectName.getText().toLowerCase());

		String fullProjectName = getRootProjectName();
		if (getProjectName().length() == 0) {
			updateStatus(Policy.bind("Message.ProjectNameRequired")); //$NON-NLS-1$
			return;
		}
		IStatus status = ResourcesPlugin.getWorkspace().validateName(fullProjectName, IResource.PROJECT);
		if (!status.isOK()) {
			updateStatus(Policy.bind("Message.ProjectNameInvalid")); //$NON-NLS-1$
			return;
		}
		IProject projectToCreate = ResourcesPlugin.getWorkspace().getRoot().getProject(fullProjectName);
		if (projectToCreate.exists()) {
			updateStatus(Policy.bind("Message.ProjectAlreadyExist")); //$NON-NLS-1$
			return;
		}

		if (getProjectDescription().length() == 0) {
			updateStatus(Policy.bind("Message.ProjectDescRequired")); //$NON-NLS-1$
			return;
		}
		if (getProjectDescription().indexOf('&') > -1) {
			updateStatus(Policy.bind("Message.ProjectDescInvalid")); //$NON-NLS-1$
			return;
		}

		if (getFolderText().length() == 0) {
			updateStatus(Policy.bind("Message.TargetLocationRequired")); //$NON-NLS-1$
			return;
		}

		String fullTargetLocation = getRootTargetLocation();
		status = ResourcesPlugin.getWorkspace().validateProjectLocation(projectToCreate, new Path(fullTargetLocation));
		if (!status.isOK()) {
			updateStatus(status.getMessage());
			return;
		}

		File f = new File(getFolderText());
		File parentFolder = new File(f.getParent());
		if (!parentFolder.isDirectory()) {
			updateStatus(Policy.bind("Message.InvalidParentFolder")); //$NON-NLS-1$
			return;
		}
		if (!parentFolder.canWrite()) {
			updateStatus(Policy.bind("Message.NoWriteableParentFolder")); //$NON-NLS-1$
			return;
		}
		f = new File(fullTargetLocation);
		if (f.exists()) {
			updateStatus(Policy.bind("Message.TargetFolderAlreadyExist", f.getAbsolutePath())); //$NON-NLS-1$
			return;
		}

		info.setText(Policy.bind("Message.InfoText", fullTargetLocation)); //$NON-NLS-1$
		updateStatus(null);
	}

	public String getRootTargetLocation() {
		// Added string trim to handle capital project name
//		int index = getFolderText().lastIndexOf("/")+1;.substring(0, index) + getFolderText().substring(getFolderText().lastIndexOf("/")+1).toLowerCase(); 
		String fullTargetLocation = getFolderText();// $NON-NLS-1$
		return fullTargetLocation;
	}

	public String getRootProjectName() {
		String fullProjectName = getProjectName(); // $NON-NLS-1$
		return fullProjectName;
	}

	private void updateStatus(String message) {
		if (message != null) {
			info.setText(""); //$NON-NLS-1$
		}
		setErrorMessage(message);
		setPageComplete(message == null);
	}

	public String getBasePackageName() {
		return basePackageName.getText();
	}

	public String getFolderText() {
		return folderText.getText();
	}

	public String getProjectName() {
		return projectName.getText();
	}

	public String getProjectDescription() {
		return projectDescription.getText();
	}

	public boolean isDefaultLocation() {
		return useDefaulLocation.getSelection();
	}

	public boolean isCurrentPage() {
		return super.isCurrentPage();
	}

	public IConfigurationElement getArchetypeConfig() {
		return archetypeConfig;
	}

	public IConfigurationElement getStackConfig() {
		return stackConfig;
	}

}