/******************************************************************************* 
 * Copyright (c) 2000, 2003 IBM Corporation and others. 
 * All rights reserved. This program and the accompanying materials! 
 * are made available under the terms of the Common Public License v1.0 
 * which accompanies this distribution, and is available at 
 * http://www.eclipse.org/legal/cpl-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.io.File;
import java.util.ArrayList;

import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.help.WorkbenchHelp;
import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
import org.eclipse.ui.internal.ide.IHelpContextIds;

/**
 * The ProjectLocationSelectionDialog is the dialog used to select the name
 * and location of a project for copying.
 */
public class ProjectLocationSelectionDialog extends SelectionStatusDialog {
	// widgets
	private Text projectNameField;
	private Text locationPathField;
	private Label locationLabel;
	private IProject project;
	private Button browseButton;

	private static String PROJECT_NAME_LABEL = IDEWorkbenchMessages.getString("ProjectLocationSelectionDialog.nameLabel"); //$NON-NLS-1$
	private static String LOCATION_LABEL = IDEWorkbenchMessages.getString("ProjectLocationSelectionDialog.locationLabel"); //$NON-NLS-1$
	private static String BROWSE_LABEL = IDEWorkbenchMessages.getString("ProjectLocationSelectionDialog.browseLabel"); //$NON-NLS-1$
	private static String DIRECTORY_DIALOG_LABEL = IDEWorkbenchMessages.getString("ProjectLocationSelectionDialog.directoryLabel"); //$NON-NLS-1$
	private static String INVALID_LOCATION_MESSAGE = IDEWorkbenchMessages.getString("ProjectLocationSelectionDialog.locationError"); //$NON-NLS-1$
	private static String PROJECT_LOCATION_SELECTION_TITLE = IDEWorkbenchMessages.getString("ProjectLocationSelectionDialog.selectionTitle"); //$NON-NLS-1$

	// constants
	private static final int SIZING_TEXT_FIELD_WIDTH = 250;

