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

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());
			}
		}
	}

	public ResourceSelectionBlock()
	{
		this(true);
	}

	public ResourceSelectionBlock(boolean showDefault)
	{
		this(IResource.FOLDER, showDefault);
	}

	public ResourceSelectionBlock(int resourceType, boolean showDefault)
	{
		this(resourceType, showDefault, true);
	}

	public ResourceSelectionBlock(int resourceType, boolean showDefault, boolean required)
	{
		this(resourceType, showDefault, required, true);
	}

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