package org.eclipse.ui.internal.ide.misc;

/******************************************************************************* 
 * 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 
 *  	Leon J. Breedt: Added multiple folder creation support
 */

import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.swt.SWT;
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.internal.ide.IDEWorkbenchMessages;

/**
 * Workbench-level composite for resource and container specification by the user.
 * Services such as field validation are performed by the group.
 * The group can be configured to accept existing resources, or only
 * new resources.
 */
public class ResourceAndContainerGroup implements Listener {
	// problem identifiers
	public static final int PROBLEM_NONE = 0;
	public static final int PROBLEM_RESOURCE_EMPTY = 1;
	public static final int PROBLEM_RESOURCE_EXIST = 2;
	public static final int PROBLEM_RESOURCE_CONTAINS_SEPARATOR = 3;
	public static final int PROBLEM_PATH_INVALID = 4;
	public static final int PROBLEM_CONTAINER_EMPTY = 5;
	public static final int PROBLEM_PROJECT_DOES_NOT_EXIST = 6;
	public static final int PROBLEM_NAME_INVALID = 7;
	
	// the client to notify of changes
	private Listener client;

	// whether to allow existing resources
	private boolean allowExistingResources = false;

	// resource type (file, folder, project)
	private String resourceType = IDEWorkbenchMessages.getString("ResourceGroup.resource"); //$NON-NLS-1$

	// show closed projects in the tree, by default
	private boolean showClosedProjects = true;
	
	// problem indicator
	private String problemMessage = "";//$NON-NLS-1$
	private int problemType = PROBLEM_NONE;

	// widgets
	private ContainerSelectionGroup containerGroup;
	private Text resourceNameField;

