/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
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;
	}

	/* (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 instanceof ITypedElement)
				path= getPath((ITypedElement)parent, level+1);
		}
		if (path == null)
			path= new String[level+1];
		path[(path.length-1)-level]= el.getName();
		return path;
	}
}
