/*******************************************************************************
 * Copyright (c) 2000, 2012 IBM Corporation and others.
 * 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:
 *     IBM Corporation - initial API and implementation
 *     Sebastian Davids <sdavids@gmx.de> - layout tweaks
 *     Matt McCutchen <hashproduct+eclipse@gmail.com> - Bug 180358 [Apply Patch] Cursor jumps to beginning of filename field on keystroke
 *******************************************************************************/
package org.eclipse.compare.internal.patch;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;

import com.ibm.icu.text.MessageFormat;

import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
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.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.WizardPage;

import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.eclipse.ui.views.navigator.ResourceComparator;

import org.eclipse.compare.internal.ICompareContextIds;
import org.eclipse.compare.internal.Utilities;
import org.eclipse.compare.patch.IFilePatch2;

public class InputPatchPage extends WizardPage {

	// constants
	protected static final int SIZING_TEXT_FIELD_WIDTH= 250;
	protected static final int COMBO_HISTORY_LENGTH= 5;

	// dialog store id constants
	private final static String PAGE_NAME= "PatchWizardPage1"; //$NON-NLS-1$
	private final static String STORE_PATCH_FILES_ID= PAGE_NAME+".PATCH_FILES"; //$NON-NLS-1$
	private final static String STORE_PATCH_URLS_ID= PAGE_NAME+".PATCH_URLS"; //$NON-NLS-1$
	private final static String STORE_INPUT_METHOD_ID= PAGE_NAME+".INPUT_METHOD"; //$NON-NLS-1$
	private final static String STORE_WORKSPACE_PATH_ID= PAGE_NAME+".WORKSPACE_PATH"; //$NON-NLS-1$

	//patch input constants
	protected final static int CLIPBOARD= 1;
	protected final static int FILE= 2;
	protected final static int WORKSPACE= 3;
	protected final static int URL= 4;

	protected final static String INPUTPATCHPAGE_NAME= "InputPatchPage"; //$NON-NLS-1$

	static final char SEPARATOR= System.getProperty("file.separator").charAt(0); //$NON-NLS-1$

	private boolean fShowError= false;
	private String fPatchSource;
	private boolean fPatchRead= false;
	private PatchWizard fPatchWizard;
	private ActivationListener fActivationListener= new ActivationListener();

	// SWT widgets
	private Button fUseClipboardButton;
	private Combo fPatchFileNameField;
	private Button fPatchFileBrowseButton;
	private Button fUsePatchFileButton;
	private Button fUseWorkspaceButton;
	private Button fUseURLButton;
	private Combo fPatchURLField;
	private Label fWorkspaceSelectLabel;
	private TreeViewer fTreeViewer;

	class ActivationListener extends ShellAdapter {
		public void shellActivated(ShellEvent e) {
			// allow error messages if the selected input actually has something selected in it
			fShowError=true;
			switch(getInputMethod()) {
			case FILE:
				fShowError= (fPatchFileNameField.getText() != "");  //$NON-NLS-1$
				break;
			case URL:
				fShowError = (fPatchURLField.getText() != ""); //$NON-NLS-1$
				break;
			case WORKSPACE:
				fShowError= (!fTreeViewer.getSelection().isEmpty());
				break;
			}
			updateWidgetEnablements();
		}
	}

	public InputPatchPage(PatchWizard pw) {
		super(INPUTPATCHPAGE_NAME, PatchMessages.InputPatchPage_title, null);
		fPatchWizard= pw;
		setMessage(PatchMessages.InputPatchPage_message);
	}

	/*
	 * Get a path from the supplied text widget.
	 * @return org.eclipse.core.runtime.IPath
	 */
	protected IPath getPathFromText(Text textField) {
		return (new Path(textField.getText())).makeAbsolute();
	}

	/* package */ String getPatchName() {
		if (getInputMethod() == CLIPBOARD)
			return PatchMessages.InputPatchPage_Clipboard;
		return getPatchFilePath();
	}

