/*******************************************************************************
 * Copyright (c) 2000, 2010 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Sebastian Davids <sdavids@gmx.de> - Fix for bug 19346 - Dialog
 *     font should be activated and used by other components.
 *******************************************************************************/

package org.eclipse.ui.dialogs;

import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectNatureDescriptor;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Point;
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.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
import org.eclipse.ui.internal.ide.IIDEHelpContextIds;
import org.eclipse.ui.internal.ide.dialogs.CreateLinkedResourceGroup;

/**
 * The NewFolderDialog is used to create a new folder.
 * The folder can optionally be linked to a file system folder.
 * <p>
 * This class may be instantiated; it is not intended to be subclassed.
 * </p>
 * @noextend This class is not intended to be subclassed by clients.
 */
public class NewFolderDialog extends SelectionStatusDialog {
	// widgets
	private Text folderNameField;

	private Button advancedButton;

	private CreateLinkedResourceGroup linkedResourceGroup;

	private IContainer container;

	private boolean firstLinkCheck = true;

	/**
	 * Parent composite of the advanced widget group for creating
	 * linked resources.
	 */
	private Composite linkedResourceParent;

	/**
	 * Linked resources widget group. Null if advanced section is not visible.
	 */
	private Composite linkedResourceComposite;

	/**
	 * Height of the dialog without the "advanced" linked resource group.
	 * Set when the advanced group is first made visible.
	 */
	private int basicShellHeight = -1;

	/**
	 * Creates a NewFolderDialog
	 *
	 * @param parentShell parent of the new dialog
	 * @param container parent of the new folder
	 */
	public NewFolderDialog(Shell parentShell, IContainer container) {
		super(parentShell);
		this.container = container;
		setTitle(IDEWorkbenchMessages.NewFolderDialog_title);
		setStatusLineAboveButtons(true);
	}

	/**
	 * Creates the folder using the name and link target entered
	 * by the user.
	 * Sets the dialog result to the created folder.
	 */
	@Override
	protected void computeResult() {
		//Do nothing here as we
		//need to know the result
	}

	@Override
	protected void configureShell(Shell shell) {
		super.configureShell(shell);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(shell,
				IIDEHelpContextIds.NEW_FOLDER_DIALOG);
	}

	/**
	 * @see org.eclipse.jface.window.Window#create()
	 */
	@Override
	public void create() {
		super.create();
		// initially disable the ok button since we don't preset the
		// folder name field
		getButton(IDialogConstants.OK_ID).setEnabled(false);
	}

