/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
package org.eclipse.compare;

import java.util.HashMap;
import java.util.ResourceBundle;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.HashSet;
import java.util.Calendar;
import java.io.InputStream;
import java.text.*;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Item;
import org.eclipse.swt.widgets.Button;

import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.*;
import org.eclipse.jface.util.Assert;
import org.eclipse.jface.dialogs.*;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFileState;
import org.eclipse.core.runtime.CoreException;

import org.eclipse.compare.internal.*;
import org.eclipse.compare.structuremergeviewer.*;
import org.eclipse.compare.*;

/**
 * A dialog where one input element can be compared against
 * a list of historic variants (editions) of the same input element.
 * The dialog can be used to implement functions like "Compare/Replace with Version" or
 * "Compare/Replace from Local History" on workspace resources.
 * <p>
 * In addition it is possible to specify a subsection of the input element
 * (e.g. a method in a Java source file) by means of a "path".
 * In this case the dialog compares only the subsection (as specified by the path)
 * with the corresponding subsection in the list of editions.
 * Only those editions are shown where the subsection differs from the same subsection in
 * another edition thereby minimizing the number of presented variants.
 * This functionality can be used to implement "Replace from Local History"
 * for the Java language.
 * <p>
 * Subsections of an input element are determined by first finding an
 * <code>IStructureCreator</code> for the input's type.
 * Then the method <code>locate</code> is used to extract the subsection.
 * <p>
 * Each edition (variant in the list of variants) must implement the <code>IModificationDate</code> interface
 * so that the dialog can sort the editions and present them in a tree structure where every
 * node corresponds one day.
 * <p>
 * The functionality is surfaced in a single function <code>selectEdition</code>.
 * <p>
 * Clients may instantiate this class; it is not intended to be subclassed.
 * </p>
 *
 * @see IModificationDate
 * @see ITypedElement
 */
public class EditionSelectionDialog extends ResizableDialog {
		
	/**
	 * An item in an underlying edition.
	 */
	private static class Pair {
		
		private ITypedElement fEdition;
		private ITypedElement fItem;
		private String fContent;
		private IStructureCreator fStructureCreator;
		private boolean fHasError= false;
				
		Pair(IStructureCreator structureCreator, ITypedElement edition, ITypedElement item) {
			fStructureCreator= structureCreator;
			fEdition= edition;
			fItem= item;
		}
		
		Pair(IStructureCreator structureCreator, ITypedElement edition) {
			this(structureCreator, edition, edition);
		}
		
		ITypedElement getEdition() {
			return fEdition;
		}

		ITypedElement getItem() {
			return fItem;
		}
		
		/**
		 * The content is lazily loaded
		 */
		private String getContent() {
			if (fContent == null) {
				if (fStructureCreator != null)
					fContent= fStructureCreator.getContents(fItem, false);
				else {
					if (fItem instanceof IStreamContentAccessor) {
						IStreamContentAccessor sca= (IStreamContentAccessor) fItem;
						try {
							InputStream is= sca.getContents();
							if (is != null)
								fContent= Utilities.readString(is);
						} catch (CoreException ex) {
						}
					}
				}
				if (fContent == null)
					fContent= ""; //$NON-NLS-1$
			}
			return fContent;
		}
		
		/**
		 * Compares content of item.
		 */
		public boolean equals(Object other) {
			if (other != null && other.getClass() == getClass()) {
				if (getContent().equals(((Pair)other).getContent()))
					return true;
			}
			return super.equals(other);
		}
	}
	
	// Configuration options
	private CompareConfiguration fCompareConfiguration;
	/** use a side-by-side compare viewer */
	private boolean fCompare= true;
	/** show target on right hand side */
	private boolean fTargetIsRight= false;
	/** hide entries which have identical content */
	private boolean fHideIdentical= true;
	/** add mode if true, otherwise replace mode */
	private boolean fAddMode= false;
	/** compare mode if true, otherwise replace/add mode */
	private boolean fCompareMode= false;
	/** perform structure compare on editions */
	private boolean fStructureCompare= false;
	
	/**
	 * Maps from members to their corresponding editions.
	 * Has only a single entry if dialog is used in "Replace" (and not "Add") mode.
	 */
	private HashMap fMemberEditions;
	/** The editions of the current selected member */
	private List fCurrentEditions;
	private Thread fThread;
	private Pair fTargetPair;
	/** The selected edition in the edition viewer */
	private ITypedElement fSelectedItem;
	private String fTitleArg;
	private Image fTitleImage;
	
