/*******************************************************************************
 * Copyright (c) 2000, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.compare.examples.xml;

import java.lang.reflect.InvocationTargetException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;

import org.eclipse.compare.CompareConfiguration;
import org.eclipse.compare.CompareViewerSwitchingPane;
import org.eclipse.compare.ITypedElement;
import org.eclipse.compare.internal.TimeoutContext;
import org.eclipse.compare.structuremergeviewer.DiffNode;
import org.eclipse.compare.structuremergeviewer.ICompareInput;
import org.eclipse.compare.structuremergeviewer.IStructureComparator;
import org.eclipse.compare.structuremergeviewer.StructureDiffViewer;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Tree;

/**
 * An XML diff tree viewer that can be configured with a <code>IStructureCreator</code>
 * to retrieve a hierarchical structure from the input object (an <code>ICompareInput</code>)
 * and perform a two-way or three-way compare on it.
 * <p>
 * This class may be instantiated; it is not intended to be subclassed outside
 * this package.
 * </p>
 *
 * @see IStructureCreator
 * @see ICompareInput
 */
public class XMLStructureViewer extends StructureDiffViewer {

	private CompareViewerSwitchingPane fParent;

	private HashMap fIdMapsInternal;
	private HashMap fIdMaps;
	private HashMap fOrderedElementsInternal;
	private HashMap fOrderedElements;

	protected static final char SIGN_SEPARATOR=
		XMLStructureCreator.SIGN_SEPARATOR;

	/**
	 * Creates a new viewer for the given SWT tree control with the specified configuration.
	 *
	 * @param tree the tree control
	 * @param configuration the configuration for this viewer
	 */
	class XMLSorter extends ViewerSorter {

		ArrayList fOrdered;
		boolean fAlwaysOrderSort;

		public XMLSorter() {
			super();
			fAlwaysOrderSort= false;
		}

		public void setOrdered(ArrayList ordered) {
			fOrdered= ordered;
		}

		public void setAlwaysOrderSort(boolean alwaysOrderSort) {
			fAlwaysOrderSort= alwaysOrderSort;
		}

		public int category(Object node) {
			if (node instanceof DiffNode) {
				Object o= ((DiffNode) node).getId();
				if (o instanceof XMLNode) {
					String xmlType= ((XMLNode) o).getXMLType();
					if (xmlType.equals(XMLStructureCreator.TYPE_ATTRIBUTE))
						return 1;
					if (xmlType.equals(XMLStructureCreator.TYPE_ELEMENT))
						return 2;
					if (xmlType.equals(XMLStructureCreator.TYPE_TEXT))
						return 2;
				}
			}
			return 0;
		}

		public void sort(final Viewer viewer, Object[] elements) {
			if ((fOrdered != null || fAlwaysOrderSort)
				&& elements != null
				&& elements.length > 0
				&& elements[0] instanceof DiffNode) {
				Object o= ((DiffNode) elements[0]).getId();
				if (o instanceof XMLNode) {
					XMLNode parent= ((XMLNode) o).getParent();
					String sig= parent.getSignature();
					if (sig.endsWith(XMLStructureCreator.SIGN_ELEMENT)) {
						String newSig=
							sig.substring(
								0,
								sig.length()
									- XMLStructureCreator.SIGN_ELEMENT.length());
						if (fAlwaysOrderSort || fOrdered.contains(newSig)) {
							final ArrayList originalTree=
								new ArrayList(
									Arrays.asList(parent.getChildren()));
							Arrays.sort(elements, new Comparator() {
								public int compare(Object a, Object b) {
									return XMLSorter.this.compare(
										(DiffNode) a,
										(DiffNode) b,
										originalTree);
								}
							});
							return;
						}
					}
				}
			}
			super.sort(viewer, elements);
		}

		private int compare(DiffNode a, DiffNode b, ArrayList originalTree) {

			int index_a= originalTree.indexOf(a.getId());
			int index_b= originalTree.indexOf(b.getId());
			if (index_a < index_b)
				return -1;
			else
				return 1;
		}
	}

