package org.eclipse.jdt.internal.core.builder;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
import java.io.*;

/**
 * <code>DeltaKey</code> objects are used to index into hierarchical structures.
 * They consist of a sequence of local names, which can be 
 * arbitrary objects.  A node in the hierarchy is obtained by 
 * traversing down from the root of the hierarchy, using the
 * localNames to indicate the choice of child at each step along the way.
 *
 * <p><code>DeltaKey</code> objects are immutable, as they must consistently describe
 * a particular branch of a source tree.  If branches are addded or deleted
 * from a <code>DeltaKey</code> object, it is done by creating a copy and modifying
 * the copy.
 */
public class DeltaKey implements IDeltaKey, Serializable {
	
	/**
	 * Names of the branches of the key
	 */
	protected Object[] fLocalNames;
	
	/**
	 * Singleton root node instance.
	 */
	protected static DeltaKey NodeRoot = new DeltaKey(0);

	/** Version UID for serialization purposes (as of LF 143)
   */
  protected static final long serialVersionUID = 1379863541613390307L;


	/**
	 * Sets the names of the key
	 */
	public DeltaKey(Object[] names) {
		fLocalNames = names;
	}
	/**
	 * Creates a new key of the given length.
	 */
	protected DeltaKey (int length) {
		fLocalNames = new Object[length];
	}
	/**
	 * Returns a new key describing the key's child with the given local name.
	 * This replaces the "/" syntax in the Smalltalk implementation
	 */
	public DeltaKey add(Object localName) {
		

		/* Calculate length of new key */
		int length = this.size();

		DeltaKey newKey = new DeltaKey(length + 1);
		
		/* Copy names from receiver to new key */
		newKey.replaceFromToWithStartingAt(0, length - 1, this, 0);
		
		/* Add new local name at end of new key */
		newKey.fLocalNames[length] = localName;
		
		return newKey;
	}
	/**
	 * Returns the local name at the given index in the receiver
	 */
	public Object at(int index) {
		return fLocalNames[index];
	}
	/** 
	 * Returns true if the receiver has the exact same local names as anObject.
	 * Returns false otherwise.
	 * Returns false if anObject is not an instance of NodeKey
	 */
	public boolean equals (Object anObject) {
		
		DeltaKey aKey;
		int result;		
			
		/* return true if the same object */
		if (this == anObject) {
			return true;
		}
		
		/* return false if different class of object */
		if (anObject instanceof DeltaKey) {
			aKey = (DeltaKey) anObject;
		} else {
			return false;
		}
		
		/* return false if not the same number of names */
		if (this.size() != aKey.size()) {
			return false;
		}
		
		/* not equal if any local names are not equal */
		for (int i = this.size() - 1; i >= 0; i--) {
			if (!this.at(i).equals(aKey.at(i))) {
				return false;
			}
		}
		return true;
	}
	/**
	 * Returns the receiver's local name (the name of the last child).  If the
	 * receiver is a root key, answer null
	 */
	public Object getLocalName() {
		if (this.size() == 0) {
			return null;
		} else {
			return fLocalNames[fLocalNames.length - 1];
		}
	}
	/**
	 * Returns the local names of the key
	 */
	protected Object[] getLocalNames() {
		return fLocalNames;
	}
	/**
	 * Returns the singleton root node instance.
	 */
	public static DeltaKey getRoot() {
		return NodeRoot;
	}
	/**
	 * Returns the hash value of the receiver.  Objects which are equal have
	 * the same hash value.
	 */
	public int hashCode() {

		int hash, selfSize;
		
		selfSize = this.size();
		if (selfSize == 0) {
			return 0;
		}		
		
		/* Hash the first element */
		hash = this.at(0).hashCode();
		if (selfSize == 1) {
			return hash;
		}
		
		/* Hash the last element */
		hash ^= this.at(selfSize - 1).hashCode();
		if (selfSize == 2) {
			return hash & 32767;
		}

		/* Hash the middle element for good luck */
		hash ^= this.at(selfSize / 2).hashCode();
		return hash & 32767;
	}
	/**
	 * Returns true if the receiver is a prefix of the given key, false otherwise.
	 * Keys which are equal are considered to be prefixes of each other (so
	 * true is answered in this case).
	 */
	public boolean isPrefixOf (DeltaKey key) {

		int size;

		/**
		 * Capitalize on the property that compound keys are usually paths, 
		 * where a common prefix is more likely than a common suffix. 
		 * Compare last elements before comparing the rest.
		 */

		size = this.size();
		if (size > key.size()) {
			return false;
		}
		if (size == 0) {
			return true;
		}

		/* Check the last element first. */
		size--;
		if (this.fLocalNames[size] != key.fLocalNames[size]) {
			return false;
		}
		if (--size <= 0) {
			return true;
		}
		
		/* Check the first element next */
		if (this.fLocalNames[0] != key.fLocalNames[0]) {
			return false;
		}
		if (size == 1) {
			return true;
		}
		
		/* Unroll the loop for increased performance */
		if (this.fLocalNames[size] != key.fLocalNames[size]) {return false;}
		if (--size == 1) {return true;}

		if (this.fLocalNames[size] != key.fLocalNames[size]) {return false;}
		if (--size == 1) {return true;}

		if (this.fLocalNames[size] != key.fLocalNames[size]) {return false;}
		if (--size == 1) {return true;}

		if (this.fLocalNames[size] != key.fLocalNames[size]) {return false;}
		if (--size == 1) {return true;}

		if (this.fLocalNames[size] != key.fLocalNames[size]) {return false;}
		if (--size == 1) {return true;}

		if (this.fLocalNames[size] != key.fLocalNames[size]) {return false;}
		if (--size == 1) {return true;}

		if (this.fLocalNames[size] != key.fLocalNames[size]) {return false;}
		if (--size == 1) {return true;}

		if (this.fLocalNames[size] != key.fLocalNames[size]) {return false;}
		if (--size == 1) {return true;}

		if (this.fLocalNames[size] != key.fLocalNames[size]) {return false;}
		if (--size == 1) {return true;}

		while (size > 1) {
			if (this.fLocalNames[size] != key.fLocalNames[size]) {
				return false;
			}
		}
		return true;
	}
	/**
	 * Returns true if the receiver is the root key, false otherwise
	 */
	public boolean isRoot() {
		return (this.size() == 0);
	}
	/**
	 * Returns the key describing the receiver's parent, or null if the receiver
	 * is the root key.
	 */
	 public DeltaKey parent() {

		int size = this.size() - 1;
		DeltaKey newKey;
		
		if (size < 0) {
			return null;
		} else {
			newKey = new DeltaKey (size);
			
			/* copy children from receiver */
			newKey.replaceFromToWithStartingAt(0, size -1, this, 0);
			return newKey;
		}
	}
	/**
	 * Returns a new key containing the first few local names in the
	 * receiver.
	 *
	 * @param count
	 *	number of local names to copy (length of prefix)
	 * @exception IllegalArgumentException
	 *	receiver contains fewer than count local names, or count is
	 *	negative."
	 */
	public DeltaKey prefix (int count) {

		DeltaKey newNode;

		if (count < 0 || this.size() < count) {
			throw new IllegalArgumentException (new Integer(count).toString());
		}
		
		newNode = new DeltaKey(count);
		
		/* copy children */
		newNode.replaceFromToWithStartingAt (0, count - 1, this, 0);
		return newNode;
	}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
	int l = in.readInt();
	fLocalNames = new String[l];
	for (int i = 0; i < l; ++i) {
		fLocalNames[i] = in.readObject();
	}
}
	/**
	 * Replaces the elements of the receiver between the given indices
	 * with the elements of the supplied key starting at a particular point.
	 *
	 * Fail if start is not an Integer. Fail if stop is not an
	 * Integer. Fail if repStart is not an Integer. Fail if start
	 * is < 1. Fail if start is > size of the receiver. Fail if
	 * stop is < 1. Fail if repStart < 1. Fail if repStart > size
	 * of replacementKey."
	 *
	 * @param start
	 *	index in the receiver to start copying at
	 * @param stop
	 * 	index in the receiver to stop copying at
	 * @param replacementKey
	 *	key to be copied
	 * @param repStart
	 *	index to start copying from in the replacement key
	 * @return the modified key
	 */
	private DeltaKey replaceFromToWithStartingAt (int start, int stop, 
		DeltaKey replacementKey, int repStart) {
		
	 	int repCount = repStart;
	 	
	 	for (int i = start; i <= stop; i++, repCount++) {
	 		this.fLocalNames[i] = replacementKey.fLocalNames[repCount];
	 	}
	 	return this;
	 }
	/**
	 * Sets the local names of the key
	 */
	protected void setLocalNames(String[] names) {
		fLocalNames = names;
	}
	/**
	 * Returns the branch length of the key
	 */
	public int size() {
		return fLocalNames.length;
	}
	/**
	 * Returns a unicode representation of the receiver.  This method is used
	 * for debugging purposes only (no NLS needed)
	 */
	public String toString () {
		StringBuffer buffer = new StringBuffer();
		
		buffer.append("DeltaKey("/*nonNLS*/);
			
		for (int i = 0; i < this.fLocalNames.length; i++) {
			buffer.append(this.fLocalNames[i]);
			if (i < this.fLocalNames.length - 1) {
				buffer.append("/"/*nonNLS*/);
			}
		}
		buffer.append(")"/*nonNLS*/);

		return buffer.toString();
	}
	/**
	 * Returns a new key containing everything but the first few local
	 * names in the receiver.
	 *
	 * @param count
	 *	number of local names in the key to leave out (length of prefix to cut)
	 * @exception IllegalArgumentException
	 *	receiver contains fewer than count local names, or count is
	 *	negative.
	 */
	public DeltaKey withoutPrefix (int count) {

		DeltaKey newNode;
		int newSize;

		if (count < 0 || this.size() < count) {
			throw new IllegalArgumentException (new Integer (count).toString());
		}
		
		newSize = this.size() - count;
		newNode = new DeltaKey (newSize);
		newNode.replaceFromToWithStartingAt (0, newSize - 1, this, count);
		return newNode;
	}
private void writeObject(ObjectOutputStream out) throws IOException {
	int l = fLocalNames.length;
	out.writeInt(l);
	for (int i = 0; i < l; ++i) {
		out.writeObject(fLocalNames[i]);
	}
}
}// end class definition
