/*******************************************************************************
 * Copyright (c) 2000, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Peter Shipton - original hashtable implementation
 *     Nick Edgar - added element comparer support
 *     David Saff (saff@mit.edu) - bug 102632: [JUnit] Support for JUnit 4.
 *******************************************************************************/

package org.eclipse.jdt.internal.junit.runner;

import java.util.Enumeration;
import java.util.NoSuchElementException;

/**
 * This is a copy of CustomHashtable from org.eclipse.jface.viewers
 */
/* package */public final class CustomHashtable {

	/**
	 * HashMapEntry is an internal class which is used to hold the entries of a
	 * Hashtable.
	 */
	private static class HashMapEntry {

		Object key, value;

		HashMapEntry next;

		HashMapEntry(Object theKey, Object theValue) {
			key= theKey;
			value= theValue;
		}
		
		public String toString() {
			StringBuffer buffer= new StringBuffer();
			appendToStringWithCommaNL(buffer);
			int length= buffer.length();
			if (length >= 2)
				return buffer.substring(0, length - 2);
			else
				return buffer.toString();
		}
		
		private void appendToStringWithCommaNL(StringBuffer buffer) {
			CustomHashtable.HashMapEntry hashMapEntry= this;
			do {
				buffer.append(hashMapEntry.key);
				buffer.append('=');
				buffer.append(hashMapEntry.value);
				buffer.append(",\n"); //$NON-NLS-1$
				hashMapEntry= hashMapEntry.next;
			} while (hashMapEntry != null);
		}
	}

	private static final class EmptyEnumerator implements Enumeration {

		public boolean hasMoreElements() {
			return false;
		}

		public Object nextElement() {
			throw new NoSuchElementException();
		}
	}

	private class HashEnumerator implements Enumeration {

		boolean key;

		int start;

		HashMapEntry entry;

		HashEnumerator(boolean isKey) {
			key= isKey;
			start= firstSlot;
		}

		public boolean hasMoreElements() {
			if (entry != null)
				return true;
			while (start <= lastSlot)
				if (elementData[start++] != null) {
					entry= elementData[start - 1];
					return true;
				}
			return false;
		}

		public Object nextElement() {
			if (hasMoreElements()) {
				Object result= key ? entry.key : entry.value;
				entry= entry.next;
				return result;
			} else
				throw new NoSuchElementException();
		}
	}

	transient int elementCount;

	transient HashMapEntry[] elementData;

	private float loadFactor;

	private int threshold;

	transient int firstSlot= 0;

	transient int lastSlot= - 1;

	transient private IElementComparer comparer;

	private static final EmptyEnumerator emptyEnumerator= new EmptyEnumerator();

	/**
	 * The default capacity used when not specified in the constructor.
	 */
	public static final int DEFAULT_CAPACITY= 13;

	/**
	 * Constructs a new Hashtable using the default capacity and load factor.
	 */
	public CustomHashtable() {
		this(13);
	}

	/**
	 * Constructs a new Hashtable using the specified capacity and the default
	 * load factor.
	 * 
	 * @param capacity the initial capacity
	 */
	public CustomHashtable(int capacity) {
		this(capacity, null);
	}

	/**
	 * Constructs a new hash table with the default capacity and the given
	 * element comparer.
	 * 
	 * @param comparer the element comparer to use to compare keys and obtain
	 *        hash codes for keys, or <code>null</code> to use the normal
	 *        <code>equals</code> and <code>hashCode</code> methods
	 */
	public CustomHashtable(IElementComparer comparer) {
		this(DEFAULT_CAPACITY, comparer);
	}

	/**
	 * Constructs a new hash table with the given capacity and the given element
	 * comparer.
	 * 
	 * @param capacity the maximum number of elements that can be added without
	 *        rehashing
	 * @param comparer the element comparer to use to compare keys and obtain
	 *        hash codes for keys, or <code>null</code> to use the normal
	 *        <code>equals</code> and <code>hashCode</code> methods
	 */
	public CustomHashtable(int capacity, IElementComparer comparer) {
		if (capacity >= 0) {
			elementCount= 0;
			elementData= new HashMapEntry[capacity == 0 ? 1 : capacity];
			firstSlot= elementData.length;
			loadFactor= 0.75f;
			computeMaxSize();
		} else
			throw new IllegalArgumentException();
		this.comparer= comparer;
	}

	/**
	 * Constructs a new hash table with enough capacity to hold all keys in the
	 * given hash table, then adds all key/value pairs in the given hash table
	 * to the new one, using the given element comparer.
	 * 
	 * @param table the original hash table
	 * @param comparer the element comparer to use to compare keys and obtain
	 *        hash codes for keys, or <code>null</code> to use the normal
	 *        <code>equals</code> and <code>hashCode</code> methods
	 */
	public CustomHashtable(CustomHashtable table, IElementComparer comparer) {
		this(table.size() * 2, comparer);
		for (int i= table.elementData.length; --i >= 0;) {
			HashMapEntry entry= table.elementData[i];
			while (entry != null) {
				put(entry.key, entry.value);
				entry= entry.next;
			}
		}
	}

	private void computeMaxSize() {
		threshold= (int) (elementData.length * loadFactor);
	}

	/**
	 * Answers if this Hashtable contains the specified object as a key of one
	 * of the key/value pairs.
	 * 
	 * @param key the object to look for as a key in this Hashtable
	 * @return true if object is a key in this Hashtable, false otherwise
	 */
	public boolean containsKey(Object key) {
		return getEntry(key) != null;
	}

	/**
	 * Answers an Enumeration on the values of this Hashtable. The results of
	 * the Enumeration may be affected if the contents of this Hashtable are
	 * modified.
	 * 
	 * @return an Enumeration of the values of this Hashtable
	 */
	public Enumeration elements() {
		if (elementCount == 0)
			return emptyEnumerator;
		return new HashEnumerator(false);
	}

	/**
	 * Answers the value associated with the specified key in this Hashtable.
	 * 
	 * @param key the key of the value returned
	 * @return the value associated with the specified key, null if the
	 *         specified key does not exist
	 */
	public Object get(Object key) {
		int index= (hashCode(key) & 0x7FFFFFFF) % elementData.length;
		HashMapEntry entry= elementData[index];
		while (entry != null) {
			if (keyEquals(key, entry.key))
				return entry.value;
			entry= entry.next;
		}
		return null;
	}

	/**
	 * Answers the stored key that is equal to the specified key.
	 * 
	 * @param key the key to search
	 * @return the stored key, or null if the specified key does not exist
	 */
	public Object getKey(Object key) {
		int index= (hashCode(key) & 0x7FFFFFFF) % elementData.length;
		HashMapEntry entry= elementData[index];
		while (entry != null) {
			if (keyEquals(key, entry.key))
				return entry.key;
			entry= entry.next;
		}
		return null;
	}

	private HashMapEntry getEntry(Object key) {
		int index= (hashCode(key) & 0x7FFFFFFF) % elementData.length;
		HashMapEntry entry= elementData[index];
		while (entry != null) {
			if (keyEquals(key, entry.key))
				return entry;
			entry= entry.next;
		}
		return null;
	}

	/**
	 * Answers the hash code for the given key.
	 */
	private int hashCode(Object key) {
		if (comparer == null)
			return key.hashCode();
		else
			return comparer.hashCode(key);
	}

	/**
	 * Compares two keys for equality.
	 */
	private boolean keyEquals(Object a, Object b) {
		if (comparer == null)
			return a.equals(b);
		else
			return comparer.equals(a, b);
	}

	/**
	 * Answers an Enumeration on the keys of this Hashtable. The results of the
	 * Enumeration may be affected if the contents of this Hashtable are
	 * modified.
	 * 
	 * @return an Enumeration of the keys of this Hashtable
	 */
	public Enumeration keys() {
		if (elementCount == 0)
			return emptyEnumerator;
		return new HashEnumerator(true);
	}

	/**
	 * Associate the specified value with the specified key in this Hashtable.
	 * If the key already exists, the old value is replaced. The key and value
	 * cannot be null.
	 * 
	 * @param key the key to add
	 * @param value the value to add
	 * @return the old value associated with the specified key, null if the key
	 *         did not exist
	 */
	public Object put(Object key, Object value) {
		if (key != null && value != null) {
			int index= (hashCode(key) & 0x7FFFFFFF) % elementData.length;
			HashMapEntry entry= elementData[index];
			while (entry != null && ! keyEquals(key, entry.key))
				entry= entry.next;
			if (entry == null) {
				if (++elementCount > threshold) {
					rehash();
					index= (hashCode(key) & 0x7FFFFFFF) % elementData.length;
				}
				if (index < firstSlot)
					firstSlot= index;
				if (index > lastSlot)
					lastSlot= index;
				entry= new HashMapEntry(key, value);
				entry.next= elementData[index];
				elementData[index]= entry;
				return null;
			}
			Object result= entry.value;
			entry.key= key; // important to avoid hanging onto keys that are
							// equal but "old" -- see bug 30607
			entry.value= value;
			return result;
		} else
			throw new NullPointerException();
	}

	/**
	 * Increases the capacity of this Hashtable. This method is sent when the
	 * size of this Hashtable exceeds the load factor.
	 */
	private void rehash() {
		int length= elementData.length << 1;
		if (length == 0)
			length= 1;
		firstSlot= length;
		lastSlot= - 1;
		HashMapEntry[] newData= new HashMapEntry[length];
		for (int i= elementData.length; --i >= 0;) {
			HashMapEntry entry= elementData[i];
			while (entry != null) {
				int index= (hashCode(entry.key) & 0x7FFFFFFF) % length;
				if (index < firstSlot)
					firstSlot= index;
				if (index > lastSlot)
					lastSlot= index;
				HashMapEntry next= entry.next;
				entry.next= newData[index];
				newData[index]= entry;
				entry= next;
			}
		}
		elementData= newData;
		computeMaxSize();
	}

	/**
	 * Remove the key/value pair with the specified key from this Hashtable.
	 * 
	 * @param key the key to remove
	 * @return the value associated with the specified key, null if the
	 *         specified key did not exist
	 */
	public Object remove(Object key) {
		HashMapEntry last= null;
		int index= (hashCode(key) & 0x7FFFFFFF) % elementData.length;
		HashMapEntry entry= elementData[index];
		while (entry != null && ! keyEquals(key, entry.key)) {
			last= entry;
			entry= entry.next;
		}
		if (entry != null) {
			if (last == null)
				elementData[index]= entry.next;
			else
				last.next= entry.next;
			elementCount--;
			return entry.value;
		}
		return null;
	}

	/**
	 * Answers the number of key/value pairs in this Hashtable.
	 * 
	 * @return the number of key/value pairs in this Hashtable
	 */
	public int size() {
		return elementCount;
	}

	/**
	 * Answers the string representation of this Hashtable.
	 * 
	 * @return the string representation of this Hashtable
	 */
	public String toString() {
		if (size() == 0)
			return "{}"; //$NON-NLS-1$

		StringBuffer buffer= new StringBuffer();
		buffer.append('{');
		for (int i= elementData.length; --i >= 0;) {
			HashMapEntry entry= elementData[i];
			if (entry != null)
				entry.appendToStringWithCommaNL(buffer);
		}
		// Remove the last ", "
		if (elementCount > 0)
			buffer.setLength(buffer.length() - 2);
		buffer.append('}');
		return buffer.toString();
	}
}