	public XMLStructureViewer(Tree tree, CompareConfiguration configuration) {
		super(tree, configuration);
		initialize();
	}

	/**
	 * Creates a new viewer under the given SWT parent with the specified configuration.
	 *
	 * @param parent the SWT control under which to create the viewer
	 * @param configuration the configuration for this viewer
	 */
	public XMLStructureViewer(
		Composite parent,
		CompareConfiguration configuration) {
		super(parent, configuration);
		if (parent instanceof CompareViewerSwitchingPane) {
			fParent= (CompareViewerSwitchingPane) parent;
		}
		initialize();
	}

	private void initialize() {
		setStructureCreator(new XMLStructureCreator());
		XMLPlugin plugin= XMLPlugin.getDefault();

		plugin.getViewers().add(this);

		fIdMaps= plugin.getIdMaps();
		fIdMapsInternal= plugin.getIdMapsInternal();
		fOrderedElements= plugin.getOrderedElements();
		fOrderedElementsInternal= plugin.getOrderedElementsInternal();

		XMLSorter sorter= new XMLSorter();
		setSorter(sorter);

	}

	protected XMLStructureCreator getXMLStructureCreator() {
		return (XMLStructureCreator) getStructureCreator();
	}

	/* (non Javadoc)
	 * Overridden to unregister all listeners.
	 */
	protected void handleDispose(DisposeEvent event) {

		XMLPlugin.getDefault().getViewers().remove(this);

		super.handleDispose(event);
	}

	/**
	 * Recreates the comparable structures for the input sides.
	 */
	protected void compareInputChanged(ICompareInput input) {
		if (input != null) {
			ITypedElement t= input.getLeft();
			if (t != null) {
				String fileExtension= t.getType();
				getXMLStructureCreator().setFileExtension(fileExtension);
			}
		}

		getXMLStructureCreator().initIdMaps();
		super.compareInputChanged(input);

		if (input != null && fParent.getTitleArgument() == null)
			appendToTitle(getXMLStructureCreator().getIdMap());
	}

	/**
	 * Calls <code>diff</code> whenever the byte contents changes.
	 */
	protected void contentChanged() {
		fIdMaps= XMLPlugin.getDefault().getIdMaps();
		fOrderedElements= XMLPlugin.getDefault().getOrderedElements();
		getXMLStructureCreator().updateIdMaps();
		if (isIdMapRemoved()) {
			getXMLStructureCreator().setIdMap(
				XMLStructureCreator.DEFAULT_IDMAP);
		}

		getXMLStructureCreator().initIdMaps();

		contentChanged(null);

		if (fParent.getTitleArgument() == null)
			appendToTitle(getXMLStructureCreator().getIdMap());

	}

	public IRunnableWithProgress getMatchingRunnable(
		final XMLNode left,
		final XMLNode right,
		final XMLNode ancestor) {
		return new IRunnableWithProgress() {
			public void run(IProgressMonitor monitor)
				throws
					InvocationTargetException,
					InterruptedException,
					OperationCanceledException {
				if (monitor == null) {
					monitor= new NullProgressMonitor();
				}
				int totalWork;
				if (ancestor != null)
					totalWork= 1;
				else
					totalWork= 3;
				monitor.beginTask(XMLCompareMessages.getString("XMLStructureViewer.matching.beginTask"), totalWork); //$NON-NLS-1$
				ArrayList ordered= null;
				if (!getXMLStructureCreator()
					.getIdMap()
					.equals(XMLStructureCreator.USE_UNORDERED)
					&& !getXMLStructureCreator().getIdMap().equals(
						XMLStructureCreator.USE_ORDERED)) {
					ordered=
						(ArrayList) fOrderedElements.get(
							getXMLStructureCreator().getIdMap());
					if (ordered == null)
						ordered=
							(ArrayList) fOrderedElementsInternal.get(
								getXMLStructureCreator().getIdMap());
				}
				if (getSorter() instanceof XMLSorter)
					 ((XMLSorter) getSorter()).setOrdered(ordered);
				AbstractMatching m= null;
				if (getXMLStructureCreator()
					.getIdMap()
					.equals(XMLStructureCreator.USE_ORDERED)) {
					m= new OrderedMatching();
					if (getSorter() instanceof XMLSorter)
						 ((XMLSorter) getSorter()).setAlwaysOrderSort(true);
				}
				try {
					if (m != null) {
						m.match(left, right, false, monitor);
						if (ancestor != null) {
							m.match(
								left,
								ancestor,
								true,
								new SubProgressMonitor(monitor, 1));
							m.match(
								right,
								ancestor,
								true,
								new SubProgressMonitor(monitor, 1));
						}
						//				} catch (InterruptedException e) {
						//					System.out.println("in run");
						//					e.printStackTrace();
					}
				} finally {
					monitor.done();
				}
			}
		};
	}

