/*******************************************************************************
 * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
 * 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:
 *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.xsl.internal.debug.ui;

import java.io.File;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
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.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.variables.IStringVariableManager;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
import org.eclipse.debug.ui.StringVariableSelectionDialog;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.window.Window;
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.FileDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
import org.eclipse.ui.dialogs.ISelectionStatusValidator;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.eclipse.ui.views.navigator.ResourceComparator;

/**
 * A block that shows a text box with buttons for browsing workspace or the filesystem
 * in order to populate the text box with a file path.
 * 
 * @author Doug Satchwell
 */
public abstract class ResourceSelectionBlock extends AbstractLaunchConfigurationTab
{
	protected static final int ERROR_DIRECTORY_NOT_SPECIFIED = 1;
	protected static final int ERROR_DIRECTORY_DOES_NOT_EXIST = 2;
	protected static final int GROUP_NAME = 3;
	protected static final int USE_DEFAULT_RADIO = 4;
	protected static final int USE_OTHER_RADIO = 5;
	protected static final int DIRECTORY_DIALOG_MESSAGE = 6;
	protected static final int WORKSPACE_DIALOG_MESSAGE = 7;
	protected static final int VARIABLES_BUTTON = 8;
	protected static final int FILE_SYSTEM_BUTTON = 9;
	protected static final int WORKSPACE_BUTTON = 10;
	protected static final int WORKSPACE_DIALOG_TITLE = 11;

	protected Button fWorkspaceButton;
	protected Button fFileSystemButton;
	protected Button fVariablesButton;
	protected Button useDefaultCheckButton;
	protected Text resourceText;
	protected WidgetListener widgetListener = new WidgetListener();
	private ILaunchConfiguration fLaunchConfiguration;
	protected final boolean showDefault;
	private final int resourceType;
	private final boolean mustExist;
	protected boolean required;
	protected String defaultOutputFile;
	protected String outputFile;
	protected String fileLabel = Messages.getString("ResourceSelectionBlock.0"); //$NON-NLS-1$

	private final ISelectionStatusValidator validator = new ISelectionStatusValidator()
	{
		public IStatus validate(Object[] selection)
		{
			if (selection.length == 0)
			{
				return new Status(IStatus.ERROR, XSLDebugUIPlugin.PLUGIN_ID, 0, "", null);  //$NON-NLS-1$
			}
			for (int i = 0; i < selection.length; i++)
			{
				if (resourceType == IResource.FOLDER && !(selection[i] instanceof IFolder))
					return new Status(IStatus.ERROR, XSLDebugUIPlugin.PLUGIN_ID, 0, "", null);  //$NON-NLS-1$
				else if (resourceType == IResource.FILE && !(selection[i] instanceof IFile))
					return new Status(IStatus.ERROR, XSLDebugUIPlugin.PLUGIN_ID, 0, "", null);  //$NON-NLS-1$
			}
			return new Status(IStatus.OK, XSLDebugUIPlugin.PLUGIN_ID, 0, "", null);  //$NON-NLS-1$
		}
	};

	class WidgetListener extends SelectionAdapter implements ModifyListener
	{
		public void modifyText(ModifyEvent e)
		{
			textModified();
			updateLaunchConfigurationDialog();
		}

		@Override
		public void widgetSelected(SelectionEvent e)
		{
			Object source = e.getSource();
			if (source == fWorkspaceButton)
			{
				handleWorkspaceResourceBrowseButtonSelected();
			}
			else if (source == fFileSystemButton)
			{
				handleExternalResourceBrowseButtonSelected();
			}
			else if (source == fVariablesButton)
			{
				handleResourceVariablesButtonSelected();
			}
			else if (source == useDefaultCheckButton)
			{
				updateResourceText(useDefaultCheckButton.getSelection());
			}
		}
	}

	/**
	 * Same as <code>new ResourceSelectionBlock(true)</code>
	 */
	public ResourceSelectionBlock()
	{
		this(true);
	}