	// SWT controls
	private CompareViewerSwitchingPane fContentPane;
	private Button fCommitButton;
	private Table fMemberTable;
	private CompareViewerPane fMemberPane;
	private Tree fEditionTree;
	private CompareViewerPane fEditionPane;
	private Image fDateImage;
	private Image fTimeImage;
	private CompareViewerSwitchingPane fStructuredComparePane;
	
	/**
	 * Creates a new modal, resizable dialog.
	 * Various titles, icons, and labels are configured from the given resource bundle.
	 * The following resource keys are used:
	 * <pre>
	 *	key         type          description
	 *	title       String        dialog title
	 *	width       Integer       initial width of dialog
	 *	height      Integer       initial height of dialog
	 *	treeTitleFormat   MessageFormat pane title for edition tree; arg 0 is the target
	 *	dateIcon    String        icon for node in edition tree; path relative to plugin
	 *	timeIcon    String        icon for leaf in edition tree; path relative to plugin
	 *	todayFormat MessageFormat format string if date is todays date; arg 0 is date
	 *	yesterdayFormat MessageFormat format string if date is yesterdays date; arg 0 is date
	 *	dayFormat   MessageFormat format string if date is any other date; arg 0 is date
	 *	editionLabel String       label for editions side of compare viewer; arg 0 is the date
	 *	targetLabel  String       label for target side of compare viewer 
	 *  buttonLabel  String       label for OK button; default is IDialogConstants.OK_LABEL
	 * </pre>
	 *
	 * @param parent if not <code>null</code> the new dialog stays on top of this parent shell
	 * @param bundle <code>ResourceBundle</code> to configure the dialog
	 */
	public EditionSelectionDialog(Shell parent, ResourceBundle bundle) {
		super(parent, bundle);
		
		fCompareConfiguration= new CompareConfiguration();
		fCompareConfiguration.setLeftEditable(false);
		fCompareConfiguration.setRightEditable(false);
				
		String iconName= Utilities.getString(fBundle, "dateIcon", "obj16/day_obj.gif"); //$NON-NLS-2$ //$NON-NLS-1$
		ImageDescriptor id= CompareUIPlugin.getImageDescriptor(iconName);
		if (id != null)
			fDateImage= id.createImage();
		iconName= Utilities.getString(fBundle, "timeIcon", "obj16/resource_obj.gif"); //$NON-NLS-1$ //$NON-NLS-2$
		id= CompareUIPlugin.getImageDescriptor(iconName);
		if (id != null)
			fTimeImage= id.createImage();
	}
		
	public void setEditionTitleArgument(String titleArgument) {
		fTitleArg= titleArgument;
	}
	
	public void setEditionTitleImage(Image titleImage) {
		fTitleImage= titleImage;
	}
	
	/**
	 * Select the previous edition (presenting a UI).
	 *
	 * @param target the input object against which the editions are compared; must not be <code>null</code>
	 * @param editions the list of editions (element type: <code>ITypedElement</code>s)
	 * @param path If <code>null</code> dialog shows full input; if non <code>null</code> it extracts a subsection
	 * @return returns the selected edition or <code>null</code> if error occurred.
	 * The returned <code>ITypedElement</code> is one of the original editions
	 * if <code>path</code> was <code>null</code>; otherwise
	 * it is an <code>ITypedElement</code> returned from <code>IStructureCreator.locate(path, item)</code>
	 */
	public ITypedElement selectPreviousEdition(final ITypedElement target, ITypedElement[] inputEditions, Object ppath) {
		Assert.isNotNull(target);
		fTargetPair= new Pair(null, target);
		
		// sort input editions
		final int count= inputEditions.length;
		final IModificationDate[] editions= new IModificationDate[count];
		for (int i= 0; i < count; i++)
			editions[i]= (IModificationDate) inputEditions[i];
		if (count > 1)
			internalSort(editions, 0, count-1);
			
		// find StructureCreator if ppath is not null
		IStructureCreator structureCreator= null;
		if (ppath != null) {
			String type= target.getType();
			IStructureCreatorDescriptor scd= CompareUIPlugin.getStructureCreator(type);
			if (scd != null)
				structureCreator= scd.createStructureCreator();
		}

		if (fAddMode) {
			// does not work in add mode
			return null;
		}
			
		if (structureCreator != null) {
			Pair pair= createPair(structureCreator, ppath, target);
			if (pair != null)
				fTargetPair= pair;
			else
				ppath= null;	// couldn't extract item because of error
		}
					
		// from front (newest) to back (oldest)
		for (int i= 0; i < count; i++) {
				
			ITypedElement edition= (ITypedElement) editions[i];
			Pair pair= null;
			
			if (structureCreator != null && ppath != null) {
				// extract sub element from edition
				pair= createPair(structureCreator, ppath, edition);
			} else {
				pair= new Pair(null, edition);
			}
			
			if (pair != null && pair.fHasError)
				return null;
				
			if (pair != null && !fTargetPair.equals(pair)) {
				return pair.fItem;
			}
		}
		
		// nothing found
		return null;
	}
	