	protected void preDiffHook(
		IStructureComparator ancestor,
		IStructureComparator left,
		IStructureComparator right) {
		//		if (!xsc.getIdMap().equals(XMLStructureCreator.USE_ORDERED)) {
		//TimeoutContext.run(true, TIMEOUT, getControl().getShell(), runnable);
		if (left != null && right != null) {
			try {
				TimeoutContext.run(
					true,
					500,
					XMLPlugin.getActiveWorkbenchShell(),
					getMatchingRunnable(
						(XMLNode) left,
						(XMLNode) right,
						(XMLNode) ancestor));
			} catch (Exception e) {
				XMLPlugin.log(e);
			}
		}
	}

	/**
	 * Overriden to create buttons in the viewer's pane control bar.
	 * <p>
	 *
	 * @param toolbarManager the toolbar manager for which to add the buttons
	 */
	protected void createToolItems(ToolBarManager toolBarManager) {
		super.createToolItems(toolBarManager);
		toolBarManager.appendToGroup("modes", new ChooseMatcherDropDownAction(this)); //$NON-NLS-1$
		toolBarManager.appendToGroup("modes", new CreateNewIdMapAction(this)); //$NON-NLS-1$
	}

	/**
	 * Overriden to create a context menu.
	 * <p>
	 *
	 * @param manager the menu manager for which to add menu items
	 */
	protected void fillContextMenu(IMenuManager manager) {
		super.fillContextMenu(manager);
		ISelection s= getSelection();
		if (s instanceof StructuredSelection
			&& ((StructuredSelection) s).getFirstElement() instanceof DiffNode
			&& ((DiffNode) ((StructuredSelection) s).getFirstElement()).getId()
				instanceof XMLNode) {
			DiffNode diffnode=
				(DiffNode) ((StructuredSelection) s).getFirstElement();
			String diffnodeIdSig= ((XMLNode) diffnode.getId()).getSignature();
			fIdMaps= XMLPlugin.getDefault().getIdMaps();
			String idmap_name= getXMLStructureCreator().getIdMap();
			if (diffnodeIdSig.endsWith(XMLStructureCreator.SIGN_ATTRIBUTE) || (diffnodeIdSig.endsWith(XMLStructureCreator.SIGN_TEXT) && ((XMLNode) diffnode.getId()).getOrigId().endsWith("(1)"))) { //$NON-NLS-1$
				Action action= new SetAsIdAction(diffnode);
				if (!fIdMaps.containsKey(idmap_name)) {
					action.setText(XMLCompareMessages.getString("XMLStructureViewer.action.notUserIdMap")); //$NON-NLS-1$
					action.setEnabled(false);
				} else {
					HashMap idmapHM= (HashMap) fIdMaps.get(idmap_name);
					XMLNode idNode= (XMLNode) diffnode.getId();
					String signature= idNode.getSignature();
					String idname= ""; //$NON-NLS-1$
					if (idNode
						.getSignature()
						.endsWith(XMLStructureCreator.SIGN_ATTRIBUTE)) {
						signature=
							signature.substring(
								0,
								signature.indexOf(
									XMLStructureCreator.SIGN_ATTRIBUTE));
						int end_of_signature=
							signature.lastIndexOf(
								SIGN_SEPARATOR,
								signature.length() - 2);
						idname=
							signature.substring(
								end_of_signature + 1,
								signature.length() - 1);
						signature= signature.substring(0, end_of_signature + 1);
					} else if (
						idNode.getSignature().endsWith(
							XMLStructureCreator.SIGN_TEXT)) {
						XMLNode textNode= (XMLNode) diffnode.getId();
						XMLNode idelem= textNode.getParent();
						XMLNode elem= idelem.getParent();
						signature=
							elem.getSignature().substring(
								0,
								elem.getSignature().indexOf(
									XMLStructureCreator.SIGN_ELEMENT));
						idname= idelem.getOrigId();
						idname=
							idname.substring(
								0,
								idname.indexOf(
									XMLStructureCreator.ID_SEPARATOR));
						idname=
							new Character(XMLStructureCreator.ID_TYPE_BODY)
								+ idname;
					}
					if (idmapHM.containsKey(signature)) {
						if (idmapHM.get(signature).equals(idname)) {
							action.setText(XMLCompareMessages.getString("XMLStructureViewer.action.setId.text1")); //$NON-NLS-1$
							action.setEnabled(false);
						} else {
							String oldId= (String) idmapHM.get(signature);
							if (oldId
								.startsWith(
									(new Character(XMLStructureCreator
										.ID_TYPE_BODY))
										.toString()))
								oldId= oldId.substring(1);
							action.setText(MessageFormat.format("{0} {1}", new String[] { XMLCompareMessages.getString("XMLStructureViewer.action.setId.text2"), oldId })); //$NON-NLS-2$ //$NON-NLS-1$
							action.setEnabled(true);
						}
					} else {
						action.setText(XMLCompareMessages.getString("XMLStructureViewer.action.setId.text3")); //$NON-NLS-1$
						action.setEnabled(true);
					}
				}
				manager.add(action);
			} else if (
				diffnodeIdSig.endsWith(XMLStructureCreator.SIGN_ELEMENT)) {
				SetOrderedAction action= new SetOrderedAction(idmap_name);
				if (!fIdMaps.containsKey(idmap_name)) {
					action.setText(XMLCompareMessages.getString("XMLStructureViewer.action.notUserIdMap")); //$NON-NLS-1$
					action.setEnabled(false);
				} else {
					ArrayList idmapOrdered=
						(ArrayList) fOrderedElements.get(idmap_name);
					XMLNode idNode= (XMLNode) diffnode.getId();
					String signature= idNode.getSignature();
					//					String idname= "";
					signature=
						signature.substring(
							0,
							signature.indexOf(
								XMLStructureCreator.SIGN_ELEMENT));
					if (idmapOrdered != null
						&& idmapOrdered.contains(signature)) {
						action.setText(XMLCompareMessages.getString("XMLStructureViewer.action.setOrdered.exists")); //$NON-NLS-1$
						action.setEnabled(false);
					} else {
						action.setText(XMLCompareMessages.getString("XMLStructureViewer.action.setOrdered")); //$NON-NLS-1$
						action.setSignature(signature);
						action.setEnabled(true);
					}
				}

				manager.add(action);
			}
		}
	}