	/**
	 * Same as <code>new ResourceSelectionBlock(IResource.FOLDER,showDefault)</code>
	 * 
	 * @param showDefault true if this should have a 'Show Default' button
	 */
	public ResourceSelectionBlock(boolean showDefault)
	{
		this(IResource.FOLDER, showDefault);
	}

	/**
	 * Same as <code>new ResourceSelectionBlock(resourceType,showDefault,true)</code>
	 * 
	 * @param resourceType the type of resource to select - IResource.FOLDER or IResource.FILE
	 * @param showDefault true if this should have a 'Show Default' button
	 */
	public ResourceSelectionBlock(int resourceType, boolean showDefault)
	{
		this(resourceType, showDefault, true);
	}

	/**
	 * Same as <code>new ResourceSelectionBlock(resourceType,showDefault,required,true)</code>
	 * 
	 * @param resourceType the type of resource to select - IResource.FOLDER or IResource.FILE
	 * @param showDefault true if this should have a 'Show Default' button
	 * @param required true if a blank text box is invalid
	 */
	public ResourceSelectionBlock(int resourceType, boolean showDefault, boolean required)
	{
		this(resourceType, showDefault, required, true);
	}

	/**
	 * Create a new instance of this.
	 * 
	 * @param resourceType the type of resource to select - IResource.FOLDER or IResource.FILE
	 * @param showDefault true if this should have a 'Show Default' button
	 * @param required true if a blank text box is invalid
	 * @param mustExist true of the selected resource must already exist
	 */
	public ResourceSelectionBlock(int resourceType, boolean showDefault, boolean required, boolean mustExist)
	{
		super();
		this.showDefault = showDefault;
		this.resourceType = resourceType;
		this.required = required;
		this.mustExist = mustExist;
	}

	public void createControl(Composite parent)
	{
		Composite group = createContainer(parent);
		setControl(group);
		createContents(group);
	}

	protected Composite createContainer(Composite parent)
	{
		Group group = new Group(parent, SWT.NONE);
		group.setText(getMessage(GROUP_NAME));
		// TODO PlatformUI.getWorkbench().getHelpSystem().setHelp...
		GridLayout groupLayout = new GridLayout();
		groupLayout.numColumns = 2;
		groupLayout.makeColumnsEqualWidth = false;
		group.setLayout(groupLayout);
		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
		group.setLayoutData(gd);
		group.setFont(parent.getFont());
		return group;
	}

	protected void createContents(Composite parent)
	{
		createCheckboxAndText(parent);
		createButtons(parent);
	}

	protected void createCheckboxAndText(Composite parent)
	{
		if (showDefault)
		{
			useDefaultCheckButton = createCheckButton(parent, getMessage(USE_DEFAULT_RADIO));
			GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
			gd.horizontalSpan = 2;
			useDefaultCheckButton.setLayoutData(gd);
			useDefaultCheckButton.addSelectionListener(widgetListener);
		}

		Composite specificFileComp = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout(2, false);
		layout.marginWidth = 0;
		if (showDefault)
			layout.marginLeft = 20;
		else
			layout.marginLeft = 0;
		layout.marginHeight = 0;
		specificFileComp.setLayout(layout);
		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
		gd.horizontalSpan = 2;
		specificFileComp.setLayoutData(gd);

		if (showDefault)
		{
			Label label = new Label(specificFileComp, SWT.NONE);
			label.setText(fileLabel);
		}

		resourceText = new Text(specificFileComp, SWT.SINGLE | SWT.BORDER);
		gd = new GridData(GridData.FILL_HORIZONTAL);
		gd.horizontalSpan = showDefault ? 1 : 2;
		resourceText.setLayoutData(gd);
		resourceText.setFont(parent.getFont());
		resourceText.addModifyListener(widgetListener);
	}

