/*******************************************************************************
 * 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.keys;

import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import org.eclipse.jface.bindings.TriggerSequence;
import org.eclipse.jface.bindings.keys.formatting.KeyFormatterFactory;
import org.eclipse.jface.util.Util;

/**
 * <p>
 * A <code>KeySequence</code> is defined as a list of zero or more
 * <code>KeyStrokes</code>, with the stipulation that all
 * <code>KeyStroke</code> objects must be complete, save for the last one,
 * whose completeness is optional. A <code>KeySequence</code> is said to be
 * complete if all of its <code>KeyStroke</code> objects are complete.
 * </p>
 * <p>
 * All <code>KeySequence</code> objects have a formal string representation
 * available via the <code>toString()</code> method. There are a number of
 * methods to get instances of <code>KeySequence</code> objects, including one
 * which can parse this formal string representation.
 * </p>
 * <p>
 * All <code>KeySequence</code> objects, via the <code>format()</code>
 * method, provide a version of their formal string representation translated by
 * platform and locale, suitable for display to a user.
 * </p>
 * <p>
 * <code>KeySequence</code> objects are immutable. Clients are not permitted
 * to extend this class.
 * </p>
 * 
 * @since 3.1
 */
public final class KeySequence extends TriggerSequence implements Comparable {

	/**
	 * An empty key sequence instance for use by everyone.
	 */
	private final static KeySequence EMPTY_KEY_SEQUENCE = new KeySequence(
			new KeyStroke[0]);

	/**
	 * The delimiter between multiple key strokes in a single key sequence --
	 * expressed in the formal key stroke grammar. This is not to be displayed
	 * to the user. It is only intended as an internal representation.
	 */
	public final static String KEY_STROKE_DELIMITER = "\u0020"; //$NON-NLS-1$

	/**
	 * The set of delimiters for <code>KeyStroke</code> objects allowed during
	 * parsing of the formal string representation.
	 */
	public final static String KEY_STROKE_DELIMITERS = KEY_STROKE_DELIMITER
			+ "\b\r\u007F\u001B\f\n\0\t\u000B"; //$NON-NLS-1$

	/**
	 * Gets an instance of <code>KeySequence</code>.
	 * 
	 * @return a key sequence. This key sequence will have no key strokes.
	 *         Guaranteed not to be <code>null</code>.
	 */
	public static final KeySequence getInstance() {
		return EMPTY_KEY_SEQUENCE;
	}

	/**
	 * Creates an instance of <code>KeySequence</code> given a key sequence
	 * and a key stroke.
	 * 
	 * @param keySequence
	 *            a key sequence. Must not be <code>null</code>.
	 * @param keyStroke
	 *            a key stroke. Must not be <code>null</code>.
	 * @return a key sequence that is equal to the given key sequence with the
	 *         given key stroke appended to the end. Guaranteed not to be
	 *         <code>null</code>.
	 */
	public static final KeySequence getInstance(final KeySequence keySequence,
			final KeyStroke keyStroke) {
		if (keySequence == null || keyStroke == null)
			throw new NullPointerException();

		final KeyStroke[] oldKeyStrokes = keySequence.getKeyStrokes();
		final int oldKeyStrokeLength = oldKeyStrokes.length;
		final KeyStroke[] newKeyStrokes = new KeyStroke[oldKeyStrokeLength + 1];
		System
				.arraycopy(oldKeyStrokes, 0, newKeyStrokes, 0,
						oldKeyStrokeLength);
		newKeyStrokes[oldKeyStrokeLength] = keyStroke;
		return new KeySequence(newKeyStrokes);
	}

	/**
	 * Creates an instance of <code>KeySequence</code> given a single key
	 * stroke.
	 * 
	 * @param keyStroke
	 *            a single key stroke. Must not be <code>null</code>.
	 * @return a key sequence. Guaranteed not to be <code>null</code>.
	 */
	public static final KeySequence getInstance(final KeyStroke keyStroke) {
		return new KeySequence(new KeyStroke[] { keyStroke });
	}

	/**
	 * Creates an instance of <code>KeySequence</code> given an array of key
	 * strokes.
	 * 
	 * @param keyStrokes
	 *            the array of key strokes. This array may be empty, but it must
	 *            not be <code>null</code>. This array must not contain
	 *            <code>null</code> elements.
	 * @return a key sequence. Guaranteed not to be <code>null</code>.
	 */
	public static final KeySequence getInstance(final KeyStroke[] keyStrokes) {
		return new KeySequence(keyStrokes);
	}

	/**
	 * Creates an instance of <code>KeySequence</code> given a list of key
	 * strokes.
	 * 
	 * @param keyStrokes
	 *            the list of key strokes. This list may be empty, but it must
	 *            not be <code>null</code>. If this list is not empty, it
	 *            must only contain instances of <code>KeyStroke</code>.
	 * @return a key sequence. Guaranteed not to be <code>null</code>.
	 */
	public static final KeySequence getInstance(final List keyStrokes) {
		return new KeySequence((KeyStroke[]) keyStrokes
				.toArray(new KeyStroke[keyStrokes.size()]));
	}

