/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
package org.eclipse.compare.internal.patch;

import java.io.*;
import java.util.*;

import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;

import org.eclipse.jface.dialogs.*;
import org.eclipse.jface.viewers.*;
import org.eclipse.jface.wizard.*;

import org.eclipse.ui.help.*;
import org.eclipse.ui.model.*;

import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;

import org.eclipse.compare.internal.Utilities;


/* package */ class InputPatchPage extends WizardPage {

	// constants
	protected static final int SIZING_TEXT_FIELD_WIDTH= 250;
	protected static final int COMBO_HISTORY_LENGTH= 5;
	
	private final static int SIZING_SELECTION_WIDGET_WIDTH= 400;
	private final static int SIZING_SELECTION_WIDGET_HEIGHT= 150;

	// dialog store id constants
	private final static String PAGE_NAME= "PatchWizardPage1"; //$NON-NLS-1$
	private final static String STORE_PATCH_FILE_ID= PAGE_NAME + ".PATCH_FILE";	//$NON-NLS-1$
	private final static String STORE_PATCH_FILES_ID= PAGE_NAME + ".PATCH_FILES";	//$NON-NLS-1$
	private final static String STORE_USE_CLIPBOARD_ID= PAGE_NAME + ".USE_CLIPBOARD";	//$NON-NLS-1$

	// help IDs
	private final static String PATCH_HELP_CONTEXT_ID= "PatchWizardHelpId";	//$NON-NLS-1$
	
	private boolean fShowError= false;
	
	// SWT widgets
	private Button fUseClipboardButton;
	private Combo fPatchFileNameField;
	private Button fPatchFileBrowseButton;
	private Button fUsePatchFileButton;
	private Group fPatchFileGroup;
	private CheckboxTreeViewer fPatchTargets;
	private PatchWizard fPatchWizard;


	InputPatchPage(PatchWizard pw) {
		super("InputPatchPage", PatchMessages.getString("InputPatchPage.title"), null); //$NON-NLS-1$ //$NON-NLS-2$
		fPatchWizard= pw;
		setMessage(PatchMessages.getString("InputPatchPage.message")); //$NON-NLS-1$
	}
	
	/**
	 * 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 (getUseClipboard())
			return PatchMessages.getString("InputPatchPage.Clipboard"); //$NON-NLS-1$
		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);
		
		Label l= new Label(composite, SWT.NONE);	// a spacer
		l.setText(PatchMessages.getString("InputPatchPage.SelectInput")); //$NON-NLS-1$
		buildInputGroup(composite);
		
		new Label(composite, SWT.NONE);	// a spacer		
		
		buildPatchFileGroup(composite);		
			
		restoreWidgetValues();

		updateWidgetEnablements();
		//updatePageCompletion();
		
		WorkbenchHelp.setHelp(composite, PATCH_HELP_CONTEXT_ID);
	}
	
	/* (non-JavaDoc)
	 * Method declared in IWizardPage.
	 */
	public IWizardPage getNextPage() {
		if (true) {
			
			Patcher patcher= ((PatchWizard) getWizard()).getPatcher();
			
			// Create a reader for the input
			Reader reader= null;
			if (getUseClipboard()) {
				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);
				}
			} else {
				String patchFilePath= getPatchFilePath();
				if (patchFilePath != null) {
					try {
						reader= new FileReader(patchFilePath);
					} catch (FileNotFoundException ex) {
						MessageDialog.openError(null,
							PatchMessages.getString("InputPatchPage.PatchErrorDialog.title"),	//$NON-NLS-1$
							PatchMessages.getString("InputPatchPage.PatchFileNotFound.message")); //$NON-NLS-1$
					}
				}
			}
			
			// parse the input
			if (reader != null) {
				try {
					patcher.parse(new BufferedReader(reader));
				} catch (IOException ex) {
					MessageDialog.openError(null,
						PatchMessages.getString("InputPatchPage.PatchErrorDialog.title"), //$NON-NLS-1$ 
						PatchMessages.getString("InputPatchPage.ParseError.message")); //$NON-NLS-1$
				}
				
				try {
					reader.close();
				} catch (IOException x) {
				}
			}
			
			Diff[] diffs= patcher.getDiffs();
			if (diffs == null || diffs.length == 0) {
				String source= getUseClipboard() ? "Clipboard"	//$NON-NLS-1$
												   : "File";	//$NON-NLS-1$
				MessageDialog.openError(null,
					PatchMessages.getString("InputPatchPage.PatchErrorDialog.title"),	//$NON-NLS-1$
					PatchMessages.getString("InputPatchPage.NoDiffsFound_"+source+".message")); //$NON-NLS-1$ //$NON-NLS-2$
				return this;
			}
			
			// guess prefix count
			int guess= guessPrefix(diffs);
			patcher.setStripPrefixSegments(guess);
		}
		return super.getNextPage();
	}
		
	private int guessPrefix(Diff[] diffs) {
		/*
		ArrayList list= new ArrayList();
		IResource target= fPatchWizard.getTarget();
		if (target instanceof IFile) {
			list.add(target.getFullPath());
		} else if (target instanceof IContainer) {
			addLeaf(list, (IContainer) target);
		}
		
		// guess prefix count
		for (int i= 0; i < diffs.length; i++) {
			IPath p= diffs[i].fOldPath;
			if (p != null) {
				int matches= match(p, list);
				if (matches > 0) {
					return p.segmentCount() - matches;
				}
			}
		}
		*/
		return 0;
	}
	
	private int match(IPath path, ArrayList list) {
		Iterator iter= list.iterator();
		while (iter.hasNext()) {
			IPath filePath= (IPath) iter.next();
			int matches= matchTrailingSegments(path, filePath);
			if (matches > 0)
				return matches;
		}
		return 0;
	}
	
	private int matchTrailingSegments(IPath p1, IPath p2) {
		int matches= 0;
		int i1= p1.segmentCount()-1;
		int i2= p2.segmentCount()-1;
		for (; i1 >= 0 && i2 >= 0; i1--, i2--) {
			String s1= p1.segment(i1);
			String s2= p2.segment(i2);
			if (!s1.equals(s2))
				break;
			matches++;
		}
		return matches;
	}
	
	private void addLeaf(ArrayList list, IContainer c) {
		IResource[] rs= null;
		try {
			rs= c.members();
		} catch(CoreException ex) {
		}
		if (rs != null) {
			for (int i= 0; i < rs.length; i++) {
				IResource r= rs[i];
				if (r instanceof IFile)
					list.add(r.getFullPath());
				else if (r instanceof IContainer)
					addLeaf(list, (IContainer) r);
			}
		}
	}

	/* (non-JavaDoc)
	 * Method declared in IWizardPage.
	 */
	public boolean canFlipToNextPage() {
		if (true) {
			// 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();
		} else {
			return super.canFlipToNextPage();
		}
	}
	
	private void setEnablePatchFile(boolean enable) {
		fPatchFileNameField.setEnabled(enable);
		fPatchFileBrowseButton.setEnabled(enable);
	}

	/**
	 *	Create the group for selecting the patch file
	 */
	private void buildPatchFileGroup(Composite parent) {
		
		fPatchFileGroup= new Group(parent, SWT.NONE);
		fPatchFileGroup.setText(PatchMessages.getString("InputPatchPage.SelectPatch.title")); //$NON-NLS-1$
		GridLayout layout= new GridLayout();
		layout.numColumns= 3;
		fPatchFileGroup.setLayout(layout);
		fPatchFileGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		
		// 1st row
		fUsePatchFileButton= new Button(fPatchFileGroup, SWT.RADIO);
		fUsePatchFileButton.setText(PatchMessages.getString("InputPatchPage.FileButton.text")); //$NON-NLS-1$
		
		fPatchFileNameField= new Combo(fPatchFileGroup, SWT.BORDER);
		GridData gd= new GridData(GridData.FILL_HORIZONTAL);
		//gd.horizontalIndent= 8;
		gd.widthHint= SIZING_TEXT_FIELD_WIDTH;
		fPatchFileNameField.setLayoutData(gd);
		
		fPatchFileBrowseButton= new Button(fPatchFileGroup, SWT.PUSH);
		fPatchFileBrowseButton.setText(PatchMessages.getString("InputPatchPage.ChooseFileButton.text")); //$NON-NLS-1$
		fPatchFileBrowseButton.setLayoutData(new GridData());
		
		// 2nd row
		fUseClipboardButton= new Button(fPatchFileGroup, SWT.RADIO);
		fUseClipboardButton.setText(PatchMessages.getString("InputPatchPage.UseClipboardButton.text")); //$NON-NLS-1$
		gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
		gd.horizontalSpan= 2;
		fUseClipboardButton.setLayoutData(gd);


		// Add listeners
		fUsePatchFileButton.addSelectionListener(
			new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					fShowError= true;
					setEnablePatchFile(!getUseClipboard());
					updateWidgetEnablements();
				}
			}
		);
		fPatchFileNameField.addSelectionListener(
			new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					setSourceName(fPatchFileNameField.getText());
					updateWidgetEnablements();
				}
			}
		);
		fPatchFileNameField.addModifyListener(
			new ModifyListener() {
				public void modifyText(ModifyEvent e) {
					fShowError= true;
					updateWidgetEnablements();
				}
			}
		);
		fPatchFileBrowseButton.addSelectionListener(
			new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					handlePatchFileBrowseButtonPressed();
					updateWidgetEnablements();
				}
			}
		);
		
		//fPatchFileNameField.setFocus();
	}

	private void buildInputGroup(Composite parent) {
		
		PatchWizard pw= (PatchWizard) getWizard();
		IResource target= pw.getTarget();
		IWorkspace workspace= target.getWorkspace();
		IWorkspaceRoot root= workspace.getRoot();
		
		Tree tree= new Tree(parent, SWT.BORDER);
		GridData gd= new GridData(GridData.FILL_HORIZONTAL);
		gd.heightHint= 200;
		tree.setLayoutData(gd);
		
		fPatchTargets= new CheckboxTreeViewer(tree);
		fPatchTargets.setLabelProvider(new WorkbenchLabelProvider());
		fPatchTargets.setContentProvider(new WorkbenchContentProvider());
		fPatchTargets.setSorter(new WorkbenchViewerSorter());
		fPatchTargets.setInput(root);
		if (target != null) {
			fPatchTargets.expandToLevel(target, 0);
			fPatchTargets.setSelection(new StructuredSelection(target));
		}
		
		// register listeners
		fPatchTargets.addSelectionChangedListener(
			new ISelectionChangedListener() {
				public void selectionChanged(SelectionChangedEvent event) {
					fPatchWizard.setTargets(PatchWizard.getResource(event.getSelection()));
					updateWidgetEnablements();
				}
			}
		);
		//fPatchFileNameField.setFocus();
	}
	
	/**
	 * Returns a content provider for <code>IResource</code>s that returns 
	 * only children of the given resource type.
	 */
	private ITreeContentProvider getResourceProvider(final int resourceType) {
		return new WorkbenchContentProvider() {
			public Object[] getChildren(Object o) {
				if (o instanceof IContainer) {
					try {
						ArrayList results= new ArrayList();
						IResource[] members= ((IContainer)o).members();
						for (int i= 0; i < members.length; i++)
							// filter out the desired resource types
							if ((members[i].getType() & resourceType) != 0)
								results.add(members[i]);
						return results.toArray();
					} catch (CoreException e) {
					}
				}
				// just return an empty set of children
				return new Object[0];
			}
		};
	}
	
	/**
	 * Updates the enable state of this page's controls.
	 */
	private void updateWidgetEnablements() {
		
		String error= null;

		ISelection selection= fPatchTargets.getSelection();
		boolean anySelected= selection != null && !selection.isEmpty();
		if (!anySelected)
			error= PatchMessages.getString("InputPatchPage.NothingSelected.message"); //$NON-NLS-1$

		boolean gotPatch= false;
		if (getUseClipboard()) {
			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.getString("InputPatchPage.ClipboardIsEmpty.message"); //$NON-NLS-1$
				} else
					error= PatchMessages.getString("InputPatchPage.NoTextInClipboard.message");					 //$NON-NLS-1$
			} else
				error= PatchMessages.getString("InputPatchPage.CouldNotReadClipboard.message");					 //$NON-NLS-1$
		} else {
			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.getString("InputPatchPage.CannotLocatePatch.message") + path; //$NON-NLS-1$
			} else {
				error= PatchMessages.getString("InputPatchPage.NoFileName.message"); //$NON-NLS-1$
			}
		}
		
		setPageComplete(anySelected && gotPatch);
		if (fShowError)
			setErrorMessage(error);
	}
	
	protected void handlePatchFileBrowseButtonPressed() {
		FileDialog dialog= new FileDialog(getShell(), SWT.NONE);
		dialog.setText(PatchMessages.getString("InputPatchPage.SelectPatchFileDialog.title"));		 //$NON-NLS-1$
		dialog.setFilterPath(getPatchFilePath());
		String res= dialog.open();
		if (res == null)
			return;
		
		String 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() {
		
		boolean useClipboard= false;
		
		IDialogSettings settings= getDialogSettings();
		if (settings != null) {
			
			useClipboard= settings.getBoolean(STORE_USE_CLIPBOARD_ID);

			// 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 'Use Clipboard' radio buttons
		setUseClipboard(useClipboard);
	}
	
	/**
	 * 	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_USE_CLIPBOARD_ID, getUseClipboard());
			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);
		}
	}
	
	// static helpers
		
	private void setUseClipboard(boolean useClipboard) {
		if (useClipboard)
			fUseClipboardButton.setSelection(true);
		else
			fUsePatchFileButton.setSelection(true);
		setEnablePatchFile(!useClipboard);
	}
	
	private boolean getUseClipboard() {
		if (fUseClipboardButton != null)
			return fUseClipboardButton.getSelection();
		return false;
	}

	private String getPatchFilePath() {
		if (fPatchFileNameField != null)
			return fPatchFileNameField.getText();
		return ""; //$NON-NLS-1$
	} 

	/**
	 * Creates a new label with a bold font.
	 *
	 * @param parent the parent control
	 * @param text the label text
	 * @return the new label control
	 */
	private static Label buildPlainLabel(Composite parent, String text) {
		Label label= new Label(parent, SWT.NONE);
		label.setText(text);
		GridData data= new GridData();
		data.verticalAlignment= GridData.FILL;
		data.horizontalAlignment= GridData.FILL;
		label.setLayoutData(data);
		return label;
	}

	/**
	 * 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()]);
	}
}