	public void createControl(Composite parent) {

		Composite composite= new Composite(parent, SWT.NULL);
		composite.setLayout(new GridLayout());
		composite.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL | GridData.HORIZONTAL_ALIGN_FILL));
		setControl(composite);

		initializeDialogUnits(parent);

		buildPatchFileGroup(composite);

		// by default, whatever was used last was selected or
		// default to File if nothing has been selected
		restoreWidgetValues();

		// see if there are any better options presently selected (i.e workspace
		// or clipboard or URL from clipboard)
		adjustToCurrentTarget();

		// No error for dialog opening
		fShowError= false;
		clearErrorMessage();
		updateWidgetEnablements();

		Shell shell= getShell();
		shell.addShellListener(fActivationListener);

		Dialog.applyDialogFont(composite);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, ICompareContextIds.PATCH_INPUT_WIZARD_PAGE);
	}

	/**
	 * Returns the next page depending on what type of patch is being applied:
	 * 	 i) If the patch is a Workspace patch then it will proceed right to the PreviewPatchPage
	 *  ii) If the patch is a single project patch then it will proceed to the PatchTargetPage, which
	 *      allows the user to specify where to root the patch
	 * @return PreviewPatchPage if multi-project patch, PatchTargetPage if single project patch
	 */
	public IWizardPage getNextPage() {
		if (!checkPageComplete())
			return this;

		WorkspacePatcher patcher= ((PatchWizard) getWizard()).getPatcher();

		// guess prefix count
		int guess= 0; // guessPrefix(diffs);
		patcher.setStripPrefixSegments(guess);

		// If this is a workspace patch we don't need to set a target as the targets will be figured out from
		// all of the projects that make up the patch and continue on to final preview page
		if (patcher.isWorkspacePatch()) {
			// skip 'Patch Target' page
			IWizardPage page = super.getNextPage();
			if (page.getName().equals(PatchTargetPage.PATCHTARGETPAGE_NAME))
				return page.getNextPage();
		}

		// If this is a git patch set the workspace root as the target and skip the target selection page
		if (patcher.isGitPatch()) {
			// skip 'Patch Target' page
			IWizardPage page = super.getNextPage();
			if (page.getName().equals(PatchTargetPage.PATCHTARGETPAGE_NAME)) {
				// set the workspace root as the target
				patcher.setTarget(ResourcesPlugin.getWorkspace().getRoot());
				return page.getNextPage();
			}
		}

		// else go on to target selection page
		return super.getNextPage();
	}

	boolean checkPageComplete() {
		WorkspacePatcher patcher= ((PatchWizard)getWizard()).getPatcher();

		// Read in the patch
		readInPatch();

		IFilePatch2[] diffs= patcher.getDiffs();
		if (diffs == null || diffs.length == 0) {
			String format= PatchMessages.InputPatchPage_NoDiffsFound_format;
			String message= MessageFormat.format(format, fPatchSource);
			MessageDialog.openInformation(null, PatchMessages.InputPatchPage_PatchErrorDialog_title, message);
			return false;
		}
		return true;
	}

	/*
	 * Reads in the patch contents
	 */
	public void readInPatch(){
		if (fPatchRead)
			return;

		WorkspacePatcher patcher= ((PatchWizard) getWizard()).getPatcher();
		// Create a reader for the input
		Reader reader= null;
		try {
			int inputMethod= getInputMethod();
			if (inputMethod == CLIPBOARD) {
				Control c= getControl();
				if (c != null) {
					Clipboard clipboard= new Clipboard(c.getDisplay());
					Object o= clipboard.getContents(TextTransfer.getInstance());
					clipboard.dispose();
					if (o instanceof String)
						reader= new StringReader((String)o);
				}
				fPatchSource= PatchMessages.InputPatchPage_Clipboard_title;
			} else if (inputMethod==FILE) {
				String patchFilePath= getPatchFilePath();
				if (patchFilePath != null) {
					try {
						reader= new FileReader(patchFilePath);
					} catch (FileNotFoundException ex) {
						MessageDialog.openError(null,
							PatchMessages.InputPatchPage_PatchErrorDialog_title,
							PatchMessages.InputPatchPage_PatchFileNotFound_message);
					}
				}
				fPatchSource= PatchMessages.InputPatchPage_PatchFile_title;
			} else if (inputMethod==URL) {
				String patchFileURL = fPatchURLField.getText();
				if (patchFileURL != null) {
					try {
						String contents = Utilities.getURLContents(new URL(
								patchFileURL), getContainer());
						if (contents != null)
							reader = new StringReader(contents);
					} catch (MalformedURLException e) {
						// ignore as we tested it with modify listener on combo
					} catch (InvocationTargetException e) { // ignore
					} catch (OperationCanceledException e) { // ignore
					} catch (InterruptedException e) { // ignore
					}
				}
				fPatchSource= PatchMessages.InputPatchPage_URL_title;
			} else if (inputMethod==WORKSPACE) {
				// Get the selected patch file (tree will only allow for one selection)
				IResource[] resources= Utilities.getResources(fTreeViewer.getSelection());
				IResource patchFile= resources[0];
				if (patchFile != null) {
					try {
						reader= new FileReader(patchFile.getLocation().toFile());
					} catch (FileNotFoundException ex) {
						MessageDialog.openError(null, PatchMessages.InputPatchPage_PatchErrorDialog_title, PatchMessages.InputPatchPage_PatchFileNotFound_message);
					} catch (NullPointerException nex) {
						//in case the path doesn't exist (eg. getLocation() returned null)
						MessageDialog.openError(null, PatchMessages.InputPatchPage_PatchErrorDialog_title, PatchMessages.InputPatchPage_PatchFileNotFound_message);
					}
				}
				fPatchSource= PatchMessages.InputPatchPage_WorkspacePatch_title;
			}

			// parse the input
			if (reader != null) {
				try {
					patcher.parse(new BufferedReader(reader));
					//report back to the patch wizard that the patch has been read in
					fPatchWizard.patchReadIn();
					fPatchRead=true;
				} catch (Exception ex) {
					// Ignore. User will be informed of error since patcher contains no diffs
					setPageComplete(false);
				}
			}
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException x) {
					// silently ignored
				}
			}
		}
	}

	/* (non-JavaDoc)
	 * Method declared in IWizardPage.
	 */
	public boolean canFlipToNextPage() {
		// we can't call getNextPage to determine if flipping is allowed since computing
		// the next page is quite expensive. So we say yes if the page is complete.
		return isPageComplete();
	}

	private void setEnablePatchFile(boolean enable) {
		fPatchFileNameField.setEnabled(enable);
		fPatchFileBrowseButton.setEnabled(enable);
	}

	private void setEnableWorkspacePatch(boolean enable) {
		fWorkspaceSelectLabel.setEnabled(enable);
		fTreeViewer.getTree().setEnabled(enable);
	}

	private void setEnableURLPatch(boolean enable) {
		fPatchURLField.setEnabled(enable);
	}

	/*
	 *	Create the group for selecting the patch file
	 */
	private void buildPatchFileGroup(Composite parent) {

		final Composite composite= new Composite(parent, SWT.NULL);
		GridLayout gridLayout= new GridLayout();
		gridLayout.numColumns= 3;
		composite.setLayout(gridLayout);
		composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

		// 1st row
		GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
		gd.horizontalSpan= 3;
		fUseClipboardButton= new Button(composite, SWT.RADIO);
		fUseClipboardButton.setText(PatchMessages.InputPatchPage_UseClipboardButton_text);
		fUseClipboardButton.setLayoutData(gd);

		// 2nd row
		fUsePatchFileButton= new Button(composite, SWT.RADIO);
		fUsePatchFileButton.setText(PatchMessages.InputPatchPage_FileButton_text);

		fPatchFileNameField= new Combo(composite, SWT.BORDER);
		gd= new GridData(GridData.FILL_HORIZONTAL);
		gd.widthHint= SIZING_TEXT_FIELD_WIDTH;
		fPatchFileNameField.setLayoutData(gd);

		fPatchFileBrowseButton= new Button(composite, SWT.PUSH);
		fPatchFileBrowseButton.setText(PatchMessages.InputPatchPage_ChooseFileButton_text);
		GridData data= new GridData(GridData.HORIZONTAL_ALIGN_FILL);
		int widthHint= convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
		Point minSize= fPatchFileBrowseButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
		data.widthHint= Math.max(widthHint, minSize.x);
		fPatchFileBrowseButton.setLayoutData(data);

		//3rd row
		fUseURLButton = new Button(composite, SWT.RADIO);
		fUseURLButton.setText(PatchMessages.InputPatchPage_URLButton_text);

		fPatchURLField = new Combo(composite, SWT.BORDER);
		gd = new GridData(GridData.FILL_HORIZONTAL);
		gd.horizontalSpan = 2;
		fPatchURLField.setLayoutData(gd);

		//4th row
		fUseWorkspaceButton= new Button(composite, SWT.RADIO);
		fUseWorkspaceButton.setText(PatchMessages.InputPatchPage_UseWorkspaceButton_text);
		gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
		fUseWorkspaceButton.setLayoutData(gd);

		addWorkspaceControls(parent);

		// Add listeners
		fUseClipboardButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				if (!fUseClipboardButton.getSelection())
					return;

				clearErrorMessage();
				fShowError= true;
				int state= getInputMethod();
				setEnablePatchFile(state == FILE);
				setEnableURLPatch(state == URL);
				setEnableWorkspacePatch(state == WORKSPACE);
				updateWidgetEnablements();
				fPatchRead = false;
			}
		});

		fUsePatchFileButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				if (!fUsePatchFileButton.getSelection())
					return;
				//If there is anything typed in at all
				clearErrorMessage();
				fShowError= (fPatchFileNameField.getText() != ""); //$NON-NLS-1$
				int state= getInputMethod();
				setEnablePatchFile(state == FILE);
				setEnableURLPatch(state == URL);
				setEnableWorkspacePatch(state == WORKSPACE);
				updateWidgetEnablements();
				fPatchRead = false;
			}
		});
		fPatchFileNameField.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				updateWidgetEnablements();
			}
		});
		fPatchFileNameField.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				clearErrorMessage();
				fShowError= true;
				fPatchRead = false;
				updateWidgetEnablements();
			}
		});
		fPatchFileBrowseButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				clearErrorMessage();
				fShowError= true;
				handlePatchFileBrowseButtonPressed();
				updateWidgetEnablements();
			}
		});
		fUseURLButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				clearErrorMessage();
				fShowError= (fPatchURLField.getText() != ""); //$NON-NLS-1$
				int state= getInputMethod();
				setEnablePatchFile(state == FILE);
				setEnableURLPatch(state == URL);
				setEnableWorkspacePatch(state == WORKSPACE);
				updateWidgetEnablements();
			}
		});
		fPatchURLField.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				clearErrorMessage();
				fShowError = true;
				fPatchRead = false;
				updateWidgetEnablements();
			}
		});
		fUseWorkspaceButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				if (!fUseWorkspaceButton.getSelection())
					return;
				clearErrorMessage();
				// If there is anything typed in at all
				fShowError= (!fTreeViewer.getSelection().isEmpty());
				int state= getInputMethod();
				setEnablePatchFile(state == FILE);
				setEnableURLPatch(state == URL);
				setEnableWorkspacePatch(state == WORKSPACE);
				updateWidgetEnablements();
				fPatchRead = false;
			}
		});

		fTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
			public void selectionChanged(SelectionChangedEvent event) {
				clearErrorMessage();
				updateWidgetEnablements();
			}
		});

		fTreeViewer.addDoubleClickListener(new IDoubleClickListener() {
			public void doubleClick(DoubleClickEvent event) {
				ISelection selection= event.getSelection();
				if (selection instanceof TreeSelection) {
					TreeSelection treeSel= (TreeSelection) selection;
					Object res= treeSel.getFirstElement();
					if (res != null) {
						if (res instanceof IProject || res instanceof IFolder) {
							if (fTreeViewer.getExpandedState(res))
								fTreeViewer.collapseToLevel(res, 1);
							else
								fTreeViewer.expandToLevel(res, 1);
						} else if (res instanceof IFile)
							fPatchWizard.showPage(getNextPage());
					}
				}
			}
		});
	}

	private void addWorkspaceControls(Composite composite) {

		Composite newComp= new Composite(composite, SWT.NONE);
		GridLayout layout= new GridLayout(1, false);
		layout.marginLeft= 16; // align w/ lable of check button
		newComp.setLayout(layout);
		newComp.setLayoutData(new GridData(GridData.FILL_BOTH));

		fWorkspaceSelectLabel= new Label(newComp, SWT.LEFT);
		fWorkspaceSelectLabel.setText(PatchMessages.InputPatchPage_WorkspaceSelectPatch_text);

		fTreeViewer= new TreeViewer(newComp, SWT.BORDER);
		fTreeViewer.getTree().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

		fTreeViewer.setLabelProvider(new WorkbenchLabelProvider());
		fTreeViewer.setContentProvider(new WorkbenchContentProvider());
		fTreeViewer.setComparator(new ResourceComparator(ResourceComparator.NAME));
		fTreeViewer.setInput(ResourcesPlugin.getWorkspace().getRoot());
	}


	/**
	 * Updates the enable state of this page's controls.
	 */
	private void updateWidgetEnablements() {

		String error= null;

		boolean gotPatch= false;
		int inputMethod= getInputMethod();
		if (inputMethod==CLIPBOARD) {
			Control c= getControl();
			if (c != null) {
				Clipboard clipboard= new Clipboard(c.getDisplay());
				Object o= clipboard.getContents(TextTransfer.getInstance());
				clipboard.dispose();
				if (o instanceof String) {
					String s= ((String) o).trim();
					if (s.length() > 0)
						gotPatch= true;
					else
						error= PatchMessages.InputPatchPage_ClipboardIsEmpty_message;
				} else
					error= PatchMessages.InputPatchPage_NoTextInClipboard_message;
			} else
				error= PatchMessages.InputPatchPage_CouldNotReadClipboard_message;
		} else if (inputMethod==FILE) {
			String path= fPatchFileNameField.getText();
			if (path != null && path.length() > 0) {
				File file= new File(path);
				gotPatch= file.exists() && file.isFile() && file.length() > 0;
				if (!gotPatch)
					error= PatchMessages.InputPatchPage_CannotLocatePatch_message + path;
			} else {
				error= PatchMessages.InputPatchPage_NoFileName_message;
			}
		} else if (inputMethod == URL) {
			String urlText = fPatchURLField.getText();
			if(urlText != null) {
				try {
					new URL(urlText);
					// Checking the URL is a bit too heavy for each keystroke.
					// Let's assume it contains a valid patch.
					gotPatch = true;
				} catch (MalformedURLException e) {
					error= PatchMessages.InputPatchPage_MalformedURL;
				}
			} else {
				error= PatchMessages.InputPatchPage_NoURL;
			}
		} else if (inputMethod == WORKSPACE) {
			//Get the selected patch file (tree will only allow for one selection)
			IResource[] resources= Utilities.getResources(fTreeViewer.getSelection());
			if (resources != null && resources.length > 0) {
				IResource patchFile= resources[0];
				if (patchFile != null && patchFile.getType() == IResource.FILE) {
					IPath location = patchFile.getLocation();
					if (location == null) {
						error = PatchMessages.InputPatchPage_PatchFileNotFound_message;
					} else {
						File actualFile= location.toFile();
						gotPatch= actualFile.exists()&&actualFile.isFile()&&actualFile.length() > 0;
						if (!gotPatch)
							error= PatchMessages.InputPatchPage_FileSelectedNotPatch_message;
					}
				}
			} else {
				error= PatchMessages.InputPatchPage_NoFileName_message;
			}
		}

		setPageComplete(gotPatch);

		if (fShowError)
			setErrorMessage(error);
	}

	protected void handlePatchFileBrowseButtonPressed() {
		FileDialog dialog= new FileDialog(getShell(), SWT.NONE);
		dialog.setText(PatchMessages.InputPatchPage_SelectPatchFileDialog_title);
		String patchFilePath= getPatchFilePath();
		if (patchFilePath != null) {
			int lastSegment= patchFilePath.lastIndexOf(SEPARATOR);
			if (lastSegment > 0) {
				patchFilePath= patchFilePath.substring(0, lastSegment);
			}
		}
		dialog.setFilterPath(patchFilePath);
		String res= dialog.open();
		if (res == null)
			return;

		patchFilePath= dialog.getFileName();
		IPath filterPath= new Path(dialog.getFilterPath());
		IPath path= filterPath.append(patchFilePath).makeAbsolute();
		patchFilePath= path.toOSString();
		//fDialogSettings.put(IUIConstants.DIALOGSTORE_LASTEXTJAR, filterPath.toOSString());

		fPatchFileNameField.setText(patchFilePath);
		//setSourceName(patchFilePath);
	}

	/**
	 * Sets the source name of the import to be the supplied path.
	 * Adds the name of the path to the list of items in the
	 * source combo and selects it.
	 *
	 * @param path the path to be added
	 */
	protected void setSourceName(String path) {

		if (path.length() > 0) {

			String[] currentItems= fPatchFileNameField.getItems();
			int selectionIndex= -1;
			for (int i= 0; i < currentItems.length; i++)
				if (currentItems[i].equals(path))
					selectionIndex= i;

			if (selectionIndex < 0) {	// not found in history
				int oldLength= currentItems.length;
				String[] newItems= new String[oldLength + 1];
				System.arraycopy(currentItems, 0, newItems, 0, oldLength);
				newItems[oldLength]= path;
				fPatchFileNameField.setItems(newItems);
				selectionIndex= oldLength;
			}
			fPatchFileNameField.select(selectionIndex);

			//resetSelection();
		}
	}

	/**
	 *	The Finish button was pressed. Try to do the required work now and answer
	 *	a boolean indicating success. If false is returned then the wizard will
	 *	not close.
	 *
	 * @return boolean
	 */
	public boolean finish() {
//		if (!ensureSourceIsValid())
//			return false;

		saveWidgetValues();

//		Iterator resourcesEnum= getSelectedResources().iterator();
//		List fileSystemObjects= new ArrayList();
//		while (resourcesEnum.hasNext()) {
//			fileSystemObjects.add(
//				((FileSystemElement) resourcesEnum.next()).getFileSystemObject());
//		}
//
//		if (fileSystemObjects.size() > 0)
//			return importResources(fileSystemObjects);
//
//		MessageDialog
//			.openInformation(
//				getContainer().getShell(),
//				DataTransferMessages.getString("DataTransfer.information"), //$NON-NLS-1$
//				DataTransferMessages.getString("FileImport.noneSelected")); //$NON-NLS-1$
//
//		return false;

		return true;
	}

	/**
	 *	Use the dialog store to restore widget values to the values that they held
	 *	last time this wizard was used to completion
	 */
	private void restoreWidgetValues() {

		int inputMethod= FILE;

		IDialogSettings settings= getDialogSettings();
		if (settings != null) {

			try {
				inputMethod= settings.getInt(STORE_INPUT_METHOD_ID);
			} catch (NumberFormatException ex) {
				//OK - no value stored in settings; just use CLIPBOARD
			}

			// set filenames history
			String[] sourceNames= settings.getArray(STORE_PATCH_FILES_ID);
			if (sourceNames != null)
				for (int i= 0; i < sourceNames.length; i++)
					if (sourceNames[i] != null && sourceNames[i].length() > 0)
						fPatchFileNameField.add(sourceNames[i]);

			// set patch file path
			String patchFilePath= settings.get(STORE_PATCH_FILES_ID);
			if (patchFilePath != null)
				setSourceName(patchFilePath);

			// set URLs history
			String[] sourceURLs= settings.getArray(STORE_PATCH_URLS_ID);
			if (sourceURLs != null)
				for (int i= 0; i < sourceURLs.length; i++)
					if (sourceURLs[i] != null && sourceURLs[i].length() > 0)
						fPatchURLField.add(sourceURLs[i]);

			// If the previous apply patch was used with a clipboard, we need to check
			// if there is a valid patch on the clipboard. This will be done in adjustToCurrentTarget()
			// so just set it to FILE now and, if there exists a patch on the clipboard, then clipboard
			// will be selected automatically
			if (inputMethod == CLIPBOARD){
				inputMethod= FILE;
				fPatchFileNameField.deselectAll();
			}

			//set the workspace patch selection
			String workspaceSetting= settings.get(STORE_WORKSPACE_PATH_ID);
			if (workspaceSetting != null && workspaceSetting.length() > 0) {
				// See if this resource still exists in the workspace
				try {
					IPath path= new Path(workspaceSetting);
					IFile targetFile= ResourcesPlugin.getWorkspace().getRoot().getFile(path);
					if (fTreeViewer != null && targetFile.exists()){
						fTreeViewer.expandToLevel(targetFile, 0);
						fTreeViewer.setSelection(new StructuredSelection(targetFile));
					}
				} catch (RuntimeException e) {
					// Ignore. The setting was invalid
				}
			} else {
				//check to see if the current input is set to workspace - if it is switch it
				//back to clipboard since there is no corresponding element to go along with
				//the tree viewer
				if (inputMethod == WORKSPACE)
					inputMethod= FILE;
			}
		}

		// set radio buttons state
		setInputButtonState(inputMethod);
	}

	/**
	 * 	Since Finish was pressed, write widget values to the dialog store so that they
	 *	will persist into the next invocation of this wizard page
	 */
	void saveWidgetValues() {
		IDialogSettings settings= getDialogSettings();
		if (settings != null) {

			settings.put(STORE_INPUT_METHOD_ID, getInputMethod());
			settings.put(STORE_PATCH_FILES_ID, getPatchFilePath());

			// update source names history
			String[] sourceNames= settings.getArray(STORE_PATCH_FILES_ID);
			if (sourceNames == null)
				sourceNames= new String[0];

			sourceNames= addToHistory(sourceNames, getPatchFilePath());
			settings.put(STORE_PATCH_FILES_ID, sourceNames);

			// update source URLs history
			String[] sourceURLs= settings.getArray(STORE_PATCH_URLS_ID);
			if (sourceURLs == null)
				sourceURLs= new String[0];

			sourceURLs= addToHistory(sourceURLs, fPatchURLField.getText());
			settings.put(STORE_PATCH_URLS_ID, sourceURLs);

			// save the workspace selection
			settings.put(STORE_WORKSPACE_PATH_ID, getWorkspacePath());

		}
	}

	private String getWorkspacePath() {
		if (fTreeViewer != null){
			IResource[] resources= Utilities.getResources(fTreeViewer.getSelection());
			if (resources.length > 0) {
				IResource patchFile= resources[0];
				return patchFile.getFullPath().toString();
			}

		}
		return ""; //$NON-NLS-1$
	}

	// static helpers

	/**
	 * Checks to see if the file that has been selected for Apply Patch is
	 * actually a patch
	 *
	 * @return true if the file selected to run Apply Patch on in the workspace
	 *         is a patch file or if the clipboard contains a patch or if the
	 *         clipboard contains an URL (we assume it points to a patch )
	 */
	private boolean adjustToCurrentTarget() {
		// readjust selection if there is a patch selected in the workspace or on the clipboard
		// check workspace first
		IResource patchTarget= fPatchWizard.getTarget();
		if (patchTarget instanceof IFile) {
			Reader reader= null;
			try {
				try {
					reader= new FileReader(patchTarget.getLocation().toFile());
					if (isPatchFile(reader)) {
						// set choice to workspace
						setInputButtonState(WORKSPACE);
						if (fTreeViewer != null && patchTarget.exists()) {
							fTreeViewer.expandToLevel(patchTarget, 0);
							fTreeViewer.setSelection(new StructuredSelection(patchTarget));
						}
						return true;
					}
				} catch (FileNotFoundException ex) {
					// silently ignored
				} catch (NullPointerException nex) {
					// silently ignored
				}

			} finally {
				if (reader != null) {
					try {
						reader.close();
					} catch (IOException x) {
						// silently ignored
					}
				}
			}
		}
		// check out clipboard contents
		Reader reader = null;
		Control c = getControl();
		if (c != null) {
			Clipboard clipboard= new Clipboard(c.getDisplay());
			Object o= clipboard.getContents(TextTransfer.getInstance());
			clipboard.dispose();
			try {
				if (o instanceof String) {
					reader= new StringReader((String) o);
					if (isPatchFile(reader)) {
						setInputButtonState(CLIPBOARD);
						return true;
					}
					// maybe it's an URL
					try {
						new URL((String)o);
						setInputButtonState(URL);
						fPatchURLField.setText((String)o);
						return true;
					} catch (MalformedURLException e) {
						// ignore
					}
				}
			} finally {
				if (reader != null) {
					try {
						reader.close();
					} catch (IOException x) {
						// silently ignored
					}
				}
			}
		}
		return false;
	}

	private boolean isPatchFile(Reader reader) {
		WorkspacePatcher patcher= ((PatchWizard) getWizard()).getPatcher();

		try {
			patcher.parse(new BufferedReader(reader));
		} catch (Exception ex) {
			return false;
		}

		IFilePatch2[] diffs= patcher.getDiffs();
		if (diffs == null || diffs.length == 0)
			return false;
		return true;
	}

	/*
	 * Clears the dialog message box
	 */
	private void clearErrorMessage(){
		setErrorMessage(null);
	}

	private void setInputButtonState(int state) {

		switch (state) {
		case CLIPBOARD:
			fUseClipboardButton.setSelection(true);
			fUsePatchFileButton.setSelection(false);
			fUseURLButton.setSelection(false);
			fUseWorkspaceButton.setSelection(false);
			break;

		case FILE:
			fUseClipboardButton.setSelection(false);
			fUsePatchFileButton.setSelection(true);
			fUseURLButton.setSelection(false);
			fUseWorkspaceButton.setSelection(false);
			break;

		case URL:
			fUseClipboardButton.setSelection(false);
			fUsePatchFileButton.setSelection(false);
			fUseURLButton.setSelection(true);
			fUseWorkspaceButton.setSelection(false);
			break;

		case WORKSPACE:
			fUseClipboardButton.setSelection(false);
			fUsePatchFileButton.setSelection(false);
			fUseURLButton.setSelection(false);
			fUseWorkspaceButton.setSelection(true);
			break;
		}

		setEnablePatchFile(state == FILE);
		setEnableWorkspacePatch(state == WORKSPACE);
		setEnableURLPatch(state == URL);
	}

	protected int getInputMethod() {
		if (fUseClipboardButton.getSelection())
			return CLIPBOARD;
		if (fUsePatchFileButton.getSelection())
			return FILE;
		if(fUseURLButton.getSelection())
			return URL;
		return WORKSPACE;
	}

	private String getPatchFilePath() {
		if (fPatchFileNameField != null)
			return fPatchFileNameField.getText();
		return ""; //$NON-NLS-1$
	}

	/*
	 * Adds an entry to a history, while taking care of duplicate history items
	 * and excessively long histories. The assumption is made that all histories
	 * should be of length <code>COMBO_HISTORY_LENGTH</code>.
	 *
	 * @param history the current history
	 * @param newEntry the entry to add to the history
	 */
	protected static String[] addToHistory(String[] history, String newEntry) {
		java.util.ArrayList l= new java.util.ArrayList(java.util.Arrays.asList(history));

		l.remove(newEntry);
		l.add(0,newEntry);

		// since only one new item was added, we can be over the limit
		// by at most one item
		if (l.size() > COMBO_HISTORY_LENGTH)
			l.remove(COMBO_HISTORY_LENGTH);

		return (String[]) l.toArray(new String[l.size()]);
	}

	public boolean isPatchRead() {
		return fPatchRead;
	}
}