	/**
	 * Presents this modal dialog with the functionality described in the class comment above.
	 *
	 * @param target the input object against which the editions are compared; must not be <code>null</code>
	 * @param editions the list of editions (element type: <code>ITypedElement</code>s)
	 * @param path If <code>null</code> dialog shows full input; if non <code>null</code> it extracts a subsection
	 * @return returns the selected edition or <code>null</code> if dialog was cancelled.
	 * The returned <code>ITypedElement</code> is one of the original editions
	 * if <code>path</code> was <code>null</code>; otherwise
	 * it is an <code>ITypedElement</code> returned from <code>IStructureCreator.locate(path, item)</code>
	 */
	public ITypedElement selectEdition(final ITypedElement target, ITypedElement[] inputEditions, Object ppath) {
		
		Assert.isNotNull(target);
		fTargetPair= new Pair(null, target);
		
		// sort input editions
		final int count= inputEditions.length;
		final IModificationDate[] editions= new IModificationDate[count];
		for (int i= 0; i < count; i++)
			editions[i]= (IModificationDate) inputEditions[i];
		if (count > 1)
			internalSort(editions, 0, count-1);
			
		// find StructureCreator if ppath is not null
		IStructureCreator structureCreator= null;
		if (ppath != null) {
			String type= target.getType();
			IStructureCreatorDescriptor scd= CompareUIPlugin.getStructureCreator(type);
			if (scd != null)
				structureCreator= scd.createStructureCreator();
		}

		if (!fAddMode) {
			// replace mode
			
			if (structureCreator != null) {
				Pair pair= createPair(structureCreator, ppath, target);
				if (pair != null)
					fTargetPair= pair;
				else
					ppath= null;	// couldn't extract item because of error
			}
			
			// set the left and right labels for the compare viewer
			String targetLabel= getTargetLabel(target, fTargetPair.getItem());
			if (fTargetIsRight)
				fCompareConfiguration.setRightLabel(targetLabel);
			else
				fCompareConfiguration.setLeftLabel(targetLabel);
			
			if (structureCreator != null && ppath != null) {	// extract sub element
				
				final IStructureCreator sc= structureCreator;
				final Object path= ppath;
				
				// construct the comparer thread
				// and perform the background extract
				fThread= new Thread() {
					public void run() {
																				
						// from front (newest) to back (oldest)
						for (int i= 0; i < count; i++) {
								
							if (fEditionTree == null || fEditionTree.isDisposed())
								break;
							ITypedElement edition= (ITypedElement) editions[i];
							
							// extract sub element from edition
							Pair pair= createPair(sc, path, edition);
							if (pair != null)
								sendPair(pair);
						}
						sendPair(null);
					}
				};
			} else {
				// create tree widget
				create();
				
				// from front (newest) to back (oldest)
				for (int i= 0; i < count; i++)
					addMemberEdition(new Pair(null, (ITypedElement) editions[i]));
			}
			
		} else {
			// add mode
			final Object container= ppath;
			Assert.isNotNull(container);
								
			if (structureCreator == null)
				return null;	// error
		
			// extract all elements of container
			final HashSet current= new HashSet();
			IStructureComparator sco= structureCreator.locate(container, target);
			if (sco != null) {
				Object[] children= sco.getChildren();
				if (children != null)
					for (int i= 0; i < children.length; i++)
						current.add(children[i]);
			}
			
			final IStructureCreator sc= structureCreator;
			
			// construct the comparer thread
			// and perform the background extract
			fThread= new Thread() {
				public void run() {
					
					// from front (newest) to back (oldest)
					for (int i= 0; i < count; i++) {
							
						if (fEditionTree == null || fEditionTree.isDisposed())
							break;
						ITypedElement edition= (ITypedElement) editions[i];
						
						IStructureComparator sco2= sc.locate(container, edition);
						if (sco2 != null) {
							Object[] children= sco2.getChildren();
							if (children != null) {
								for (int i2= 0; i2 < children.length; i2++) {
									ITypedElement child= (ITypedElement) children[i2];
									if (!current.contains(child))
										sendPair(new Pair(sc, edition, child));
								}
							}
						}
					}
					sendPair(null);
				}
			};
		}
		
		open();
		
		if (getReturnCode() == OK)
			return fSelectedItem;
		return null;
	}
	
