/*******************************************************************************
 * 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.structuremergeviewer;

import java.text.MessageFormat;

import org.eclipse.swt.graphics.Image;

import org.eclipse.jface.util.ListenerList;

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

/**
 * Diff node are used as the compare result of the differencing engine.
 * Since it implements the <code>ITypedElement</code> and <code>ICompareInput</code>
 * interfaces it can be used directly to display the
 * compare result in a <code>DiffTreeViewer</code> and as the input to any other
 * compare/merge viewer.
 * <p>
 * <code>DiffNode</code>s are typically created as the result of performing
 * a compare with the <code>Differencer</code>.
 * <p>
 * Clients typically use this class as is, but may subclass if required.
 * 
 * @see DiffTreeViewer
 * @see Differencer
 */
public class DiffNode extends DiffContainer implements ITypedElement, ICompareInput {

	private ITypedElement fAncestor;
	private ITypedElement fLeft;
	private ITypedElement fRight;
	private boolean fDontExpand;
	private ListenerList fListener;
	private boolean fSwapSides;

	
	/**
	 * Creates a new <code>DiffNode</code> and initializes with the given values.
	 *
	 * @param parent under which the new container is added as a child or <code>null</code>
	 * @param kind of difference (defined in <code>Differencer</code>)
	 * @param ancestor the common ancestor input to a compare
	 * @param left the left input to a compare
	 * @param right the right input to a compare
	 */
	public DiffNode(IDiffContainer parent, int kind, ITypedElement ancestor, ITypedElement left, ITypedElement right) {
		this(parent, kind);
		fAncestor= ancestor;
		fLeft= left;
		fRight= right;
	}

	/**
	 * Creates a new <code>DiffNode</code> with diff kind <code>Differencer.CHANGE</code>
	 * and initializes with the given values.
	 *
	 * @param left the left input to a compare
	 * @param right the right input to a compare
	 */
	public DiffNode(ITypedElement left, ITypedElement right) {
		this(null, Differencer.CHANGE, null, left, right);
	}

	/**
	 * Creates a new <code>DiffNode</code> and initializes with the given values.
	 *
	 * @param kind of difference (defined in <code>Differencer</code>)
	 * @param ancestor the common ancestor input to a compare
	 * @param left the left input to a compare
	 * @param right the right input to a compare
	 */
	public DiffNode(int kind, ITypedElement ancestor, ITypedElement left, ITypedElement right) {
		this(null, kind, ancestor, left, right);
	}

	/**
	 * Creates a new <code>DiffNode</code> with the given diff kind.
	 *
	 * @param kind of difference (defined in <code>Differencer</code>)
	 */
	public DiffNode(int kind) {
		super(null, kind);
	}

	/**
	 * Creates a new <code>DiffNode</code> and initializes with the given values.
	 *
	 * @param parent under which the new container is added as a child or <code>null</code>
	 * @param kind of difference (defined in <code>Differencer</code>)
	 */
	public DiffNode(IDiffContainer parent, int kind) {
		super(parent, kind);
	}

	/**
	 * Registers a listener for changes of this <code>ICompareInput</code>.
	 * Has no effect if an identical listener is already registered.
	 *
	 * @param listener the listener to add
	 */
	public void addCompareInputChangeListener(ICompareInputChangeListener listener) {
		if (fListener == null)
			fListener= new ListenerList();
		fListener.add(listener);
	}
	
	/**
	 * Unregisters a <code>ICompareInput</code> listener.
	 * Has no effect if listener is not registered.
	 *
	 * @param listener the listener to remove
	 */
	public void removeCompareInputChangeListener(ICompareInputChangeListener listener) {
		if (fListener != null) {
			fListener.remove(listener);
			if (fListener.isEmpty())
				fListener= null;
		}
	}
	
	/**
	 * Sends out notification that a change has occured on the <code>ICompareInput</code>.
	 */
	protected void fireChange() {
		if (fListener != null) {
			Object[] listeners= fListener.getListeners();
			for (int i= 0; i < listeners.length; i++)
				((ICompareInputChangeListener) listeners[i]).compareInputChanged(this);
		}
	}

	//---- getters & setters

	/**
	 * Returns <code>true</code> if this node shouldn't automatically be expanded in
	 * a </code>DiffTreeViewer</code>.
	 *
	 * @return <code>true</code> if node shouldn't automatically be expanded
	 */
	public boolean dontExpand() {
		return fDontExpand;
	}

	/**
	 * Controls whether this node is not automatically expanded when displayed in
	 * a </code>DiffTreeViewer</code>.
	 *
	 * @param dontExpand if <code>true</code> this node is not automatically expanded in </code>DiffTreeViewer</code>
	 */
	public void setDontExpand(boolean dontExpand) {
		fDontExpand= dontExpand;
	}

	/**
	 * Returns the first not-<code>null</code> input of this node.
	 * Method checks the three inputs in the order: ancestor, right, left.
	 *
	 * @return the first not-<code>null</code> input of this node
	 */
	public ITypedElement getId() {
		if (fAncestor != null)
			return fAncestor;
		if (fRight != null)
			return fRight;
		return fLeft;
	}

