/*******************************************************************************
 * Copyright (c) 2004, 2005 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jface.bindings;

import org.eclipse.jface.util.Util;

/**
 * <p>
 * A sequence of one or more triggers. None of these triggers may be
 * <code>null</code>.
 * </p>
 * 
 * @since 3.1
 */
public abstract class TriggerSequence {
	
	/**
	 * The value to see that hash code to if the hash code is not yet computed.
	 */
	private static final int HASH_CODE_NOT_COMPUTED = -1;

	/**
	 * A factor for computing the hash code for all trigger sequences.
	 */
	private static final int HASH_FACTOR = 89;

	/**
	 * An internal constant used only in this object's hash code algorithm.
	 */
	private static final int HASH_INITIAL = TriggerSequence.class.getName()
			.hashCode();

	/**
	 * The hash code for this object. This value is computed lazily, and marked
	 * as invalid when one of the values on which it is based changes.  This
	 * values is <code>HASH_CODE_NOT_COMPUTED</code> iff the hash code has not
	 * yet been computed.
	 */
	protected transient int hashCode = HASH_CODE_NOT_COMPUTED;

	/**
	 * The list of trigger in this sequence. This value is never
	 * <code>null</code>, and never contains <code>null</code> elements.
	 */
	protected final Trigger[] triggers;

	/**
	 * Constructs a new instance of <code>TriggerSequence</code>.
	 * 
	 * @param triggers
	 *            The triggers contained within this sequence; must not be
	 *            <code>null</code> or contain <code>null</code> elements.
	 *            May be empty.
	 */
	public TriggerSequence(final Trigger[] triggers) {
		if (triggers == null) {
			throw new NullPointerException("The triggers cannot be null"); //$NON-NLS-1$
		}

		for (int i = 0; i < triggers.length; i++) {
			if (triggers[i] == null) {
				throw new IllegalArgumentException(
						"All triggers in a trigger sequence must be an instance of Trigger"); //$NON-NLS-1$
			}
		}

		final int triggerLength = triggers.length;
		this.triggers = new Trigger[triggerLength];
		System.arraycopy(triggers, 0, this.triggers, 0, triggerLength);
	}

	/**
	 * Returns whether or not this key sequence ends with the given key
	 * sequence.
	 * 
	 * @param triggerSequence
	 *            a trigger sequence. Must not be <code>null</code>.
	 * @param equals
	 *            whether or not an identical trigger sequence should be
	 *            considered as a possible match.
	 * @return <code>true</code>, iff the given trigger sequence ends with
	 *         this trigger sequence.
	 */
	public final boolean endsWith(final TriggerSequence triggerSequence,
			final boolean equals) {
		if (triggerSequence == null) {
			throw new NullPointerException(
					"Cannot end with a null trigger sequence"); //$NON-NLS-1$
		}

		return Util.endsWith(triggers, triggerSequence.triggers, equals);
	}

	public final boolean equals(final Object object) {
		// Check if they're the same.
		if (object == this) {
			return true;
		}

		// Check if they're the same type.
		if (!(object instanceof TriggerSequence))
			return false;

		final TriggerSequence triggerSequence = (TriggerSequence) object;
		return Util.equals(triggers, triggerSequence.triggers);
	}

	/**
	 * Formats this trigger sequence into the current default look.
	 * 
	 * @return A string representation for this trigger sequence using the
	 *         default look; never <code>null</code>.
	 */
	public abstract String format();

	/**
	 * <p>
	 * Returns a list of prefixes for the current sequence. A prefix is any
	 * leading subsequence in a <code>TriggerSequence</code>. A prefix is
	 * also an instance of <code>TriggerSequence</code>.
	 * </p>
	 * <p>
	 * For example, consider a trigger sequence that consists of four triggers:
	 * A, B, C and D. The prefixes would be "", "A", "A B", and "A B C". The
	 * list of prefixes must always be the same as the size of the trigger list.
	 * </p>
	 * 
	 * @return The array of possible prefixes for this sequence. This array must
	 *         not be <code>null</code>, but may be empty. It must only
	 *         contains instances of <code>TriggerSequence</code>.
	 */
	public abstract TriggerSequence[] getPrefixes();

	/**
	 * Returns the list of triggers.
	 * 
	 * @return The triggers; never <code>null</code> and guaranteed to only
	 *         contain instances of <code>Trigger</code>.
	 */
	public final Trigger[] getTriggers() {
		final int triggerLength = triggers.length;
		final Trigger[] triggerCopy = new Trigger[triggerLength];
		System.arraycopy(triggers, 0, triggerCopy, 0, triggerLength);
		return triggerCopy;
	}

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#hashCode()
	 */
	public final int hashCode() {
		if (hashCode == HASH_CODE_NOT_COMPUTED) {
			hashCode = HASH_INITIAL;
			hashCode = hashCode * HASH_FACTOR + Util.hashCode(triggers);
			if (hashCode == HASH_CODE_NOT_COMPUTED) {
				hashCode++;
			}
		}

		return hashCode;
	}

	/**
	 * Returns whether or not this trigger sequence is empty.
	 * 
	 * @return <code>true</code>, iff the trigger sequence is empty.
	 */
	public final boolean isEmpty() {
		return (triggers.length == 0);
	}

	/**
	 * Returns whether or not this trigger sequence starts with the given
	 * trigger sequence.
	 * 
	 * @param triggerSequence
	 *            a trigger sequence. Must not be <code>null</code>.
	 * @param equals
	 *            whether or not an identical trigger sequence should be
	 *            considered as a possible match.
	 * @return <code>true</code>, iff the given trigger sequence starts with
	 *         this key sequence.
	 */
	public final boolean startsWith(final TriggerSequence triggerSequence,
			final boolean equals) {
		if (triggerSequence == null)
			throw new NullPointerException(
					"A trigger sequence cannot start with null"); //$NON-NLS-1$

		return Util.startsWith(triggers, triggerSequence.triggers, equals);
	}
}
