/*******************************************************************************
 * 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.tabs.output;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
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.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.wst.xsl.internal.debug.ui.ResourceSelectionBlock;
import org.eclipse.wst.xsl.internal.debug.ui.XSLDebugUIPlugin;
import org.eclipse.wst.xsl.launching.XSLLaunchConfigurationConstants;
import org.eclipse.wst.xsl.launching.XSLTRuntime;

public class OutputFileBlock extends ResourceSelectionBlock
{
	private Button openFileCheckButton;
	private Button formatFileCheckButton;
	private String inputFilename;
	private Text fileNameText;
	private String defaultOutputFileName;
	private String outputFileName;

	public OutputFileBlock()
	{
		super(IResource.FOLDER, true, true, false);
	}

	@Override
	protected String getMessage(int type)
	{
		switch (type)
		{
			case ERROR_DIRECTORY_NOT_SPECIFIED:
				return Messages.OutputFOFileBlock_DIRECTORY_NOT_SPECIFIED;
			case ERROR_DIRECTORY_DOES_NOT_EXIST:
				return Messages.OutputFOFileBlock_DIRECTORY_DOES_NOT_EXIST;
			case GROUP_NAME:
				return getName();
			case USE_DEFAULT_RADIO:
				return Messages.OutputFileBlock_0;
			case USE_OTHER_RADIO:
				return Messages.OutputFOFileBlock_OTHER_RADIO;
			case DIRECTORY_DIALOG_MESSAGE:
				return Messages.OutputFOFileBlock_DIALOG_MESSAGE;
			case WORKSPACE_DIALOG_MESSAGE:
				return Messages.OutputFOFileBlock_WORKSPACE_DIALOG_MESSAGE;
			case VARIABLES_BUTTON:
				return Messages.OutputFOFileBlock_VARIABLES_BUTTON;
			case FILE_SYSTEM_BUTTON:
				return Messages.OutputFOFileBlock_FILE_SYSTEM_BUTTON;
			case WORKSPACE_BUTTON:
				return Messages.OutputFOFileBlock_WORKSPACE_BUTTON;
			case WORKSPACE_DIALOG_TITLE:
				return Messages.OutputFOFileBlock_WORKSPACE_DIALOG_TITLE;
		}
		return "" + type; //$NON-NLS-1$
	}

	@Override
	protected void setDefaultResource()
	{}
	
	@Override
	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);

		Label label = new Label(specificFileComp, SWT.NONE);
		label.setText("Filename");

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

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

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

	@Override
	protected void createButtons(Composite parent)
	{
		Composite checkComposite = new Composite(parent,SWT.NONE);
		checkComposite.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
		GridLayout gl = new GridLayout();
		gl.marginWidth = 0;
		checkComposite.setLayout(gl);
		
		openFileCheckButton = createCheckButton(checkComposite, Messages.OutputFileBlock_8);
		GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
		gd.horizontalSpan = 1;
		openFileCheckButton.setLayoutData(gd);
		openFileCheckButton.addSelectionListener(new SelectionListener()
		{

			public void widgetDefaultSelected(SelectionEvent e)
			{
			}

			public void widgetSelected(SelectionEvent e)
			{
				if (openFileCheckButton.getSelection())
				{
					formatFileCheckButton.setEnabled(true);
					updateLaunchConfigurationDialog();
				}
				else
				{
					formatFileCheckButton.setEnabled(false);
					formatFileCheckButton.setSelection(false);
				}
			}
		});

		formatFileCheckButton = createCheckButton(checkComposite, "Format file on completion");
		gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
		gd.horizontalSpan = 1;
		formatFileCheckButton.setLayoutData(gd);
		formatFileCheckButton.addSelectionListener(new SelectionListener()
		{

			public void widgetDefaultSelected(SelectionEvent e)
			{
			}

			public void widgetSelected(SelectionEvent e)
			{
				updateLaunchConfigurationDialog();
			}
		});

		Composite buttonComp = new Composite(parent, SWT.TOP);
		GridLayout layout = new GridLayout(3, false);
		layout.marginHeight = 0;
		layout.marginWidth = 0;
		buttonComp.setLayout(layout);
		gd = new GridData(GridData.HORIZONTAL_ALIGN_END | GridData.VERTICAL_ALIGN_BEGINNING);
		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);
	}

	public String getName()
	{
		return Messages.OutputFileBlock_9;
	}

	public void initializeFrom(ILaunchConfiguration configuration)
	{
		try
		{
			inputFilename = configuration.getAttribute(XSLLaunchConfigurationConstants.ATTR_INPUT_FILE, ""); //$NON-NLS-1$
			updateDefaultOutputFile();

			boolean useDefault = configuration.getAttribute(XSLLaunchConfigurationConstants.ATTR_USE_DEFAULT_OUTPUT_FILE, true);
			useDefaultCheckButton.setSelection(useDefault);

			outputFileName = configuration.getAttribute(XSLLaunchConfigurationConstants.ATTR_OUTPUT_FILENAME, defaultOutputFileName);
			resource = configuration.getAttribute(XSLLaunchConfigurationConstants.ATTR_OUTPUT_FOLDER, defaultResource);

			updateResourceText(useDefault);

			boolean openFileOnCompletion = configuration.getAttribute(XSLLaunchConfigurationConstants.ATTR_OPEN_FILE, true);
			openFileCheckButton.setSelection(openFileOnCompletion);
			
			boolean formatFileOnCompletion = configuration.getAttribute(XSLLaunchConfigurationConstants.ATTR_FORMAT_FILE, false);
			formatFileCheckButton.setSelection(formatFileOnCompletion);
		}
		catch (CoreException e)
		{
			XSLDebugUIPlugin.log(e);
		}
	}

	public void performApply(ILaunchConfigurationWorkingCopy configuration)
	{
		boolean useDefault = useDefaultCheckButton.getSelection();
		configuration.setAttribute(XSLLaunchConfigurationConstants.ATTR_USE_DEFAULT_OUTPUT_FILE, useDefault);

		String outputFile = resourceText.getText();
		configuration.setAttribute(XSLLaunchConfigurationConstants.ATTR_OUTPUT_FOLDER, outputFile);

		String outputFileName = fileNameText.getText();
		configuration.setAttribute(XSLLaunchConfigurationConstants.ATTR_OUTPUT_FILENAME, outputFileName);

		boolean openFileOnCompletion = openFileCheckButton.getSelection();
		configuration.setAttribute(XSLLaunchConfigurationConstants.ATTR_OPEN_FILE, openFileOnCompletion);
		
		boolean formatFileOnCompletion = formatFileCheckButton.getSelection();
		configuration.setAttribute(XSLLaunchConfigurationConstants.ATTR_FORMAT_FILE, formatFileOnCompletion);
	}

	public void setDefaults(ILaunchConfigurationWorkingCopy configuration)
	{
		configuration.setAttribute(XSLLaunchConfigurationConstants.ATTR_USE_DEFAULT_OUTPUT_FILE, true);
		configuration.setAttribute(XSLLaunchConfigurationConstants.ATTR_OUTPUT_FOLDER, (String)null);
		configuration.setAttribute(XSLLaunchConfigurationConstants.ATTR_OUTPUT_FILENAME, (String)null);
		configuration.setAttribute(XSLLaunchConfigurationConstants.ATTR_OPEN_FILE, true);
		configuration.setAttribute(XSLLaunchConfigurationConstants.ATTR_FORMAT_FILE, false);
	}
	
	protected void updateResourceText(boolean useDefault)
	{
		fileNameText.setEnabled(!useDefault);
		if (useDefault)
			fileNameText.setText(defaultOutputFileName == null ? "" : defaultOutputFileName); //$NON-NLS-1$
		else
			fileNameText.setText(outputFileName == null ? defaultOutputFileName : outputFileName); //$NON-NLS-1$
		super.updateResourceText(useDefault);
	}

	private void updateDefaultOutputFile()
	{
		try
		{
			IPath path = XSLTRuntime.defaultOutputFileForInputFile(inputFilename);
			// determine whether this path exists in the workspace
			IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(path);
			if (files.length > 0)
			{// inside workspace
				IPath p = new Path(files[0].getProject().getName());
				p.append(files[0].getParent().getProjectRelativePath());
				defaultResource = "${workspace_loc:/"+p.toString()+"}";
			}
			else
			{// outside workspace
				IPath p = path.removeLastSegments(1);
				defaultResource = p.toOSString();
			}
			defaultOutputFileName = path.lastSegment();
		}
		catch (CoreException e)
		{
			// do nothing			
		}
	}
}