	// constants
	private static final int SIZING_TEXT_FIELD_WIDTH = 250;
/**
 * Create an instance of the group to allow the user
 * to enter/select a container and specify a resource
 * name.
 *
 * @param parent composite widget to parent the group
 * @param client object interested in changes to the group's fields value
 * @param resourceFieldLabel label to use in front of the resource name field
 * @param resourceType one word, in lowercase, to describe the resource to the user (file, folder, project)
 */
public ResourceAndContainerGroup(Composite parent, Listener client, String resourceFieldLabel, String resourceType) {
	this(parent, client, resourceFieldLabel, resourceType, true);
}
/**
 * Create an instance of the group to allow the user
 * to enter/select a container and specify a resource
 * name.
 *
 * @param parent composite widget to parent the group
 * @param client object interested in changes to the group's fields value
 * @param resourceFieldLabel label to use in front of the resource name field
 * @param resourceType one word, in lowercase, to describe the resource to the user (file, folder, project)
 * @param showClosedProjects whether or not to show closed projects
 */
public ResourceAndContainerGroup(Composite parent, Listener client, String resourceFieldLabel, String resourceType, boolean showClosedProjects) {
	this(parent,client,resourceFieldLabel, resourceType, showClosedProjects, SWT.DEFAULT);
}
/**
 * Create an instance of the group to allow the user
 * to enter/select a container and specify a resource
 * name.
 *
 * @param parent composite widget to parent the group
 * @param client object interested in changes to the group's fields value
 * @param resourceFieldLabel label to use in front of the resource name field
 * @param resourceType one word, in lowercase, to describe the resource to the user (file, folder, project)
 * @param showClosedProjects whether or not to show closed projects
 * @param heightHint height hint for the container selection widget group
 */
public ResourceAndContainerGroup(Composite parent, Listener client, String resourceFieldLabel, String resourceType, boolean showClosedProjects, int heightHint) {
	super();
	this.resourceType = resourceType;
	this.showClosedProjects = showClosedProjects;
	createContents(parent,resourceFieldLabel,heightHint);
	this.client = client;
}
/**
 * Returns a boolean indicating whether all controls in this group
 * contain valid values.
 *
 * @return boolean
 */
public boolean areAllValuesValid() {
	return problemType == PROBLEM_NONE;
}
/**
 * Creates this object's visual components.
 *
 * @param parent org.eclipse.swt.widgets.Composite
 * @param heightHint height hint for the container selection widget group
 */
protected void createContents(Composite parent,String resourceLabelString,int heightHint) {
	
	Font font = parent.getFont();	
	// server name group
	Composite composite = new Composite(parent,SWT.NONE);
	GridLayout layout = new GridLayout();
	layout.marginWidth = 0;
	layout.marginHeight = 0;
	composite.setLayout(layout);
	composite.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
	composite.setFont(font);

	// container group
	if (heightHint == SWT.DEFAULT)
		containerGroup = new ContainerSelectionGroup(composite, this, true, null,showClosedProjects);
	else
		containerGroup = new ContainerSelectionGroup(composite, this, true, null,showClosedProjects, heightHint);
	
	// resource name group
	Composite nameGroup = new Composite(composite,SWT.NONE);
	layout = new GridLayout();
	layout.numColumns = 2;
	layout.marginWidth = 0;
	nameGroup.setLayout(layout);
	nameGroup.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
	nameGroup.setFont(font);

	Label label = new Label(nameGroup,SWT.NONE);
	label.setText(resourceLabelString);
	label.setFont(font);

	// resource name entry field
	resourceNameField = new Text(nameGroup,SWT.BORDER);
	resourceNameField.addListener(SWT.Modify,this);
	GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
	data.widthHint = SIZING_TEXT_FIELD_WIDTH;
	resourceNameField.setLayoutData(data);
	resourceNameField.setFont(font);

	validateControls();
}
/**
 * Returns the path of the currently selected container
 * or null if no container has been selected. Note that
 * the container may not exist yet if the user entered
 * a new container name in the field.
 */
public IPath getContainerFullPath() {
	return containerGroup.getContainerFullPath();
}
/**
 * Returns an error message indicating the current problem with the value
 * of a control in the group, or an empty message if all controls in the
 * group contain valid values.
 *
 * @return java.lang.String
 */
public String getProblemMessage() {
	return problemMessage;
}
/**
 * Returns the type of problem with the value of a control
 * in the group.
 *
 * @return one of the PROBLEM_* constants
 */
public int getProblemType() {
	return problemType;
}
/**
 * Returns a string that is the path of the currently selected
 * container.  Returns an empty string if no container has been
 * selected.
 */
public String getResource() {
	return resourceNameField.getText();
}
/**
 * Handles events for all controls in the group.
 *
 * @param e org.eclipse.swt.widgets.Event
 */
public void handleEvent(Event e) {
	validateControls();
	if (client != null) {
		client.handleEvent(e);
	}
}
/**
 * Sets the flag indicating whether existing resources are permitted.
 */
public void setAllowExistingResources(boolean value) {
	allowExistingResources = value;
}
/**
 * Sets the value of this page's container.
 *
 * @param value Full path to the container.
 */
public void setContainerFullPath(IPath path) {
	IResource initial = 
		ResourcesPlugin.getWorkspace().getRoot().findMember(path); 
	if (initial != null) {
		if (!(initial instanceof IContainer)) {
			initial = initial.getParent();
		}
		containerGroup.setSelectedContainer((IContainer) initial);
	}
	validateControls();
}
/**
 * Gives focus to the resource name field and selects its contents
 */
public void setFocus() {
	//select the whole resource name.
	resourceNameField.setSelection(0, resourceNameField.getText().length());
	resourceNameField.setFocus();
}
/**
 * Sets the value of this page's resource name.
 *
 * @param value new value
 */
public void setResource(String value) {
	resourceNameField.setText(value);
	validateControls();
}
/**
 * Returns a <code>boolean</code> indicating whether a container name represents
 * a valid container resource in the workbench.  An error message is stored for
 * future reference if the name does not represent a valid container.
 *
 * @return <code>boolean</code> indicating validity of the container name
 */
protected boolean validateContainer() {
	IPath path = containerGroup.getContainerFullPath();
	if (path == null) {
		problemType = PROBLEM_CONTAINER_EMPTY;
		problemMessage = IDEWorkbenchMessages.getString("ResourceGroup.folderEmpty"); //$NON-NLS-1$
		return false;
	}
	IWorkspace workspace = ResourcesPlugin.getWorkspace();
	String projectName = path.segment(0);
	if (projectName == null || !workspace.getRoot().getProject(projectName).exists()) {
		problemType = PROBLEM_PROJECT_DOES_NOT_EXIST;
		problemMessage = IDEWorkbenchMessages.getString("ResourceGroup.noProject"); //$NON-NLS-1$
		return false;
	}
	return true;
}
/**
 * Validates the values for each of the group's controls.  If an invalid
 * value is found then a descriptive error message is stored for later
 * reference.  Returns a boolean indicating the validity of all of the
 * controls in the group.
 */
protected boolean validateControls() {
	// don't attempt to validate controls until they have been created
	if (containerGroup == null) {
		return false;
	}
	problemType = PROBLEM_NONE;
	problemMessage = "";//$NON-NLS-1$

	if (!validateContainer() || !validateResourceName())
		return false;

	IPath path = containerGroup.getContainerFullPath().append(resourceNameField.getText());
	return validateFullResourcePath(path);
}
/**
 * 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 containerName the container name to validate
 * @return <code>boolean</code> indicating validity of the resource path
 */
protected boolean validateFullResourcePath(IPath resourcePath) {
	IWorkspace workspace = ResourcesPlugin.getWorkspace();

	IStatus result = workspace.validatePath(resourcePath.toString(),IResource.FOLDER);
	if (!result.isOK()) {
		problemType = PROBLEM_PATH_INVALID;
		problemMessage = result.getMessage();
		return false;
	}

	if (!allowExistingResources && (workspace.getRoot().getFolder(resourcePath).exists() || workspace.getRoot().getFile(resourcePath).exists())) {
		problemType = PROBLEM_RESOURCE_EXIST;
		problemMessage = IDEWorkbenchMessages.getString("ResourceGroup.nameExists"); //$NON-NLS-1$
		return false;
	} 
	return true;
}
/**
 * Returns a <code>boolean</code> indicating whether the resource name rep-
 * resents a valid resource name in the workbench.  An error message is stored
 * for future reference if the name does not represent a valid resource name.
 *
 * @return <code>boolean</code> indicating validity of the resource name
 */
protected boolean validateResourceName() {
    String resourceName = resourceNameField.getText();

    if (resourceName.equals("")) {//$NON-NLS-1$
        problemType = PROBLEM_RESOURCE_EMPTY;
        problemMessage = IDEWorkbenchMessages.format("ResourceGroup.emptyName", new Object[] {resourceType}); //$NON-NLS-1$
        return false;
    }
    
    if(!(new Path("")).isValidSegment(resourceName)){ //$NON-NLS-1$
		problemType = PROBLEM_NAME_INVALID;
		problemMessage = IDEWorkbenchMessages.format("ResourceGroup.invalidFilename", new String[] {resourceName}); //$NON-NLS-1$
		return false;
	}
	
    return true;
}

}