	private Pair createPair(IStructureCreator sc, Object path, ITypedElement input) {
		IStructureComparator scmp= sc.locate(path, input);
		if (scmp == null && sc.getStructure(input) == null) {	// parse error
			Pair p= new Pair(sc, input);
			p.fHasError= true;
			return p;
		}
		if (scmp instanceof ITypedElement)
			return new Pair(sc, input, (ITypedElement) scmp);
		return null;
	}

	/**
	 * Controls whether identical entries are shown or not (default).
	 * This method must be called before <code>selectEdition</code>.
	 *
	 * @param hide if true identical entries are hidden; otherwise they are shown.
	 */
	public void setHideIdenticalEntries(boolean hide) {
		fHideIdentical= hide;
	}

	/**
	 * Controls whether workspace target is on the left (the default) or right hand side.
	 *
	 * @param isRight if true target is shown on right hand side.
	 */
	public void setTargetIsRight(boolean isRight) {
		fTargetIsRight= isRight;
	}
		
	/**
	 * Controls whether the EditionSelectionDialog is in 'add' mode
	 * or 'replace' mode (the default).
	 *
	 * @param addMode if true dialog is in 'add' mode.
	 */
	public void setAddMode(boolean addMode) {
		fAddMode= addMode;
	}
	
	/**
	 * Controls whether the EditionSelectionDialog is in 'compare' mode
	 * or 'add/replace' (the default) mode. 
	 *
	 * @param addMode if true dialog is in 'add' mode.
	 */
	public void setCompareMode(boolean compareMode) {
		fCompareMode= compareMode;
		fStructureCompare= fCompareMode && !fAddMode;
	}
	
	/**
	 * Returns the input target that has been specified with the most recent call
	 * to <code>selectEdition</code>. If a not <code>null</code> path was specified this method
	 * returns a subsection of this target (<code>IStructureCreator.locate(path, target)</code>)
	 * instead of the input target.
	 * <p>
	 * For example if the <code>target</code> is a Java compilation unit and <code>path</code> specifies
	 * a method, the value returned from <code>getTarget</code> will be the method not the compilation unit.
	 *
	 * @return the last specified target or a subsection thereof.
	 */
	public ITypedElement getTarget() {
		return fTargetPair.getItem();
	}
 	
 	/**
 	 * Returns a label for identifying the target side of a compare viewer.
 	 * This implementation extracts the value for the key "targetLabel" from the resource bundle
 	 * and passes it as the format argument to <code>MessageFormat.format</code>.
 	 * The single format argument for <code>MessageFormat.format</code> ("{0}" in the format string)
 	 * is the name of the given input element.
	 * <p>
	 * Subclasses may override to create their own label.
	 * </p>
 	 *
 	 * @param target the target element for which a label must be returned
 	 * @param item if a path has been specified in <code>selectEdition</code> a sub element of the given target; otherwise the same as target
 	 * @return a label the target side of a compare viewer
  	 */
	protected String getTargetLabel(ITypedElement target, ITypedElement item) {
		String format= null;
		if (target instanceof ResourceNode)
			format= Utilities.getString(fBundle, "workspaceTargetLabel", null); //$NON-NLS-1$
		if (format == null)
			format= Utilities.getString(fBundle, "targetLabel"); //$NON-NLS-1$
		if (format == null)
			format= "x{0}"; //$NON-NLS-1$
		
		return MessageFormat.format(format, new Object[] { target.getName() });
	}
	