	/**
	 * Creates an instance of <code>KeySequence</code> by parsing a given
	 * formal string representation.
	 * 
	 * @param string
	 *            the formal string representation to parse.
	 * @return a key sequence. Guaranteed not to be <code>null</code>.
	 * @throws ParseException
	 *             if the given formal string representation could not be parsed
	 *             to a valid key sequence.
	 */
	public static final KeySequence getInstance(final String string)
			throws ParseException {
		if (string == null)
			throw new NullPointerException();

		final List keyStrokes = new ArrayList();
		final StringTokenizer stringTokenizer = new StringTokenizer(string,
				KEY_STROKE_DELIMITERS);

		try {
			while (stringTokenizer.hasMoreTokens())
				keyStrokes.add(KeyStroke.getInstance(stringTokenizer
						.nextToken()));

			final KeyStroke[] keyStrokeArray = (KeyStroke[]) keyStrokes
					.toArray(new KeyStroke[keyStrokes.size()]);
			return new KeySequence(keyStrokeArray);
		} catch (final IllegalArgumentException e) {
			throw new ParseException(
					"Could not construct key sequence with these key strokes: " //$NON-NLS-1$
							+ keyStrokes);
		} catch (final NullPointerException e) {
			throw new ParseException(
					"Could not construct key sequence with these key strokes: " //$NON-NLS-1$
							+ keyStrokes);
		}
	}

	/**
	 * Constructs an instance of <code>KeySequence</code> given a list of key
	 * strokes.
	 * 
	 * @param keyStrokes
	 *            the list of key strokes. This list may be empty, but it must
	 *            not be <code>null</code>. If this list is not empty, it
	 *            must only contain instances of <code>KeyStroke</code>.
	 */
	protected KeySequence(final KeyStroke[] keyStrokes) {
		super(keyStrokes);

		for (int i = 0; i < triggers.length - 1; i++) {
			KeyStroke keyStroke = (KeyStroke) triggers[i];

			if (!keyStroke.isComplete())
				throw new IllegalArgumentException();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#compareTo(java.lang.Object)
	 */
	public final int compareTo(final Object object) {
		final KeySequence castedObject = (KeySequence) object;
		return Util.compare(triggers, castedObject.triggers);
	}

	/**
	 * Formats this key sequence into the current default look.
	 * 
	 * @return A string representation for this key sequence using the default
	 *         look; never <code>null</code>.
	 */
	public final String format() {
		return KeyFormatterFactory.getDefault().format(this);
	}

	/**
	 * Returns the list of key strokes for this key sequence.
	 * 
	 * @return the list of key strokes keys. This list may be empty, but is
	 *         guaranteed not to be <code>null</code>. If this list is not
	 *         empty, it is guaranteed to only contain instances of
	 *         <code>KeyStroke</code>.
	 */
	public final KeyStroke[] getKeyStrokes() {
		final int triggerLength = triggers.length;
		final KeyStroke[] keyStrokes = new KeyStroke[triggerLength];
		System.arraycopy(triggers, 0, keyStrokes, 0, triggerLength);
		return keyStrokes;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.bindings.TriggerSequence#getPrefixes()
	 */
	public final TriggerSequence[] getPrefixes() {
		final int numberOfPrefixes = triggers.length;
		final TriggerSequence[] prefixes = new TriggerSequence[numberOfPrefixes];
		prefixes[0] = KeySequence.getInstance();
		for (int i = 0; i < numberOfPrefixes - 1; i++) {
			final KeyStroke[] prefixKeyStrokes = new KeyStroke[i + 1];
			System.arraycopy(triggers, 0, prefixKeyStrokes, 0, i + 1);
			prefixes[i + 1] = KeySequence.getInstance(prefixKeyStrokes);
		}

		return prefixes;
	}

	/**
	 * Returns whether or not this key sequence is complete. Key sequences are
	 * complete iff all of their key strokes are complete.
	 * 
	 * @return <code>true</code>, iff the key sequence is complete.
	 */
	public final boolean isComplete() {
		final int triggersLength = triggers.length;
		for (int i = 0; i < triggersLength; i++) {
			if (!((KeyStroke) triggers[i]).isComplete()) {
				return false;
			}
		}

		return true;
	}

	/**
	 * Returns the formal string representation for this key sequence.
	 * 
	 * @return The formal string representation for this key sequence.
	 *         Guaranteed not to be <code>null</code>.
	 * @see java.lang.Object#toString()
	 */
	public final String toString() {
		return KeyFormatterFactory.getFormalKeyFormatter().format(this);
	}
}
