/*******************************************************************************
 * Copyright (c) 2000, 2003 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.structuremergeviewer;

import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.widgets.*;
import org.eclipse.jface.util.PropertyChangeEvent;

import org.eclipse.compare.*;
import org.eclipse.compare.internal.*;


/**
 * A 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 StructureDiffViewer extends DiffTreeViewer {
		
	private Differencer fDifferencer;
	private boolean fThreeWay= false;
	
	private ITypedElement fAncestorInput;
	private ITypedElement fLeftInput;
	private ITypedElement fRightInput;
	
	private IStructureComparator fAncestorStructure;
	private IStructureComparator fLeftStructure;
	private IStructureComparator fRightStructure;
	
	private IStructureCreator fStructureCreator;
	private IDiffContainer fRoot;
	private IContentChangeListener fContentChangedListener;
	private CompareViewerSwitchingPane fParent;
		
	/**
	 * 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
	 */
	public StructureDiffViewer(Tree tree, CompareConfiguration configuration) {
		super(tree, configuration);
		Composite c= tree.getParent();
		if (c instanceof CompareViewerSwitchingPane)
			fParent= (CompareViewerSwitchingPane) c;
		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 StructureDiffViewer(Composite parent, CompareConfiguration configuration) {
		super(parent, configuration);
		if (parent instanceof CompareViewerSwitchingPane)
			fParent= (CompareViewerSwitchingPane) parent;
		initialize();
	}
	
	private void initialize() {
		
		setAutoExpandLevel(3);
		
		fContentChangedListener= new IContentChangeListener() {
			public void contentChanged(IContentChangeNotifier changed) {
				StructureDiffViewer.this.contentChanged(changed);
			}
		};
		new ICompareInputChangeListener() {
			public void compareInputChanged(ICompareInput input) {
				StructureDiffViewer.this.compareInputChanged(input);
			}
		};
	}
	
	/**
	 * Configures the <code>StructureDiffViewer</code> with a structure creator.
	 * The structure creator is used to create a hierarchical structure
	 * for each side of the viewer's input element of type <code>ICompareInput</code>.
	 *
	 * @param structureCreator the new structure creator
	 */
	public void setStructureCreator(IStructureCreator structureCreator) {
		if (fStructureCreator != structureCreator) {
			fStructureCreator= structureCreator;
			Control tree= getControl();
			if (tree != null && !tree.isDisposed())
				tree.setData(CompareUI.COMPARE_VIEWER_TITLE, getTitle());
		}
	}
	
	/**
	 * Returns the structure creator or <code>null</code> if no
	 * structure creator has been set with <code>setStructureCreator</code>.
	 *
	 * @return the structure creator or <code>null</code>
	 */
	public IStructureCreator getStructureCreator() {
		return fStructureCreator;
	}
	
	/**
	 * Reimplemented to get the descriptive title for this viewer from the <code>IStructureCreator</code>.
	 */
	public String getTitle() {
		if (fStructureCreator != null)
			return fStructureCreator.getName();
		return super.getTitle();
	}
	
	/**
	 * Overridden because the input of this viewer is not identical to the root of the tree.
	 * The tree's root is a IDiffContainer that was returned from the method <code>diff</code>.
	 * 
	 * @return the root of the diff tree produced by method <code>diff</code>
	 */
	protected Object getRoot() {
		return fRoot;
	}
	
	/**
	 * Overridden to create the comparable structures from the input object
	 * and to feed them through the differencing engine. Note: for this viewer
	 * the value from <code>getInput</code> is not identical to <code>getRoot</code>.
	 */
	protected void inputChanged(Object input, Object oldInput) {
		if (input instanceof ICompareInput) {
			compareInputChanged((ICompareInput) input);
			if (input != oldInput)
				initialSelection();
		}
	}
	
	protected void initialSelection() {
		expandToLevel(2);
	}

	/* (non Javadoc)
	 * Overridden to unregister all listeners.
	 */
	protected void handleDispose(DisposeEvent event) {
		
		compareInputChanged(null);
		
		fContentChangedListener= null;
				
		super.handleDispose(event);
	}
	
	/**
	 * Recreates the comparable structures for the input sides.
	 */
	protected void compareInputChanged(ICompareInput input) {
		ITypedElement t= null;
		boolean changed= false;
		
		if (input != null)
			t= input.getAncestor();
			
		fThreeWay= (t != null);
		
		if (t != fAncestorInput) {
			if (fAncestorInput instanceof IContentChangeNotifier)
				((IContentChangeNotifier)fAncestorInput).removeContentChangeListener(fContentChangedListener);
			fAncestorInput= t;
			if (fAncestorInput != null) {
				fAncestorStructure= fStructureCreator.getStructure(fAncestorInput);
				changed= true;
			} else
				fAncestorStructure= null;
			if (fAncestorInput instanceof IContentChangeNotifier)
				((IContentChangeNotifier)fAncestorInput).addContentChangeListener(fContentChangedListener);
		}
		
		if (input != null)
			t= input.getLeft();
		if (t != fLeftInput) {
			if (fLeftInput instanceof IContentChangeNotifier)
				((IContentChangeNotifier)fLeftInput).removeContentChangeListener(fContentChangedListener);
			fLeftInput= t;
			if (fLeftInput != null) {
				fLeftStructure= fStructureCreator.getStructure(fLeftInput);
				changed= true;
			} else
				fLeftStructure= null;
			if (fLeftInput instanceof IContentChangeNotifier)
				((IContentChangeNotifier)fLeftInput).addContentChangeListener(fContentChangedListener);
		}
		
		if (input != null)
			t= input.getRight();
		if (t != fRightInput) {
			if (fRightInput instanceof IContentChangeNotifier)
				((IContentChangeNotifier)fRightInput).removeContentChangeListener(fContentChangedListener);
			fRightInput= t;
			if (fRightInput != null) {
				fRightStructure= fStructureCreator.getStructure(fRightInput);
				changed= true;
			} else
				fRightStructure= null;
			if (fRightInput instanceof IContentChangeNotifier)
				((IContentChangeNotifier)fRightInput).addContentChangeListener(fContentChangedListener);
		}
		
		if (changed)
			diff();
	}
	
	/**
	 * Calls <code>diff</code> whenever the byte contents changes.
	 */
	protected void contentChanged(IContentChangeNotifier changed) {
		
		if (fStructureCreator == null)
			return;
			
		if (changed != null) {
			if (changed == fAncestorInput) {
				fAncestorStructure= fStructureCreator.getStructure(fAncestorInput);
			} else if (changed == fLeftInput) {
				fLeftStructure= fStructureCreator.getStructure(fLeftInput);
			} else if (changed == fRightInput) {
				fRightStructure= fStructureCreator.getStructure(fRightInput);
			} else
				return;
		} else {
			fAncestorStructure= fStructureCreator.getStructure(fAncestorInput);
			fLeftStructure= fStructureCreator.getStructure(fLeftInput);
			fRightStructure= fStructureCreator.getStructure(fRightInput);
		}
		
		diff();
	}

	/**
	 * This method is called from within <code>diff()</code> before the difference
	 * tree is being built.
	 * Clients may override this method to perform their own pre-processing.
	 * This default implementation does nothing.
	 * @param ancestor the ancestor input to the differencing operation
	 * @param left the left input to the differencing operation
	 * @param right the right input to the differencing operation
	 * @since 2.0
	 */
	protected void preDiffHook(IStructureComparator ancestor, IStructureComparator left, IStructureComparator right) {
		// we do nothing here
	}
	
	/**
	 * Runs the difference engine and refreshes the tree.
	 */
	protected void diff() {
		
		preDiffHook(fAncestorStructure, fLeftStructure, fRightStructure);
							
		String message= null;
		
		if ((fThreeWay && fAncestorStructure == null) || fLeftStructure == null || fRightStructure == null) {
			// could not get structure of one (or more) of the legs
			fRoot= null;
			message= CompareMessages.getString("StructureDiffViewer.StructureError");	//$NON-NLS-1$
			
		} else {	// calculate difference of the two (or three) structures

			if (fDifferencer == null)
				fDifferencer= new Differencer() {
					protected boolean contentsEqual(Object o1, Object o2) {
						return StructureDiffViewer.this.contentsEqual(o1, o2);
					}
					protected Object visit(Object data, int result, Object ancestor, Object left, Object right) {
						Object o= super.visit(data, result, ancestor, left, right);
						if (fLeftIsLocal && o instanceof DiffNode)
							((DiffNode)o).swapSides(fLeftIsLocal);
						return o;
					}
				};
			
			fRoot= (IDiffContainer) fDifferencer.findDifferences(fThreeWay, null, null,
					fAncestorStructure, fLeftStructure, fRightStructure);
					
			if (fRoot == null || fRoot.getChildren().length == 0) {
				message= CompareMessages.getString("StructureDiffViewer.NoStructuralDifferences");	//$NON-NLS-1$
			} else {
				postDiffHook(fDifferencer, fRoot);
			}
		}
		if (fParent != null)
			fParent.setTitleArgument(message);
			
		refresh(getRoot());
	}
	
	/**
	 * This method is called from within <code>diff()</code> after the difference
	 * tree has been built.
	 * Clients may override this method to perform their own post-processing.
	 * This default implementation does nothing.
	 * @param differencer the differencer used to perform the differencing
	 * @param root the non-<code>null</code> root node of the difference tree
	 * @since 2.0
	 */
	protected void postDiffHook(Differencer differencer, IDiffContainer root) {
		// we do nothing here
	}
	
	/**
	 * Performs a byte compare on the given objects.
	 * Called from the difference engine.
	 * Returns <code>null</code> if no structure creator has been set.
	 */
	private boolean contentsEqual(Object o1, Object o2) {
		if (fStructureCreator != null) {
			boolean ignoreWhiteSpace= Utilities.getBoolean(getCompareConfiguration(), CompareConfiguration.IGNORE_WHITESPACE, false);		
			String s1= fStructureCreator.getContents(o1, ignoreWhiteSpace);
			String s2= fStructureCreator.getContents(o2, ignoreWhiteSpace);
			if (s1 == null || s2 == null)
				return false;
			return s1.equals(s2);
		}
		return false;
	}
	
	/**
	 * 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))
			diff();
		else
			super.propertyChange(event);
	}
		
	/**
	 * Overridden to call the <code>save</code> method on the structure creator after
	 * nodes have been copied from one side to the other side of an input object.
	 *
	 * @param leftToRight if <code>true</code> the left side is copied to the right side.
	 * If <code>false</code> the right side is copied to the left side
	 */
	protected void copySelected(boolean leftToRight) {
		super.copySelected(leftToRight);
		
		if (fStructureCreator != null)
			fStructureCreator.save(
							leftToRight ? fRightStructure : fLeftStructure,
							leftToRight ? fRightInput : fLeftInput);
	}
}