	protected void createButtons(Composite parent)
	{
		// filler
		new Label(parent, SWT.NONE);

		Composite buttonComp = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout(3, false);
		layout.marginHeight = 0;
		layout.marginWidth = 0;
		buttonComp.setLayout(layout);
		GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
		gd.horizontalSpan = 1;
		buttonComp.setLayoutData(gd);
		buttonComp.setFont(parent.getFont());

		fWorkspaceButton = createPushButton(buttonComp, getMessage(WORKSPACE_BUTTON), null);
		fWorkspaceButton.addSelectionListener(widgetListener);

		fFileSystemButton = createPushButton(buttonComp, getMessage(FILE_SYSTEM_BUTTON), null);
		fFileSystemButton.addSelectionListener(widgetListener);

		fVariablesButton = createPushButton(buttonComp, getMessage(VARIABLES_BUTTON), null);
		fVariablesButton.addSelectionListener(widgetListener);
	}

	protected void updateResourceText(boolean useDefault)
	{
		if (useDefault)
		{
			resourceText.setText(defaultOutputFile == null ? "" : defaultOutputFile); //$NON-NLS-1$
		}
		else
		{
			resourceText.setText(outputFile == null ? "" : outputFile); //$NON-NLS-1$
		}
		resourceText.setEnabled(!useDefault);
		fFileSystemButton.setEnabled(!useDefault);
		fVariablesButton.setEnabled(!useDefault);
		fWorkspaceButton.setEnabled(!useDefault);
	}

	@Override
	public void dispose()
	{
	}

	protected void handleExternalResourceBrowseButtonSelected()
	{
		String currentWorkingDir = getText();
		String selected = null;
		if (resourceType == IResource.FOLDER)
		{
			DirectoryDialog dialog = new DirectoryDialog(getShell());
			dialog.setMessage(getMessage(DIRECTORY_DIALOG_MESSAGE));
			if (!currentWorkingDir.trim().equals("")) //$NON-NLS-1$
			{
				File path = new File(currentWorkingDir);
				if (path.exists())
				{
					dialog.setFilterPath(currentWorkingDir);
				}
			}
			selected = dialog.open();
		}
		else
		{
			FileDialog dialog = new FileDialog(getShell());
			if (!currentWorkingDir.trim().equals("")) //$NON-NLS-1$
			{
				File path = new File(currentWorkingDir);
				if (path.exists())
				{
					dialog.setFilterPath(currentWorkingDir);
				}
			}
			String[] fileExtensions = getFileExtensions();
			if (fileExtensions != null)
			{
				String[] filterExtensions = new String[fileExtensions.length];
				for (int i = 0; i < fileExtensions.length; i++)
				{
					String ext = fileExtensions[i];
					filterExtensions[i] = "*." + ext; //$NON-NLS-1$
				}
				dialog.setFilterExtensions(filterExtensions);
			}
			selected = dialog.open();
		}
		if (selected != null)
		{
			resourceText.setText(selected);
		}
	}

	protected String[] getFileExtensions()
	{
		return null;
	}

	protected void handleWorkspaceResourceBrowseButtonSelected()
	{
		IPath path = openWorkspaceResourceDialog();
		if (path != null)
			setText("${workspace_loc:" + path.toString() + "}");   //$NON-NLS-1$ //$NON-NLS-2$
	}

	protected IPath openWorkspaceResourceDialog()
	{
		IResource currentResource = getResource();
		ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(getShell(), new WorkbenchLabelProvider(), new WorkbenchContentProvider());
		dialog.setTitle(getMessage(WORKSPACE_DIALOG_TITLE));
		dialog.setMessage(getMessage(WORKSPACE_DIALOG_MESSAGE));
		dialog.setValidator(validator);
		dialog.addFilter(new ViewerFilter()
		{
			@Override
			public boolean select(Viewer viewer, Object parentElement, Object element)
			{
				if (element instanceof IContainer)
					return true;
				if (resourceType != IResource.FILE)
					return false;
				IFile file = (IFile) element;
				String[] extensions = getFileExtensions();
				if (extensions == null)
					return true;
				String fileExt = file.getFileExtension();
				if (fileExt != null)
				{
					for (String ext : extensions)
					{
						if (fileExt.equalsIgnoreCase(ext))
							return true;
					}
				}
				return false;
			}
		});
		ViewerFilter filter = getResourceFilter();
		if (filter != null)
			dialog.addFilter(filter);
		dialog.setInput(ResourcesPlugin.getWorkspace().getRoot());
		dialog.setInitialSelection(currentResource);
		dialog.setComparator(new ResourceComparator(ResourceComparator.NAME));
		dialog.setAllowMultiple(false);

		if (dialog.open() == Window.OK)
		{
			Object[] elements = dialog.getResult();
			if (elements.length > 0)
				return ((IResource) elements[0]).getFullPath();
		}
		return null;
	}