	/**
	 * Returns the (non-<code>null</code>) name of the left or right side if they are identical.
	 * Otherwise both names are concatenated (separated with a slash ('/')).
	 * <p>
	 * Subclasses may re-implement to provide a different name for this node.
	 */
	/* (non Javadoc)
	 * see ITypedElement.getName
	 */
	public String getName() {
		String right= null;
		if (fRight != null)
			right= fRight.getName();

		String left= null;
		if (fLeft != null)
			left= fLeft.getName();

		if (right == null && left == null) {
			if (fAncestor != null)
				return fAncestor.getName();
			return Utilities.getString("DiffNode.noName"); //$NON-NLS-1$
		}

		if (right == null)
			return left;
		if (left == null)
			return right;

		if (right.equals(left))
			return right;
			
		String s1;
		String s2;
		
		if (fSwapSides) {
			s1= left;
			s2= right;
		} else {
			s1= right;
			s2= left;
		}
		
		String fmt= Utilities.getString("DiffNode.nameFormat"); //$NON-NLS-1$
		return MessageFormat.format(fmt, new String[] { s1, s2 });
	}
	
	void swapSides(boolean swap) {
		fSwapSides= swap;
	}
		
	/* (non Javadoc)
	 * see ITypedElement.getImage
	 */
	public Image getImage() {
		ITypedElement id= getId();
		if (id != null)
			return id.getImage();
		return null;
	}

	/* (non Javadoc)
	 * see ITypedElement.getType
	 */
	public String getType() {
		ITypedElement id= getId();
		if (id != null)
			return id.getType();
		return ITypedElement.UNKNOWN_TYPE;
	}

	/**
	 * Sets the ancestor input to the given value.
	 *
	 * @param ancestor the new value for the ancestor input
	 * @since 3.0
	 */
	public void setAncestor(ITypedElement ancestor) {
	    fAncestor= ancestor;
	}
	
	/* (non Javadoc)
	 * see ICompareInput.getAncestor
	 */
	public ITypedElement getAncestor() {
		return fAncestor;
	}
	
	/**
	 * Sets the left input to the given value.
	 *
	 * @param left the new value for the left input
	 */
	public void setLeft(ITypedElement left) {
		fLeft= left;
	}
	
	/* (non Javadoc)
	 * see ICompareInput.getLeft
	 */
	public ITypedElement getLeft() {
		return fLeft;
	}

	/**
	 * Sets the right input to the given value.
	 *
	 * @param right the new value for the right input
	 */
	public void setRight(ITypedElement right) {
		fRight= right;
	}
	
	/* (non Javadoc)
	 * see ICompareInput.getRight
	 */
	public ITypedElement getRight() {
		return fRight;
	}

	/* (non Javadoc)
	 * see ICompareInput.copy
	 */
	public void copy(boolean leftToRight) {
		//System.out.println("DiffNode.copy: " + leftToRight);
		
		IDiffContainer pa= getParent();
		if (pa instanceof ICompareInput) {
			ICompareInput parent= (ICompareInput) pa;
			Object dstParent= leftToRight ? parent.getRight() : parent.getLeft();
			
			if (dstParent instanceof IEditableContent) {
				ITypedElement dst= leftToRight ? getRight() : getLeft();
				ITypedElement src= leftToRight ? getLeft() : getRight();
				dst= ((IEditableContent)dstParent).replace(dst, src);
				if (leftToRight)
					setRight(dst);
				else
					setLeft(dst);
				
				//setKind(Differencer.NO_CHANGE);
				
				fireChange();
			}
		}
	}
	
	/* (non Javadoc)
	 * see Object.hashCode
	 */
	public int hashCode() {
		String[] path= getPath(this, 0);
		int hashCode= 1;
		for (int i= 0; i < path.length; i++) {
	    	String s= path[i];
	   	 	hashCode= (31*hashCode) + (s != null ? s.hashCode() : 0);
		}
		return hashCode;
	}
	
	/* (non Javadoc)
	 * see Object.equals
	 */
	public boolean equals(Object other) {
		if (other != null && getClass() == other.getClass()) {
			String[] path1= getPath(this, 0);
			String[] path2= getPath((DiffNode) other, 0);
			if (path1.length != path2.length)
				return false;
			for (int i= 0; i < path1.length; i++)
				if (! path1[i].equals(path2[i]))
					return false;
			return true;
		}
		return super.equals(other);
	}
	
	private static String[] getPath(ITypedElement el, int level) {
		String[] path= null;
		if (el instanceof IDiffContainer) {
			IDiffContainer parent= ((IDiffContainer)el).getParent();
			if (parent != null)
				path= getPath(parent, level+1);
		}
		if (path == null)
			path= new String[level+1];
		path[(path.length-1)-level]= el.getName();
		return path;
	}
}
