package org.eclipse.debug.internal.core;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */

/**
 * Local version of org.eclipse.jface.util.ListenerList (modified)s
 */
public class ListenerList {
	/**
	 * The current number of listeners.
	 * Maintains invariant: 0 <= fSize <= listeners.length.
	 */
	private int fSize;

	/**
	 * The list of listeners.  Initially <code>null</code> but initialized
	 * to an array of size capacity the first time a listener is added.
	 * Maintains invariant: listeners != null if and only if fSize != 0
	 */
	private Object[] fListeners= null;

	/**
	 * The empty array singleton instance, returned by getListeners()
	 * when size == 0.
	 */
	private static final Object[] EmptyArray= new Object[0];

	/**
	 * Creates a listener list with the given initial capacity.
	 *
	 * @param capacity the number of listeners which this list can initially accept 
	 *    without growing its internal representation; must be at least 1
	 */
	public ListenerList(int capacity) {
		if (capacity < 1) {
			throw new IllegalArgumentException();
		}
		fListeners= new Object[capacity];
		fSize= 0;
	}

	/**
	 * Adds a listener to the list.
	 * Has no effect if an identical listener is already registered.
	 *
	 * @param listener a listener
	 */
	public synchronized void add(Object listener) {
		if (listener == null) {
			throw new IllegalArgumentException();
		}
		// check for duplicates using identity
		for (int i= 0; i < fSize; ++i) {
			if (fListeners[i] == listener) {
				return;
			}
		}
		// grow array if necessary
		if (fSize == fListeners.length) {
			Object[] temp= new Object[(fSize * 2) + 1];
			System.arraycopy(fListeners, 0, temp, 0, fSize);
			fListeners= temp;
		}
		fListeners[fSize++]= listener;
	}

	/**
	 * Returns an array containing all the registered listeners.
	 * The resulting array is unaffected by subsequent adds or removes.
	 * If there are no listeners registered, the result is an empty array
	 * singleton instance (no garbage is created).
	 * Use this method when notifying listeners, so that any modifications
	 * to the listener list during the notification will have no effect on the
	 * notification itself.
	 */
	public synchronized Object[] getListeners() {
		if (fSize == 0) {
			return EmptyArray;
		}
		Object[] result= new Object[fSize];
		System.arraycopy(fListeners, 0, result, 0, fSize);
		return result;
	}

	/**
	 * Removes a listener from the list.
	 * Has no effect if an identical listener was not already registered.
	 *
	 * @param listener a listener
	 */
	public synchronized void remove(Object listener) {
		if (listener == null) {
			throw new IllegalArgumentException();
		}

		for (int i= 0; i < fSize; ++i) {
			if (fListeners[i] == listener) {
				if (--fSize == 0) {
					fListeners= new Object[1];
				} else {
					if (i < fSize) {
						fListeners[i]= fListeners[fSize];
					}
					fListeners[fSize]= null;
				}
				return;
			}
		}
	}

	/**
	 * Removes all the listeners from the list.
	 */
	public void removeAll() {
		fListeners= new Object[0];
		fSize= 0;
	}

	/**
	 * Returns the number of registered listeners
	 *
	 * @return the number of registered listeners
	 */
	public int size() {
		return fSize;
	}
}

