/*******************************************************************************
 * Copyright (c) 2000, 2017 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * 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 java.util.ArrayList;
import java.util.Arrays;

import org.eclipse.compare.internal.ICompareContextIds;
import org.eclipse.compare.internal.Utilities;
import org.eclipse.compare.patch.IFilePatch2;
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.core.runtime.IPath;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
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.ISelection;
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.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
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.ui.PlatformUI;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.eclipse.ui.views.navigator.ResourceComparator;

import com.ibm.icu.text.MessageFormat;

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$

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

	@Override
	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);

		if(PlatformUI.isWorkbenchRunning()) {
			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
	 */
	@Override
	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 | InvocationTargetException | OperationCanceledException | 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) {
					if (patchFile.getLocation() == null) {
						MessageDialog.openError(null, PatchMessages.InputPatchPage_PatchErrorDialog_title, PatchMessages.InputPatchPage_PatchFileNotFound_message);
					} else {
						try {
							reader = new FileReader(patchFile.getLocation().toFile());
						} catch (FileNotFoundException ex) {
							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
				}
			}
		}
	}

	@Override
	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() {
			@Override
			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() {
			@Override
			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() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				updateWidgetEnablements();
			}
		});
		fPatchFileNameField.addModifyListener(e -> {
			clearErrorMessage();
			fShowError= true;
			fPatchRead = false;
			updateWidgetEnablements();
		});
		fPatchFileBrowseButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				clearErrorMessage();
				fShowError= true;
				handlePatchFileBrowseButtonPressed();
				updateWidgetEnablements();
			}
		});
		fUseURLButton.addSelectionListener(new SelectionAdapter() {
			@Override
			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(e -> {
			clearErrorMessage();
			fShowError = true;
			fPatchRead = false;
			updateWidgetEnablements();
		});
		fUseWorkspaceButton.addSelectionListener(new SelectionAdapter() {
			@Override
			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(event -> {
			clearErrorMessage();
			updateWidgetEnablements();
		});

		fTreeViewer.addDoubleClickListener(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);
		GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
		layoutData.heightHint = 300;
		fTreeViewer.getTree().setLayoutData(layoutData);

		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(File.separatorChar);
			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 (String sourceName : sourceNames) {
					if (sourceName != null && sourceName.length() > 0) {
						fPatchFileNameField.add(sourceName);
					}
				}

			// 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 (String sourceURL : sourceURLs) {
					if (sourceURL != null && sourceURL.length() > 0) {
						fPatchURLField.add(sourceURL);
					}
				}

			// 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 && patchTarget.getLocation() != null) {
			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
				}
			} 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) {
		ArrayList<String> l= new ArrayList<>(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 l.toArray(new String[l.size()]);
	}

	public boolean isPatchRead() {
		return fPatchRead;
	}
}

