/*******************************************************************************
 * Copyright (c) 2000, 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.ui.keys;

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

import org.eclipse.ui.internal.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>
 * 
 * @deprecated Please use org.eclipse.jface.bindings.keys.KeySequence
 * @since 3.0
 */
public final class KeySequence implements Comparable {

    /**
     * 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$

    /**
     * An empty key sequence instance for use by everyone.
     */
    private final static KeySequence EMPTY_KEY_SEQUENCE = new KeySequence(
            Collections.EMPTY_LIST);

    /**
     * An internal constant used only in this object's hash code algorithm.
     */
    private final static int HASH_FACTOR = 89;

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

    /**
     * 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 KeySequence getInstance() {
        return EMPTY_KEY_SEQUENCE;
    }

    /**
     * Gets 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 KeySequence getInstance(KeySequence keySequence,
            KeyStroke keyStroke) {
        if (keySequence == null || keyStroke == null) {
			throw new NullPointerException();
		}

        List keyStrokes = new ArrayList(keySequence.getKeyStrokes());
        keyStrokes.add(keyStroke);
        return new KeySequence(keyStrokes);
    }

    /**
     * Gets 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 KeySequence getInstance(KeyStroke keyStroke) {
        return new KeySequence(Collections.singletonList(keyStroke));
    }

    /**
     * Gets 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 KeySequence getInstance(KeyStroke[] keyStrokes) {
        return new KeySequence(Arrays.asList(keyStrokes));
    }

    /**
     * Gets 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 KeySequence getInstance(List keyStrokes) {
        return new KeySequence(keyStrokes);
    }
	
	/**
	 * Gets an instance of <code>KeySequence</code> given a new-style key
	 * sequence.
	 * 
	 * @param newKeySequence
	 *            The new-style key sequence to convert into a legacy key
	 *            sequence; must not be <code>null</code>.
	 * @return a key sequence; never <code>null</code>.
	 */
	public static final KeySequence getInstance(
			final org.eclipse.jface.bindings.keys.KeySequence newKeySequence) {
		final org.eclipse.jface.bindings.keys.KeyStroke[] newKeyStrokes = newKeySequence
				.getKeyStrokes();
		final int newKeyStrokesCount = newKeyStrokes.length;
		final List legacyKeyStrokes = new ArrayList(newKeyStrokesCount);

		for (int i = 0; i < newKeyStrokesCount; i++) {
			final org.eclipse.jface.bindings.keys.KeyStroke newKeyStroke = newKeyStrokes[i];
			legacyKeyStrokes.add(SWTKeySupport
					.convertAcceleratorToKeyStroke(newKeyStroke
							.getModifierKeys()
							| newKeyStroke.getNaturalKey()));
		}
		
		return new KeySequence(legacyKeyStrokes);
	}

    /**
     * Gets an instance of <code>KeySequence</code> by parsing a given a
     * 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 KeySequence getInstance(String string) throws ParseException {
        if (string == null) {
			throw new NullPointerException();
		}

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

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

        try {
            return new KeySequence(keyStrokes);
        } catch (Throwable t) {
            throw new ParseException(
                    "Could not construct key sequence with these key strokes: " //$NON-NLS-1$
                            + keyStrokes);
        }
    }

    /**
     * The cached hash code for this object. Because <code>KeySequence</code>
     * objects are immutable, their hash codes need only to be computed once.
     * After the first call to <code>hashCode()</code>, the computed value
     * is cached here for all subsequent calls.
     */
    private transient int hashCode;

    /**
     * A flag to determine if the <code>hashCode</code> field has already
     * been computed.
     */
    private transient boolean hashCodeComputed;

    /**
     * The list of key strokes for this key sequence.
     */
    private List 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>.
     */
    private KeySequence(List keyStrokes) {
        this.keyStrokes = Util.safeCopy(keyStrokes, KeyStroke.class);

        for (int i = 0; i < this.keyStrokes.size() - 1; i++) {
            KeyStroke keyStroke = (KeyStroke) this.keyStrokes.get(i);

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

    /**
     * @see java.lang.Object#equals(java.lang.Object)
     */
    public int compareTo(Object object) {
        KeySequence castedObject = (KeySequence) object;
        int compareTo = Util.compare(keyStrokes, castedObject.keyStrokes);
        return compareTo;
    }

    /**
     * Returns whether or not this key sequence ends with the given key
     * sequence.
     * 
     * @param keySequence
     *            a key sequence. Must not be <code>null</code>.
     * @param equals
     *            whether or not an identical key sequence should be considered
     *            as a possible match.
     * @return <code>true</code>, iff the given key sequence ends with this
     *         key sequence.
     */
    public boolean endsWith(KeySequence keySequence, boolean equals) {
        if (keySequence == null) {
			throw new NullPointerException();
		}

        return Util.endsWith(keyStrokes, keySequence.keyStrokes, equals);
    }

    /**
     * @see java.lang.Object#equals(java.lang.Object)
     */
    public boolean equals(Object object) {
        if (!(object instanceof KeySequence)) {
			return false;
		}

        return keyStrokes.equals(((KeySequence) object).keyStrokes);
    }

    /**
     * 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 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 List getKeyStrokes() {
        return keyStrokes;
    }

    /**
     * @see java.lang.Object#hashCode()
     */
    public int hashCode() {
        if (!hashCodeComputed) {
            hashCode = HASH_INITIAL;
            hashCode = hashCode * HASH_FACTOR + keyStrokes.hashCode();
            hashCodeComputed = true;
        }

        return hashCode;
    }

    /**
     * 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 boolean isComplete() {
        return keyStrokes.isEmpty()
                || ((KeyStroke) keyStrokes.get(keyStrokes.size() - 1))
                        .isComplete();
    }

    /**
     * Returns whether or not this key sequence is empty. Key sequences are
     * complete iff they have no key strokes.
     * 
     * @return <code>true</code>, iff the key sequence is empty.
     */
    public boolean isEmpty() {
        return keyStrokes.isEmpty();
    }

    /**
     * Returns whether or not this key sequence starts with the given key
     * sequence.
     * 
     * @param keySequence
     *            a key sequence. Must not be <code>null</code>.
     * @param equals
     *            whether or not an identical key sequence should be considered
     *            as a possible match.
     * @return <code>true</code>, iff the given key sequence starts with
     *         this key sequence.
     */
    public boolean startsWith(KeySequence keySequence, boolean equals) {
        if (keySequence == null) {
			throw new NullPointerException();
		}

        return Util.startsWith(keyStrokes, keySequence.keyStrokes, equals);
    }

    /**
     * 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 String toString() {
        return KeyFormatterFactory.getFormalKeyFormatter().format(this);
    }
}