	protected void appendToTitle(String idmap_name) {
		if (fParent != null) {
			getXMLStructureCreator().setIdMap(idmap_name);
			fParent.setTitleArgument(idmap_name);
		}
	}

	/**
	 * Returns true if the current Id Map scheme has been removed.
	 */
	private boolean isIdMapRemoved() {
		XMLStructureCreator xsc= getXMLStructureCreator();
		String IdMapName= xsc.getIdMap();
		return !IdMapName.equals(XMLStructureCreator.USE_UNORDERED)
			&& !IdMapName.equals(XMLStructureCreator.USE_ORDERED)
			&& !fIdMaps.containsKey(IdMapName)
			&& !fIdMapsInternal.containsKey(IdMapName)
			&& !fOrderedElements.containsKey(IdMapName);
	}

	protected class SetAsIdAction extends Action {

		DiffNode fDiffNode;

		public SetAsIdAction(DiffNode diffnode) {
			fDiffNode= diffnode;
		}

		public void run() {
			XMLStructureCreator sc= getXMLStructureCreator();
			//			DiffNode diffnode = (DiffNode) ((StructuredSelection) getSelection()).getFirstElement();
			String idmap_name= sc.getIdMap();
			if (fIdMaps.containsKey(idmap_name)) {
				HashMap idmapHM= (HashMap) fIdMaps.get(idmap_name);
				if (((XMLNode) fDiffNode.getId())
					.getSignature()
					.endsWith(XMLStructureCreator.SIGN_ATTRIBUTE)) {
					XMLNode attrNode= (XMLNode) fDiffNode.getId();
					String signature= attrNode.getSignature();
					signature=
						signature.substring(
							0,
							signature.indexOf(
								XMLStructureCreator.SIGN_ATTRIBUTE));
					int end_of_signature=
						signature.lastIndexOf(
							SIGN_SEPARATOR,
							signature.length() - 2);
					String idattr=
						signature.substring(
							end_of_signature + 1,
							signature.length() - 1);
					signature= signature.substring(0, end_of_signature + 1);
					idmapHM.put(signature, idattr);
					XMLPlugin.getDefault().setIdMaps(
						fIdMaps,
						null,
						null,
						false);
					//contentChanged();
				} else if (
					((XMLNode) fDiffNode.getId()).getSignature().endsWith(
						XMLStructureCreator.SIGN_TEXT)) {
					XMLNode textNode= (XMLNode) fDiffNode.getId();
					XMLNode idelem= textNode.getParent();
					XMLNode elem= idelem.getParent();
					String signature=
						elem.getSignature().substring(
							0,
							elem.getSignature().indexOf(
								XMLStructureCreator.SIGN_ELEMENT));
					String idname= idelem.getOrigId();
					idname=
						idname.substring(
							0,
							idname.indexOf(XMLStructureCreator.ID_SEPARATOR));
					idname=
						new Character(XMLStructureCreator.ID_TYPE_BODY)
							+ idname;
					idmapHM.put(signature, idname);
					XMLPlugin.getDefault().setIdMaps(
						fIdMaps,
						null,
						null,
						false);
					//contentChanged();
				}
			}
		}
	}