 	/**
 	 * Returns a label for identifying the edition side of a compare viewer.
 	 * This implementation extracts the value for the key "editionLabel" from the resource bundle
 	 * and passes it as the format argument to <code>MessageFormat.format</code>.
 	 * The single format argument for <code>MessageFormat.format</code> ("{0}" in the format string)
 	 * is the formatted modification date of the given input element.
 	 * <p>
	 * Subclasses may override to create their own label.
	 * </p>
	 *
	 * @param selectedEdition the selected edition for which a label must be returned
 	 * @param item if a path has been specified in <code>selectEdition</code> a sub element of the given selectedEdition; otherwise the same as selectedEdition
 	 * @return a label the edition side of a compare viewer
  	 */
	protected String getEditionLabel(ITypedElement selectedEdition, ITypedElement item) {
		String format= null;
		if (selectedEdition instanceof ResourceNode)
			format= Utilities.getString(fBundle, "workspaceEditionLabel", null);	//$NON-NLS-1$
		else if (selectedEdition instanceof HistoryItem)
			format= Utilities.getString(fBundle, "historyEditionLabel", null);	//$NON-NLS-1$
		if (format == null)
			format= Utilities.getString(fBundle, "editionLabel");	//$NON-NLS-1$
		if (format == null)
			format= "x{0}";	//$NON-NLS-1$
		

		String date= "";	//$NON-NLS-1$
		if (selectedEdition instanceof IModificationDate) {
			long modDate= ((IModificationDate)selectedEdition).getModificationDate();
			date= DateFormat.getDateTimeInstance().format(new Date(modDate));
		}
		
		return MessageFormat.format(format, new Object[] { date });
	}
	
	protected String getShortEditionLabel(ITypedElement edition, ITypedElement item, Date date) {
		String format= null;
		if (edition instanceof ResourceNode)
			format= Utilities.getString(fBundle, "workspaceTreeFormat", null);	//$NON-NLS-1$
		if (format == null)
			format= Utilities.getString(fBundle, "treeFormat", null);	//$NON-NLS-1$
		if (format == null)
			format= "x{0}"; //$NON-NLS-1$

		String ds= DateFormat.getTimeInstance().format(date);
		return MessageFormat.format(format, new Object[] { ds });
	}
	
 	/**
 	 * Returns an image for identifying the edition side of a compare viewer.
 	 * This implementation extracts the value for the key "editionLabel" from the resource bundle
 	 * and passes it as the format argument to <code>MessageFormat.format</code>.
 	 * The single format argument for <code>MessageFormat.format</code> ("{0}" in the format string)
 	 * is the formatted modification date of the given input element.
 	 * <p>
	 * Subclasses may override to create their own label.
	 * </p>
	 *
	 * @param selectedEdition the selected edition for which a label must be returned
 	 * @param item if a path has been specified in <code>selectEdition</code> a sub element of the given selectedEdition; otherwise the same as selectedEdition
 	 * @return a label the edition side of a compare viewer
  	 */
	protected Image getEditionImage(ITypedElement selectedEdition, ITypedElement item) {
		if (selectedEdition instanceof ResourceNode)
			return selectedEdition.getImage();
		if (selectedEdition instanceof HistoryItem)
			return fTimeImage;
		return null;
	}
	
