/*******************************************************************************
 * Copyright (c) 2000, 2018 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *      Alexander Fedorov <Alexander.Fedorov@borland.com>
 *     		- Bug 172000 [Wizards] WizardNewFileCreationPage should support overwriting existing resources
 *
 * This file is copied  from org.eclipse.ui.internal.ide.misc.ResourceAndContainerGroup
 *******************************************************************************/
package org.eclipse.ocl.examples.emf.validation.validity.ui.ripoffs;

import org.eclipse.core.resources.IContainer;
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.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.ocl.examples.emf.validation.validity.ui.messages.ValidityUIMessages;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;

/**
 * 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

	/**
	 * Constant for no problem.
	 */
	public static final int PROBLEM_NONE = 0;
	/**
	 * Constant for empty resource.
	 */
	public static final int PROBLEM_RESOURCE_EMPTY = 1;

	/**
	 * Constant for resource already exists.
	 */
	public static final int PROBLEM_RESOURCE_EXIST = 2;

	/**
	 * Constant for invalid path.
	 */
	public static final int PROBLEM_PATH_INVALID = 4;

	/**
	 * Constant for empty container.
	 */
	public static final int PROBLEM_CONTAINER_EMPTY = 5;

	/**
	 * Constant for project does not exist.
	 */
	public static final int PROBLEM_PROJECT_DOES_NOT_EXIST = 6;

	/**
	 * Constant for invalid name.
	 */
	public static final int PROBLEM_NAME_INVALID = 7;

	/**
	 * Constant for path already occupied.
	 */
	public static final int PROBLEM_PATH_OCCUPIED = 8;

	// 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 = ValidityUIMessages.ResourceGroup_resource;

	// 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;

	/**
	 * The resource extension for the resource name field.
	 *
	 * @see ResourceAndContainerGroup#setResourceExtension(String)
	 */
	private String resourceExtension;

	// 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)
	 * @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(SWT.FILL, SWT.FILL, true, true));
		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,
					SIZING_TEXT_FIELD_WIDTH);
		}

		// 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);
		resourceNameField.addFocusListener(new FocusAdapter() {
			@Override
			public void focusLost(FocusEvent e) {
				handleResourceNameFocusLostEvent();
			}
		});
		GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL
				| GridData.GRAB_HORIZONTAL);
		data.widthHint = SIZING_TEXT_FIELD_WIDTH;
		resourceNameField.setLayoutData(data);
		resourceNameField.setFont(font);
		//		BidiUtils.applyBidiProcessing(resourceNameField, StructuredTextTypeHandlerFactory.FILE);	-- first available on Kepler
		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.
	 *
	 * @return The path of the container, or <code>null</code>
	 */
	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 name of the chosen resource, or an empty
	 * string if no resource has been entered. <br>
	 * <br>
	 * The name will include the resource extension if the preconditions are
	 * met.
	 *
	 * @see ResourceAndContainerGroup#setResourceExtension(String)
	 *
	 * @return The resource name
	 */
	public String getResource() {
		String resource = resourceNameField.getText();
		if (useResourceExtension()) {
			return resource + '.' + resourceExtension;
		}
		return resource;
	}

	/**
	 * Determines whether the resource extension should be added to the resource
	 * name field. <br>
	 * <br>
	 *
	 * @see ResourceAndContainerGroup#setResourceExtension(String)
	 * @return <code>true</code> if the preconditions are met; otherwise,
	 *         <code>false</code>.
	 */
	private boolean useResourceExtension() {
		String resource = resourceNameField.getText();
		if ((resourceExtension != null) && (resourceExtension.length() > 0)
				&& (resource.length() > 0)
				&& (resource.endsWith('.' + resourceExtension) == false)) {
			return true;
		}
		return false;
	}

	/**
	 * Handle the focus lost event from the resource name field. <br>
	 * Adds the resource extension to the resource name field when it loses
	 * focus (if the preconditions are met).
	 *
	 * @see ResourceAndContainerGroup#setResourceExtension(String)
	 */
	private void handleResourceNameFocusLostEvent() {
		if (useResourceExtension()) {
			setResource(resourceNameField.getText() + '.' + resourceExtension);
		}
	}

	/**
	 * Handles events for all controls in the group.
	 *
	 * @param e
	 *            org.eclipse.swt.widgets.Event
	 */
	@Override
	public void handleEvent(Event e) {
		validateControls();
		if (client != null) {
			client.handleEvent(e);
		}
	}

	/**
	 * Sets the flag indicating whether existing resources are permitted.
	 * @param value
	 */
	public void setAllowExistingResources(boolean value) {
		allowExistingResources = value;
	}

	/**
	 * Sets the value of this page's container.
	 *
	 * @param path
	 *            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(String.valueOf(value));
		validateControls();
	}

	/**
	 * Set the only file extension allowed for the resource name field. <br>
	 * <br>
	 * If a resource extension is specified, then it will always be appended
	 * with a '.' to the text from the resource name field for validation when
	 * the following conditions are met: <br>
	 * <br>
	 * (1) Resource extension length is greater than 0 <br>
	 * (2) Resource name field text length is greater than 0 <br>
	 * (3) Resource name field text does not already end with a '.' and the
	 * resource extension specified (case sensitive) <br>
	 * <br>
	 * The resource extension will not be reflected in the actual resource name
	 * field until the resource name field loses focus.
	 *
	 * @param value
	 *            The resource extension without the '.' prefix (e.g. 'java',
	 *            'xml')
	 */
	public void setResourceExtension(String value) {
		resourceExtension = 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 = ValidityUIMessages.ResourceGroup_folderEmpty;
			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 = ValidityUIMessages.ResourceGroup_noProject;
			return false;
		}
		// path is invalid if any prefix is occupied by a file
		IWorkspaceRoot root = workspace.getRoot();
		while (path.segmentCount() > 1) {
			if (root.getFile(path).exists()) {
				problemType = PROBLEM_PATH_OCCUPIED;
				problemMessage = NLS.bind(
						ValidityUIMessages.ResourceGroup_pathOccupied, path
						.makeRelative());
				return false;
			}
			path = path.removeLastSegments(1);
		}
		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(getResource());
		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 resourcePath
	 *            the path 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 = NLS.bind(
					ValidityUIMessages.ResourceGroup_nameExists,
					getResource());
			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 = getResource();

		if (resourceName.length() == 0) {
			problemType = PROBLEM_RESOURCE_EMPTY;
			problemMessage = NLS.bind(
					ValidityUIMessages.ResourceGroup_emptyName, resourceType);
			return false;
		}

		if (!Path.ROOT.isValidPath(resourceName)) {
			problemType = PROBLEM_NAME_INVALID;
			problemMessage = NLS.bind(
					ValidityUIMessages.ResourceGroup_invalidFilename,
					resourceName);
			return false;
		}
		return true;
	}

	/**
	 * Returns the flag indicating whether existing resources are permitted.
	 *
	 * @return The allow existing resources flag.
	 * @see ResourceAndContainerGroup#setAllowExistingResources(boolean)
	 */
	public boolean getAllowExistingResources() {
		return allowExistingResources;
	}

}