	protected ViewerFilter getResourceFilter()
	{
		return null;
	}

	/**
	 * Returns the selected workspace container,or <code>null</code>
	 */
	protected IResource getResource()
	{
		String path = getText();
		if (path.length() > 0)
		{
			IResource res = null;
			IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
			if (path.startsWith("${workspace_loc:"))  //$NON-NLS-1$
			{
				IStringVariableManager manager = VariablesPlugin.getDefault().getStringVariableManager();
				try
				{
					path = manager.performStringSubstitution(path, false);
					if (resourceType == IResource.FOLDER)
					{
						IContainer[] containers = root.findContainersForLocation(new Path(path));
						if (containers.length > 0)
						{
							res = containers[0];
						}
					}
					else if (resourceType == IResource.FILE)
					{
						IFile[] files = root.findFilesForLocation(new Path(path));
						if (files.length > 0)
						{
							res = files[0];
						}
					}
				}
				catch (CoreException e)
				{
				}
			}
			else
			{
				res = root.findMember(path);
			}
			return res;
		}
		return null;
	}

	protected void handleResourceVariablesButtonSelected()
	{
		StringVariableSelectionDialog dialog = new StringVariableSelectionDialog(getShell());
		dialog.open();
		String variableText = dialog.getVariableExpression();
		if (variableText != null)
		{
			resourceText.insert(variableText);
		}
	}

	protected abstract void setDefaultResource();

	@Override
	public boolean isValid(ILaunchConfiguration config)
	{
		setErrorMessage(null);
		setMessage(null);
		// if variables are present, we cannot resolve the directory
		String workingDirPath = getText();
		if (workingDirPath.indexOf("${") >= 0) //$NON-NLS-1$
		{
			IStringVariableManager manager = VariablesPlugin.getDefault().getStringVariableManager();
			try
			{
				manager.validateStringVariables(workingDirPath);
				if (mustExist)
				{
					String path = manager.performStringSubstitution(workingDirPath);
					validateResource(path);
				}
			}
			catch (CoreException e)
			{
				setErrorMessage(e.getMessage());
				return false;
			}
		}
		else if (mustExist && workingDirPath.length() > 0)
		{
			return validateResource(workingDirPath);
		}
		else if (required && workingDirPath.length() == 0)
		{
			setErrorMessage(getMessage(ERROR_DIRECTORY_NOT_SPECIFIED));
		}
		return true;
	}

	protected boolean validateResource(String workingDirPath)
	{
		if (resourceType == IResource.FOLDER)
		{
			IContainer container = (IContainer) getResource();
			if (container == null)
			{
				File dir = new File(workingDirPath);
				if (dir.isDirectory())
				{
					return true;
				}
			}
			else
				return true;
		}
		else if (resourceType == IResource.FILE)
		{
			File file = new File(workingDirPath);
			if (file.isFile())
			{
				return true;
			}
		}
		setErrorMessage(getMessage(ERROR_DIRECTORY_DOES_NOT_EXIST));
		return false;
	}

	protected abstract String getMessage(int type);

	protected void textModified()
	{
	}

	protected String getText()
	{
		return resourceText.getText().trim();
	}

	protected void setText(String text)
	{
		resourceText.setText(text);
	}

	protected void setLaunchConfiguration(ILaunchConfiguration config)
	{
		fLaunchConfiguration = config;
	}

	protected ILaunchConfiguration getLaunchConfiguration()
	{
		return fLaunchConfiguration;
	}
}