	protected class SetOrderedAction extends Action {

		String fIdMapName;
		String fSignature;

		public SetOrderedAction(String idmap_name) {
			fIdMapName= idmap_name;
		}

		public void run() {
			//String idmap_name= getXMLStructureCreator().getIdMap();
			if (fSignature != null) {
				ArrayList idmapOrdered=
					(ArrayList) fOrderedElements.get(fIdMapName);
				if (idmapOrdered == null) {
					idmapOrdered= new ArrayList();
					fOrderedElements.put(fIdMapName, idmapOrdered);
				}
				idmapOrdered.add(fSignature);
			}
		}

		public void setSignature(String signature) {
			fSignature= signature;
		}
	}

	protected void updateIdMaps() {
		getXMLStructureCreator().updateIdMaps();
	}

	/**
	 * Tracks property changes of the configuration object.
	 * Clients may override to track their own property changes.
	 * In this case they must call the inherited method.
	 */
	protected void propertyChange(PropertyChangeEvent event) {
		String key= event.getProperty();
		if (key.equals(CompareConfiguration.IGNORE_WHITESPACE)) {
			getXMLStructureCreator().setRemoveWhiteSpace(
				!getXMLStructureCreator().getRemoveWhiteSpace());
			contentChanged();
		}
		//		else
		//			super.propertyChange(event);
	}
}