 	/* (non Javadoc)
 	 * Creates SWT control tree.
 	 */
	protected synchronized Control createDialogArea(Composite parent) {
		
		getShell().setText(Utilities.getString(fBundle, "title")); //$NON-NLS-1$
		
		Splitter vsplitter= new Splitter(parent,  SWT.VERTICAL);
		vsplitter.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL
					| GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL));

		vsplitter.addDisposeListener(
			new DisposeListener() {
				public void widgetDisposed(DisposeEvent e) {
					if (fDateImage != null)
						fDateImage.dispose();
					if (fTimeImage != null)
						fTimeImage.dispose();
				}
			}
		);
		
		if (fAddMode) {
			// we need two panes: the left for the elements, the right one for the editions
			Splitter hsplitter= new Splitter(vsplitter,  SWT.HORIZONTAL);
			
			fMemberPane= new CompareViewerPane(hsplitter, SWT.BORDER | SWT.FLAT);
			fMemberPane.setText(Utilities.getString(fBundle, "memberPaneTitle")); //$NON-NLS-1$
			fMemberTable= new Table(fMemberPane, SWT.H_SCROLL + SWT.V_SCROLL);
			fMemberTable.addSelectionListener(
				new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						handleMemberSelect(e.item);
					}
				}
			);
			
			fMemberPane.setContent(fMemberTable);
			
			fEditionPane= new CompareViewerPane(hsplitter, SWT.BORDER | SWT.FLAT);
		} else {
			if (fStructureCompare) {
				// we need two panes: the left for the elements, the right one for the structured diff
				Splitter hsplitter= new Splitter(vsplitter,  SWT.HORIZONTAL);
				
				fEditionPane= new CompareViewerPane(hsplitter, SWT.BORDER | SWT.FLAT);
				fStructuredComparePane= new CompareViewerSwitchingPane(hsplitter, SWT.BORDER | SWT.FLAT, true) {
					protected Viewer getViewer(Viewer oldViewer, Object input) {
						if (input instanceof ICompareInput)
							return CompareUIPlugin.findStructureViewer(oldViewer, (ICompareInput)input, this, fCompareConfiguration);
						return null;
					}
				};
				fStructuredComparePane.addSelectionChangedListener(
					new ISelectionChangedListener() {
						public void selectionChanged(SelectionChangedEvent e) {
							feedInput2(e.getSelection());
						}
					}
				);
			} else {
				// only a single pane showing the editions
				fEditionPane= new CompareViewerPane(vsplitter, SWT.BORDER | SWT.FLAT);
			}
			if (fTitleArg == null)
				fTitleArg= fTargetPair.getItem().getName();
			String titleFormat= Utilities.getString(fBundle, "treeTitleFormat"); //$NON-NLS-1$
			String title= MessageFormat.format(titleFormat, new String[] { fTitleArg });
			fEditionPane.setText(title);
			if (fTitleImage != null)
				fEditionPane.setImage(fTitleImage);
		}
		
		fEditionTree= new Tree(fEditionPane, SWT.H_SCROLL + SWT.V_SCROLL);
		fEditionTree.addSelectionListener(
			new SelectionAdapter() {
//				public void widgetDefaultSelected(SelectionEvent e) {
//					handleDefaultSelected();
//				}
				public void widgetSelected(SelectionEvent e) {
					feedInput(e.item);
				}
			}
		);
		fEditionPane.setContent(fEditionTree);		
		
		// now start the thread (and forget about it)
		if (fThread != null) {
			fThread.start();
			fThread= null;
		}
		
		fContentPane= new CompareViewerSwitchingPane(vsplitter, SWT.BORDER | SWT.FLAT) {
			protected Viewer getViewer(Viewer oldViewer, Object input) {
				return CompareUIPlugin.findContentViewer(oldViewer, input, this, fCompareConfiguration);	
			}
		};
		vsplitter.setWeights(new int[] { 30, 70 });
				
		return vsplitter;
	}
	
	/* (non-Javadoc)
	 * Method declared on Dialog.
	 */
	protected void createButtonsForButtonBar(Composite parent) {
		String buttonLabel= Utilities.getString(fBundle, "buttonLabel", IDialogConstants.OK_LABEL); //$NON-NLS-1$
		if (fCompareMode) {
			// only a 'Done' button
			createButton(parent, IDialogConstants.CANCEL_ID, buttonLabel, false);
		} else {
			// a 'Cancel' and a 'Add/Replace' button
			fCommitButton= createButton(parent, IDialogConstants.OK_ID, buttonLabel, true);
			fCommitButton.setEnabled(false);
			createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
		}
	}

	/**
	 * Overidden to disable dismiss on double click in compare mode.
	 */
	protected void okPressed() {
		if (fCompareMode)
			;	// don't dismiss dialog
		else
			super.okPressed();
	}

	//---- private stuff ----------------------------------------------------------------------------------------
				
	/**
	 * Asynchroneously sends a Pair (or null) to the UI thread.
	 */
	private void sendPair(final Pair pair) {		
		if (fEditionTree != null && !fEditionTree.isDisposed()) {
			Display display= fEditionTree.getDisplay();
			display.asyncExec(
				new Runnable() {
					public void run() {
						addMemberEdition(pair);
					}
				}
			);
		}
	}