	/**
	 * Creates the widget for advanced options.
	 *
	 * @param parent the parent composite
	 */
	protected void createAdvancedControls(Composite parent) {
		Preferences preferences = ResourcesPlugin.getPlugin()
				.getPluginPreferences();

		if (preferences.getBoolean(ResourcesPlugin.PREF_DISABLE_LINKING) == false
				&& isValidContainer()) {
			linkedResourceParent = new Composite(parent, SWT.NONE);
			linkedResourceParent.setFont(parent.getFont());
			linkedResourceParent.setLayoutData(new GridData(
					GridData.FILL_HORIZONTAL));
			GridLayout layout = new GridLayout();
			layout.marginHeight = 0;
			layout.marginWidth = 0;
			linkedResourceParent.setLayout(layout);

			advancedButton = new Button(linkedResourceParent, SWT.PUSH);
			advancedButton.setFont(linkedResourceParent.getFont());
			advancedButton.setText(IDEWorkbenchMessages.showAdvanced);
			setButtonLayoutData(advancedButton);
			GridData data = (GridData) advancedButton.getLayoutData();
			data.horizontalAlignment = GridData.BEGINNING;
			advancedButton.setLayoutData(data);
			advancedButton.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					handleAdvancedButtonSelect();
				}
			});
		}
		linkedResourceGroup = new CreateLinkedResourceGroup(IResource.FOLDER,
				new Listener() {
					@Override
					public void handleEvent(Event e) {
						validateLinkedResource();
						firstLinkCheck = false;
					}
				}, new CreateLinkedResourceGroup.IStringValue() {
					@Override
					public void setValue(String string) {
						folderNameField.setText(string);
					}

					@Override
					public String getValue() {
						return folderNameField.getText();
					}

					@Override
					public IResource getResource() {
						return container;
					}
				});
	}

	@Override
	protected Control createDialogArea(Composite parent) {
		Composite composite = (Composite) super.createDialogArea(parent);
		composite.setLayout(new GridLayout());
		composite.setLayoutData(new GridData(GridData.FILL_BOTH));

		createFolderNameGroup(composite);
		createAdvancedControls(composite);
		return composite;
	}

	/**
	 * Creates the folder name specification controls.
	 *
	 * @param parent the parent composite
	 */
	private void createFolderNameGroup(Composite parent) {
		Font font = parent.getFont();
		// project specification group
		Composite folderGroup = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		folderGroup.setLayout(layout);
		folderGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

		// new folder label
		Label folderLabel = new Label(folderGroup, SWT.NONE);
		folderLabel.setFont(font);
		folderLabel.setText(IDEWorkbenchMessages.NewFolderDialog_nameLabel);

		// new folder name entry field
		folderNameField = new Text(folderGroup, SWT.BORDER);
		GridData data = new GridData(GridData.FILL_HORIZONTAL);
		data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
		folderNameField.setLayoutData(data);
		folderNameField.setFont(font);
		folderNameField.addListener(SWT.Modify, new Listener() {
			@Override
			public void handleEvent(Event event) {
				validateLinkedResource();
			}
		});
	}

	/**
	 * Creates a folder resource handle for the folder with the given name.
	 * The folder handle is created relative to the container specified during
	 * object creation.
	 *
	 * @param folderName the name of the folder resource to create a handle for
	 * @return the new folder resource handle
	 */
	private IFolder createFolderHandle(String folderName) {
		IWorkspaceRoot workspaceRoot = container.getWorkspace().getRoot();
		IPath folderPath = container.getFullPath().append(folderName);
		IFolder folderHandle = workspaceRoot.getFolder(folderPath);

		return folderHandle;
	}

	/**
	 * Creates a new folder with the given name and optionally linking to
	 * the specified link target.
	 *
	 * @param folderName name of the new folder
	 * @param linkTarget name of the link target folder. may be null.
	 * @return IFolder the new folder
	 */
	private IFolder createNewFolder(String folderName, final URI linkTarget) {
		final IFolder folderHandle = createFolderHandle(folderName);

		WorkspaceModifyOperation operation = new WorkspaceModifyOperation() {
			@Override
			public void execute(IProgressMonitor monitor) throws CoreException {
				try {
					monitor
							.beginTask(
									IDEWorkbenchMessages.NewFolderDialog_progress,
									2000);
					if (monitor.isCanceled()) {
						throw new OperationCanceledException();
					}
					if (linkTarget == null) {
						folderHandle.create(false, true, monitor);
					} else {
						folderHandle.createLink(linkTarget,
								IResource.ALLOW_MISSING_LOCAL, monitor);
					}
					if (monitor.isCanceled()) {
						throw new OperationCanceledException();
					}
				} finally {
					monitor.done();
				}
			}
		};
		try {
			PlatformUI.getWorkbench().getProgressService().busyCursorWhile(
					operation);
		} catch (InterruptedException exception) {
			return null;
		} catch (InvocationTargetException exception) {
			if (exception.getTargetException() instanceof CoreException) {
				ErrorDialog.openError(getShell(),
						IDEWorkbenchMessages.NewFolderDialog_errorTitle, null, // no special message
						((CoreException) exception.getTargetException())
								.getStatus());
			} else {
				// CoreExceptions are handled above, but unexpected runtime exceptions and errors may still occur.
				IDEWorkbenchPlugin.log(getClass(),
						"createNewFolder", exception.getTargetException()); //$NON-NLS-1$
				MessageDialog
						.openError(
								getShell(),
								IDEWorkbenchMessages.NewFolderDialog_errorTitle,
								NLS
										.bind(
												IDEWorkbenchMessages.NewFolderDialog_internalError,
												exception.getTargetException()
														.getMessage()));
			}
			return null;
		}
		return folderHandle;
	}

	/**
	 * Shows/hides the advanced option widgets.
	 */
	protected void handleAdvancedButtonSelect() {
		Shell shell = getShell();
		Point shellSize = shell.getSize();
		Composite composite = (Composite) getDialogArea();

		if (linkedResourceComposite != null) {
			linkedResourceComposite.dispose();
			linkedResourceComposite = null;
			composite.layout();
			shell.setSize(shellSize.x, basicShellHeight);
			advancedButton.setText(IDEWorkbenchMessages.showAdvanced);
		} else {
			if (basicShellHeight == -1) {
				basicShellHeight = shell.computeSize(SWT.DEFAULT, SWT.DEFAULT,
						true).y;
			}
			linkedResourceComposite = linkedResourceGroup
					.createContents(linkedResourceParent);
			shellSize = shell.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
			shell.setSize(shellSize);
			composite.layout();
			advancedButton.setText(IDEWorkbenchMessages.hideAdvanced);
		}
	}

	/**
	 * Returns whether the container specified in the constructor is
	 * a valid parent for creating linked resources.
	 *
	 * @return boolean <code>true</code> if the container specified in
	 * 	the constructor is a valid parent for creating linked resources.
	 * 	<code>false</code> if no linked resources may be created with the
	 * 	specified container as a parent.
	 */
	private boolean isValidContainer() {
		if (container.getType() != IResource.PROJECT
				&& container.getType() != IResource.FOLDER) {
			return false;
		}

		try {
			IWorkspace workspace = IDEWorkbenchPlugin.getPluginWorkspace();
			IProject project = container.getProject();
			String[] natureIds = project.getDescription().getNatureIds();

			for (int i = 0; i < natureIds.length; i++) {
				IProjectNatureDescriptor descriptor = workspace
						.getNatureDescriptor(natureIds[i]);
				if (descriptor != null
						&& descriptor.isLinkingAllowed() == false) {
					return false;
				}
			}
		} catch (CoreException exception) {
			// project does not exist or is closed
			return false;
		}
		return true;
	}

	/**
	 * Update the dialog's status line to reflect the given status. It is safe to call
	 * this method before the dialog has been opened.
	 */
	@Override
	protected void updateStatus(IStatus status) {
		if (firstLinkCheck && status != null) {
			// don't show the first validation result as an error.
			// fixes bug 29659
			Status newStatus = new Status(IStatus.OK, status.getPlugin(),
					status.getCode(), status.getMessage(), status
							.getException());
			super.updateStatus(newStatus);
		} else {
			super.updateStatus(status);
		}
	}

	/**
	 * Update the dialog's status line to reflect the given status. It is safe to call
	 * this method before the dialog has been opened.
	 * @param severity
	 * @param message
	 */
	private void updateStatus(int severity, String message) {
		updateStatus(new Status(severity, IDEWorkbenchPlugin.IDE_WORKBENCH,
				severity, message, null));
	}

	/**
	 * Checks whether the folder name and link location are valid.
	 * Disable the OK button if the folder name and link location are valid.
	 * a message that indicates the problem otherwise.
	 */
	private void validateLinkedResource() {
		boolean valid = validateFolderName();

		if (valid) {
			IFolder linkHandle = createFolderHandle(folderNameField.getText());
			IStatus status = linkedResourceGroup
					.validateLinkLocation(linkHandle);

			if (status.getSeverity() != IStatus.ERROR) {
				getOkButton().setEnabled(true);
			} else {
				getOkButton().setEnabled(false);
			}

			if (status.isOK() == false) {
				updateStatus(status);
			}
		} else {
			getOkButton().setEnabled(false);
		}
	}

	/**
	 * Checks if the folder name is valid.
	 *
	 * @return null if the new folder name is valid.
	 * 	a message that indicates the problem otherwise.
	 */
	private boolean validateFolderName() {
		String name = folderNameField.getText();
		IWorkspace workspace = container.getWorkspace();
		IStatus nameStatus = workspace.validateName(name, IResource.FOLDER);

		if ("".equals(name)) { //$NON-NLS-1$
			updateStatus(IStatus.ERROR,
					IDEWorkbenchMessages.NewFolderDialog_folderNameEmpty);
			return false;
		}
		if (nameStatus.isOK() == false) {
			updateStatus(nameStatus);
			return false;
		}
		IPath path = new Path(name);
		if (container.getFolder(path).exists()
				|| container.getFile(path).exists()) {
			updateStatus(IStatus.ERROR, NLS.bind(
					IDEWorkbenchMessages.NewFolderDialog_alreadyExists, name));
			return false;
		}
		updateStatus(IStatus.OK, ""); //$NON-NLS-1$
		return true;
	}

	@Override
	protected void okPressed() {
		URI linkTarget = linkedResourceGroup.getLinkTargetURI();
		IFolder folder = createNewFolder(folderNameField.getText(), linkTarget);
		if (folder == null) {
			return;
		}

		setSelectionResult(new IFolder[] { folder });

		super.okPressed();
	}
}