	private boolean useDefaults = true;
	private boolean firstLocationCheck;

/**
 * Create a ProjectLocationSelectionDialog on the supplied project parented by the parentShell.
 * @param parentShell
 * @param existingProject
 */
public ProjectLocationSelectionDialog(
	Shell parentShell,
	IProject existingProject) {
	super(parentShell);
	setShellStyle(getShellStyle() | SWT.RESIZE);
	setTitle(PROJECT_LOCATION_SELECTION_TITLE);
	setStatusLineAboveButtons(true);
	this.project = existingProject;
	try {
		this.useDefaults = this.getProject().getDescription().getLocation() == null;
	} catch (CoreException exception) {
		//Leave it as the default if we get a selection.
	}
}
/**
 * Check the message. If it is null then continue otherwise inform the user via the
 * status value and disable the OK.
 * @param message - the error message to show if it is not null.
 */
private void applyValidationResult(String errorMsg) {
	int code;
	boolean allowFinish = false;
	
	if (errorMsg == null) {
		code = IStatus.OK;
		errorMsg = "";	//$NON-NLS-1$
		allowFinish = true;
	} else if (firstLocationCheck)
		code = IStatus.OK;
	else
		code = IStatus.ERROR;

	updateStatus(
		new Status(
			code,
			IDEWorkbenchPlugin.getDefault().getDescriptor().getUniqueIdentifier(),
			code,
			errorMsg,
			null));
	getOkButton().setEnabled(allowFinish);			
}
/**
 * Check whether the entries are valid. If so return null. Otherwise
 * return a string that indicates the problem.
 */
private String checkValid() {
	String valid = checkValidName();
	if (valid != null)
		return valid;
	return checkValidLocation();
}
/**
 * Check if the entry in the widget location is valid. If it is valid return null. Otherwise
 * return a string that indicates the problem.
 */
private String checkValidLocation() {

	if (useDefaults)
		return null;
	else {
		String locationFieldContents = locationPathField.getText();
		if (locationFieldContents.equals("")) {//$NON-NLS-1$
			return(IDEWorkbenchMessages.getString("WizardNewProjectCreationPage.projectLocationEmpty")); //$NON-NLS-1$
		}
		else{
			IPath path = new Path("");//$NON-NLS-1$
			if (!path.isValidPath(locationFieldContents)) {
				return INVALID_LOCATION_MESSAGE;
			}
		}

		IStatus locationStatus =
			this.project.getWorkspace().validateProjectLocation(
				this.project,
				new Path(locationFieldContents));

		if (!locationStatus.isOK())
			return locationStatus.getMessage();

		return null;
	}
}
/**
 * Check if the entries in the widget are valid. If they are return null otherwise
 * return a string that indicates the problem.
 */
private String checkValidName() {

	String name = this.projectNameField.getText();
	IWorkspace workspace = getProject().getWorkspace();
	IStatus nameStatus = workspace.validateName(name, IResource.PROJECT);
	if (!nameStatus.isOK())
		return nameStatus.getMessage();
	IProject newProject = workspace.getRoot().getProject(name);
	if (newProject.exists()) {
		return IDEWorkbenchMessages.format("CopyProjectAction.alreadyExists", new Object[] { name }); //$NON-NLS-1$
	}

	return null;
}
/**
 * The <code>ProjectLocationSelectionDialog</code> implementation of this 
 * <code>SelectionStatusDialog</code> method builds a two element list - 
 * the first element is the project name and the second one is the location.
 */
protected void computeResult() {
	
	ArrayList list = new ArrayList();
	list.add(this.projectNameField.getText());
	if(useDefaults)
		list.add(Platform.getLocation().toString());
	else
		list.add(this.locationPathField.getText());
	setResult(list);
}
/* (non-Javadoc)
 * Method declared in Window.
 */
protected void configureShell(Shell shell) {
	super.configureShell(shell);
	WorkbenchHelp.setHelp(shell, IHelpContextIds.PROJECT_LOCATION_SELECTION_DIALOG);
}
/* (non-Javadoc)
 * Method declared on Dialog.
 */
protected Control createDialogArea(Composite parent) {
	// page group
	Composite composite = (Composite) super.createDialogArea(parent);

	composite.setLayout(new GridLayout());
	composite.setLayoutData(new GridData(GridData.FILL_BOTH));

	createProjectNameGroup(composite);
	createProjectLocationGroup(composite);

	return composite;
}
/**
 * Create the listener that is used to validate the location entered by the iser
 */
private void createLocationListener() {

	Listener listener = new Listener() {
		public void handleEvent(Event event) {
			firstLocationCheck = false;
			applyValidationResult(checkValid());
		}
	};

	this.locationPathField.addListener(SWT.Modify, listener);
}
/**
 * Create the listener that is used to validate the entries for the receiver
 */
private void createNameListener() {

	Listener listener = new Listener() {
		public void handleEvent(Event event) {
			setLocationForSelection();
			applyValidationResult(checkValid());
		}
	};

	this.projectNameField.addListener(SWT.Modify, listener);
}
/**
 * Creates the project location specification controls.
 *
 * @param parent the parent composite
 */
private final void createProjectLocationGroup(Composite parent) {
	Font font = parent.getFont();
	
	// project specification group
	Composite projectGroup = new Composite(parent, SWT.NONE);
	GridLayout layout = new GridLayout();
	layout.numColumns = 3;
	projectGroup.setLayout(layout);
	projectGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
	projectGroup.setFont(font);

	final Button useDefaultsButton =
		new Button(projectGroup, SWT.CHECK | SWT.RIGHT);
	useDefaultsButton.setText(IDEWorkbenchMessages.getString("ProjectLocationSelectionDialog.useDefaultLabel")); //$NON-NLS-1$
	useDefaultsButton.setSelection(this.useDefaults);
	GridData buttonData = new GridData();
	buttonData.horizontalSpan = 3;
	useDefaultsButton.setLayoutData(buttonData);
	useDefaultsButton.setFont(font);

	createUserSpecifiedProjectLocationGroup(projectGroup, !this.useDefaults);

	SelectionListener listener = new SelectionAdapter() {
		public void widgetSelected(SelectionEvent e) {
			useDefaults = useDefaultsButton.getSelection();
			browseButton.setEnabled(!useDefaults);
			locationPathField.setEnabled(!useDefaults);
			locationLabel.setEnabled(!useDefaults);
			setLocationForSelection();
			if (!useDefaults) {
				firstLocationCheck = true;
				applyValidationResult(checkValid());
			}
		}
	};
	useDefaultsButton.addSelectionListener(listener);
}
/**
 * Creates the project name specification controls.
 *
 * @param parent the parent composite
 */
private void createProjectNameGroup(Composite parent) {
	Font font = parent.getFont();
	// project specification group
	Composite projectGroup = new Composite(parent,SWT.NONE);
	GridLayout layout = new GridLayout();
	layout.numColumns = 2;
	projectGroup.setLayout(layout);
	projectGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

	// new project label
	Label projectLabel = new Label(projectGroup,SWT.NONE);
	projectLabel.setFont(font);
	projectLabel.setText(PROJECT_NAME_LABEL);

	// new project name entry field
	projectNameField = new Text(projectGroup, SWT.BORDER);
	GridData data = new GridData(GridData.FILL_HORIZONTAL);
	data.widthHint = SIZING_TEXT_FIELD_WIDTH;
	projectNameField.setLayoutData(data);
	projectNameField.setFont(font);
	
	// Set the initial value first before listener
	// to avoid handling an event during the creation.
	projectNameField.setText(getCopyNameFor(getProject().getName()));
	projectNameField.selectAll();
	
	createNameListener();
	
}
/**
 * Creates the project location specification controls.
 *
 * @return the parent of the widgets created
 * @param projectGroup the parent composite
 * @param enabled - sets the initial enabled state of the widgets
 */
private Composite createUserSpecifiedProjectLocationGroup(
	Composite projectGroup,
	boolean enabled) {
	
	Font font = projectGroup.getFont();
	
	// location label
	locationLabel = new Label(projectGroup, SWT.NONE);
	locationLabel.setFont(font);
	locationLabel.setText(LOCATION_LABEL);
	locationLabel.setEnabled(enabled);

	// project location entry field
	locationPathField = new Text(projectGroup, SWT.BORDER);
	GridData data = new GridData(GridData.FILL_HORIZONTAL);
	data.widthHint = SIZING_TEXT_FIELD_WIDTH;
	locationPathField.setLayoutData(data);
	locationPathField.setFont(font);
	locationPathField.setEnabled(enabled);

	// browse button
	this.browseButton = new Button(projectGroup, SWT.PUSH);
	this.browseButton.setFont(font);	
	this.browseButton.setText(BROWSE_LABEL);
	this.browseButton.addSelectionListener(new SelectionAdapter() {
		public void widgetSelected(SelectionEvent event) {
			handleLocationBrowseButtonPressed();
		}
	});
	this.browseButton.setEnabled(enabled);
	setButtonLayoutData(this.browseButton);

	// Set the initial value first before listener
	// to avoid handling an event during the creation.
	try {
		IPath location = this.getProject().getDescription().getLocation();
		if (location == null)
			setLocationForSelection();
		else
			locationPathField.setText(location.toString());
	} catch (CoreException exception) {
		//Set it to the default if possible as there is no info yet
		 setLocationForSelection();
	}

	createLocationListener();
	return projectGroup;

}
/**
 * Generates a new name for the project that does not have any collisions.
 */
private String getCopyNameFor(String projectName) {

	IWorkspace workspace = getProject().getWorkspace();
	if (!workspace.getRoot().getProject(projectName).exists())
		return projectName;

	int counter = 1;
	while (true) {
		String nameSegment;
		if (counter > 1) {
			nameSegment = IDEWorkbenchMessages.format(IDEWorkbenchMessages.getString("CopyProjectAction.copyNameTwoArgs"), new Object[] {new Integer(counter), projectName}); //$NON-NLS-1$
		}
		else {
			nameSegment = IDEWorkbenchMessages.format(IDEWorkbenchMessages.getString("CopyProjectAction.copyNameOneArg"), new Object[] {projectName}); //$NON-NLS-1$
		}
	
		if (!workspace.getRoot().getProject(nameSegment).exists())
			return nameSegment;

		counter++;
	}

}
/**
 * Get the project being manipulated.
 */
private IProject getProject() {
	return this.project;
}
/**
 *	Open an appropriate directory browser
 */
private void handleLocationBrowseButtonPressed() {
	DirectoryDialog dialog = new DirectoryDialog(locationPathField.getShell());
	dialog.setMessage(DIRECTORY_DIALOG_LABEL);
	
	String dirName = locationPathField.getText();
	if (!dirName.equals("")) {//$NON-NLS-1$
		File path = new File(dirName);
		if (path.exists())
			dialog.setFilterPath(dirName);
	}

	String selectedDirectory = dialog.open();
	if (selectedDirectory != null)
		locationPathField.setText(selectedDirectory);
}
/**
 * Set the location to the default location if we are set to useDefaults.
 */
private void setLocationForSelection() {
	if (useDefaults) {
		IPath defaultPath = Platform.getLocation().append(projectNameField.getText());
		locationPathField.setText(defaultPath.toOSString());
	}
}
}