//	private void handleDefaultSelected() {
//		if (fSelectedItem != null)
//			okPressed();
//	}
	
	private static void internalSort(IModificationDate[] keys, int left, int right) { 
	
		int original_left= left;
		int original_right= right;
		
		IModificationDate mid= keys[(left + right) / 2]; 
		do { 
			while (keys[left].getModificationDate() > mid.getModificationDate())
				left++; 
			
			while (mid.getModificationDate() > keys[right].getModificationDate())
				right--; 
		
			if (left <= right) { 
				IModificationDate tmp= keys[left]; 
				keys[left]= keys[right]; 
				keys[right]= tmp;			
				left++; 
				right--; 
			} 
		} while (left <= right);
		
		if (original_left < right)
			internalSort(keys, original_left, right); 
		
		if (left < original_right)
			internalSort(keys, left, original_right); 
	}
	
	/**
	 * Adds the given Pair to the member editions.
	 * If HIDE_IDENTICAL is true the new Pair is only added if its contents
	 * is different from the preceeding Pair.
	 * If the argument is <code>null</code> the message "No Editions found" is shown
	 * in the member or edition viewer.
	 */
	private void addMemberEdition(Pair pair) {
		
		if (pair == null) {	// end of list of pairs
			if (fMemberTable != null) {
				if (!fMemberTable.isDisposed() && fMemberTable.getItemCount() == 0) {
					TableItem ti= new TableItem(fMemberTable, SWT.NONE);
					ti.setText(Utilities.getString(fBundle, "noAdditionalMembersMessage")); //$NON-NLS-1$
				}
				return;
			}			
			if (fEditionTree != null && !fEditionTree.isDisposed() && fEditionTree.getItemCount() == 0) {
				TreeItem ti= new TreeItem(fEditionTree, SWT.NONE);
				ti.setText(Utilities.getString(fBundle, "notFoundInLocalHistoryMessage")); //$NON-NLS-1$
			}
			return;
		}
		
		if (fMemberEditions == null)
			fMemberEditions= new HashMap();
		
		ITypedElement item= pair.getItem();
		List editions= (List) fMemberEditions.get(item);
		if (editions == null) {
			editions= new ArrayList();
			fMemberEditions.put(item, editions);
			if (fMemberTable != null && !fMemberTable.isDisposed()) {
				ITypedElement te= (ITypedElement)item;
				String name= te.getName();
				
				// find position
				TableItem[] items= fMemberTable.getItems();
				int where= items.length;
				for (int i= 0; i < where; i++) {
					String n= items[i].getText();
					if (n.compareTo(name) > 0) {
						where= i;
						break;
					}
				}
				
				TableItem ti= new TableItem(fMemberTable, where, SWT.NULL);
				ti.setImage(te.getImage());
				ti.setText(name);
				ti.setData(editions);
			}
		}
		if (fHideIdentical) {
			Pair last= fTargetPair;
			int size= editions.size();
			if (size > 0)
				last= (Pair) editions.get(size-1);
			if (last != null && last.equals(pair))
				return;	// don't add since the new one is equal to old
		}
		editions.add(pair);
		
		if (!fAddMode || editions == fCurrentEditions)
			addEdition(pair);
	}
	
	/**
	 * Returns the number of s since Jan 1st, 1970.
	 * The given date is converted to GMT and daylight saving is taken into account too.
	 */
	private long dayNumber(long date) {
		int ONE_DAY_MS= 24*60*60 * 1000; // one day in milli seconds
		
		Calendar calendar= Calendar.getInstance();
		long localTimeOffset= calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET);
		
		return (date + localTimeOffset) / ONE_DAY_MS;
	}
	
	/**
	 * Adds the given Pair to the edition tree.
	 * It takes care of creating tree nodes for different dates.
	 */
	private void addEdition(Pair pair) {
		if (fEditionTree == null || fEditionTree.isDisposed())
			return;
		
		// find last day
		TreeItem[] days= fEditionTree.getItems();
		TreeItem lastDay= null;
		if (days.length > 0)
			lastDay= days[days.length-1];
		
		boolean first= lastDay == null;
		
		ITypedElement edition= pair.getEdition();
		ITypedElement item= pair.getItem();
		
		long ldate= ((IModificationDate)edition).getModificationDate();		
		long day= dayNumber(ldate);
		Date date= new Date(ldate);
		if (lastDay == null || day != dayNumber(((Date)lastDay.getData()).getTime())) {
			lastDay= new TreeItem(fEditionTree, SWT.NONE);
			lastDay.setImage(fDateImage);
			String df= DateFormat.getDateInstance().format(date);
			long today= dayNumber(System.currentTimeMillis());
			
			String formatKey;
			if (day == today)
				formatKey= "todayFormat"; //$NON-NLS-1$
			else if (day == today-1)
				formatKey= "yesterdayFormat"; //$NON-NLS-1$
			else
				formatKey= "dayFormat"; //$NON-NLS-1$
			String pattern= Utilities.getString(fBundle, formatKey);
			if (pattern != null)
				df= MessageFormat.format(pattern, new String[] { df });
			lastDay.setText(df);
			lastDay.setData(date);
		}
		TreeItem ti= new TreeItem(lastDay, SWT.NONE);
		ti.setImage(getEditionImage(edition, item));
		
		String s= getShortEditionLabel(edition, item, date);
		if (pair.fHasError) {
			String pattern= Utilities.getString(fBundle, "parseErrorFormat"); //$NON-NLS-1$
			s= MessageFormat.format(pattern, new String[] { s } );
		}
		ti.setText(s);
		
		ti.setData(pair);
		if (first) {
			fEditionTree.setSelection(new TreeItem[] {ti});
			if (!fAddMode)
				fEditionTree.setFocus();
			feedInput(ti);
		}
		if (first) // expand first node
			lastDay.setExpanded(true);
	}
						
	/**
	 * Feeds selection from member viewer to edition viewer.
	 */
	private void handleMemberSelect(Widget w) {
		Object data= w.getData();
		if (data instanceof List) {
			List editions= (List) data;
			if (editions != fCurrentEditions) {
				fCurrentEditions= editions;
				fEditionTree.removeAll();
				
				String pattern= Utilities.getString(fBundle, "treeTitleFormat"); //$NON-NLS-1$
				String title= MessageFormat.format(pattern, new Object[] { ((Item)w).getText() });
				fEditionPane.setText(title);
								
				Iterator iter= editions.iterator();
				while (iter.hasNext()) {
					Object item= iter.next();
					if (item instanceof Pair)
						addEdition((Pair) item);
				}
			}
		}
	}
	
	private void setInput(Object input) {
		if (!fCompare && input instanceof ICompareInput) {
			ICompareInput ci= (ICompareInput) input;
			if (fTargetIsRight)
				input= ci.getLeft();
			else
				input= ci.getRight();
		}
		fContentPane.setInput(input);
		if (fStructuredComparePane != null)
			fStructuredComparePane.setInput(input);
	}
	
	/*
	 * Feeds selection from edition viewer to content (and structure) viewer.
	 */
	private void feedInput(Widget w) {
		Object input= w.getData();
		boolean isOK= false;
		if (input instanceof Pair) {
			Pair pair= (Pair) input;
			fSelectedItem= pair.getItem();
			isOK= !pair.fHasError;
			
			ITypedElement edition= pair.getEdition();
			String editionLabel= getEditionLabel(edition, fSelectedItem);
			Image editionImage= getEditionImage(edition, fSelectedItem);
			
			if (fAddMode) {
				setInput(fSelectedItem);
				fContentPane.setText(editionLabel);
				fContentPane.setImage(editionImage);
			} else {
				if (fTargetIsRight) {
					fCompareConfiguration.setLeftLabel(editionLabel);
					fCompareConfiguration.setLeftImage(editionImage);
					setInput(new DiffNode(fSelectedItem, fTargetPair.getItem()));
				} else {
					fCompareConfiguration.setRightLabel(editionLabel);
					fCompareConfiguration.setRightImage(editionImage);
					setInput(new DiffNode(fTargetPair.getItem(), fSelectedItem));
				}
			}
		} else {
			fSelectedItem= null;
			setInput(null);
		}
		if (fCommitButton != null)
			fCommitButton.setEnabled(isOK && fSelectedItem != null && fTargetPair.getItem() != fSelectedItem);
	}
	
	/*
	 * Feeds selection from structure viewer to content viewer.
	 */
	private void feedInput2(ISelection sel) {
		if (sel instanceof IStructuredSelection) {
			IStructuredSelection ss= (IStructuredSelection) sel;
			if (ss.size() == 1)
				fContentPane.setInput(ss.getFirstElement());
		}
	}
}
