/*******************************************************************************
 * Copyright (c) 2004, 2008 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.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.TreeSet;

import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;

/**
 * <p>
 * A wrapper around the SWT text widget that traps literal key presses and
 * converts them into key sequences for display. There are two types of key
 * strokes that are displayed: complete and incomplete. A complete key stroke is
 * one with a natural key, while an incomplete one has no natural key.
 * Incomplete key strokes are only displayed until they are made complete or
 * their component key presses are released.
 * </p>
 * 
 * @since 3.1
 */
public final class KeySequenceText {

	/**
	 * A key listener that traps incoming events and displays them in the
	 * wrapped text field. It has no effect on traversal operations.
	 */
	private class KeyTrapListener implements Listener {
		/**
		 * The index at which insertion should occur. This is used if there is a
		 * replacement occurring in the middle of the stroke, and the first key
		 * stroke was incomplete.
		 */
		private int insertionIndex = -1;

		/**
		 * Resets the insertion index to point nowhere. In other words, it is
		 * set to <code>-1</code>.
		 */
		void clearInsertionIndex() {
			insertionIndex = -1;
		}

		/**
		 * Deletes the current selection. If there is no selection, then it
		 * deletes the last key stroke.
		 * 
		 * @param keyStrokes
		 *            The key strokes from which to delete. This list must not
		 *            be <code>null</code>, and must represent a valid key
		 *            sequence.
		 * @return An array of keystrokes minus the keystrokes that were
		 *         deleted.
		 */
		private final KeyStroke[] deleteKeyStroke(final KeyStroke[] keyStrokes) {
			clearInsertionIndex();

			if (hasSelection()) {
				/*
				 * Delete the current selection -- disallowing incomplete
				 * strokes in the middle of the sequence.
				 */
				final KeyStroke[][] deletedKeyStrokes = new KeyStroke[1][];
				deleteSelection(keyStrokes, false, deletedKeyStrokes);
				return deletedKeyStrokes[0];
			}

			// Remove the last key stroke.
			if (keyStrokes.length > 0) {
				final int newKeyStrokesLength = keyStrokes.length - 1;
				final KeyStroke[] newKeyStrokes = new KeyStroke[newKeyStrokesLength];
				System.arraycopy(keyStrokes, 0, newKeyStrokes, 0,
						newKeyStrokesLength);
				return newKeyStrokes;
			}

			return keyStrokes;
		}

		/**
		 * Handles the key pressed and released events on the wrapped text
		 * widget. This makes sure to either add the pressed key to the
		 * temporary key stroke, or complete the current temporary key stroke
		 * and prompt for the next. In the case of a key release, this makes
		 * sure that the temporary stroke is correctly displayed --
		 * corresponding with modifier keys that may have been released.
		 * 
		 * @param event
		 *            The triggering event; must not be <code>null</code>.
		 */
		public void handleEvent(Event event) {
			KeyStroke[] keyStrokes = getKeySequence().getKeyStrokes();

			// Dispatch the event to the correct handler.
			if (event.type == SWT.KeyDown) {
				keyStrokes = handleKeyDown(event, keyStrokes);
			} else if (event.type == SWT.KeyUp) {
				keyStrokes = handleKeyUp(event, keyStrokes);
			}

			// Update the underlying widget.
			setKeySequence(KeySequence.getInstance(keyStrokes));

			// Prevent the event from reaching the widget.
			event.doit = false;
		}

		/**
		 * Handles the case where the key event is an <code>SWT.KeyDown</code>
		 * event. This either causes a deletion (if it is an unmodified
		 * backspace key stroke), or an insertion (if it is any other key).
		 * 
		 * @param event
		 *            The trigger key down event; must not be <code>null</code>.
		 * @param keyStrokes
		 *            The current list of key strokes. This valud must not be
		 *            <code>null</code>, and it must represent a valid key
		 *            sequence.
		 */
		private KeyStroke[] handleKeyDown(Event event, KeyStroke[] keyStrokes) {
			// Is it an unmodified backspace character?
			if ((event.character == SWT.BS || event.character == SWT.DEL) && (event.stateMask == 0)) {
				return deleteKeyStroke(keyStrokes);
			}

			return insertKeyStroke(event, keyStrokes);
		}

		/**
		 * Handles the case where the key event is an <code>SWT.KeyUp</code>
		 * event. This resets the insertion index. If there is an incomplete
		 * stroke, then that incomplete stroke is modified to match the keys
		 * that are still held. If no keys are held, then the incomplete stroke
		 * is removed.
		 * 
		 * @param event
		 *            The triggering event; must not be <code>null</code>
		 * @param keyStrokes
		 *            The key strokes that are part of the current key sequence;
		 *            these key strokes are guaranteed to represent a valid key
		 *            sequence. This value must not be <code>null</code>.
		 */
		private final KeyStroke[] handleKeyUp(final Event event,
				final KeyStroke[] keyStrokes) {
			if (hasIncompleteStroke()) {
				/*
				 * Figure out the SWT integer representation of the remaining
				 * values.
				 */
				Event mockEvent = new Event();
				if ((event.keyCode & SWT.MODIFIER_MASK) != 0) {
					// This key up is a modifier key being released.
					mockEvent.stateMask = event.stateMask - event.keyCode;
				} else {
					/*
					 * This key up is the other end of a key down that was
					 * trapped by the operating system or window manager.
					 */
					mockEvent.stateMask = event.stateMask;
				}

				/*
				 * Get a reasonable facsimile of the stroke that is still
				 * pressed.
				 */
				int key = SWTKeySupport
						.convertEventToUnmodifiedAccelerator(mockEvent);
				KeyStroke remainingStroke = SWTKeySupport
						.convertAcceleratorToKeyStroke(key);
				final int keyStrokesLength = keyStrokes.length;
				final KeyStroke[] newKeyStrokes;
				if ((keyStrokesLength > 0)
						&& (remainingStroke.getModifierKeys() != 0)) {
					newKeyStrokes = new KeyStroke[keyStrokesLength];
					System.arraycopy(keyStrokes, 0, newKeyStrokes, 0,
							keyStrokesLength - 1);
					newKeyStrokes[keyStrokesLength - 1] = remainingStroke;

				} else if (keyStrokesLength > 0) {
					newKeyStrokes = new KeyStroke[keyStrokesLength - 1];
					System.arraycopy(keyStrokes, 0, newKeyStrokes, 0,
							keyStrokesLength - 1);

				} else if (remainingStroke.getModifierKeys() != 0) {
					newKeyStrokes = new KeyStroke[keyStrokesLength + 1];
					System.arraycopy(keyStrokes, 0, newKeyStrokes, 0,
							keyStrokesLength);
					newKeyStrokes[keyStrokesLength] = remainingStroke;

				} else {
					newKeyStrokes = keyStrokes;

				}

				return newKeyStrokes;
			}

			return keyStrokes;
		}

		/**
		 * <p>
		 * Handles the case where a key down event is leading to a key stroke
		 * being inserted. The current selection is deleted, and an invalid
		 * remanents of the stroke are also removed. The insertion is carried
		 * out at the cursor position.
		 * </p>
		 * <p>
		 * If only a natural key is selected (as part of a larger key stroke),
		 * then it is possible for the user to press a natural key to replace
		 * the old natural key. In this situation, pressing any modifier keys
		 * will replace the whole thing.
		 * </p>
		 * <p>
		 * If the insertion point is not at the end of the sequence, then
		 * incomplete strokes will not be immediately inserted. Only when the
		 * sequence is completed is the stroke inserted. This is a requirement
		 * as the widget must always represent a valid key sequence. The
		 * insertion point is tracked using <code>insertionIndex</code>,
		 * which is an index into the key stroke array.
		 * </p>
		 * 
		 * @param event
		 *            The triggering key down event; must not be
		 *            <code>null</code>.
		 * @param keyStrokes
		 *            The key strokes into which the current stroke should be
		 *            inserted. This value must not be <code>null</code>, and
		 *            must represent a valid key sequence.
		 */
		private final KeyStroke[] insertKeyStroke(final Event event,
				KeyStroke[] keyStrokes) {
			// Compute the key stroke to insert.
			int key = SWTKeySupport.convertEventToUnmodifiedAccelerator(event);
			KeyStroke stroke = SWTKeySupport.convertAcceleratorToKeyStroke(key);

			/*
			 * Only insert the stroke if it is *not ScrollLock. Let's not get
			 * silly
			 */
			if ((SWT.NUM_LOCK == stroke.getNaturalKey())
					|| (SWT.CAPS_LOCK == stroke.getNaturalKey())
					|| (SWT.SCROLL_LOCK == stroke.getNaturalKey())) {
				return keyStrokes;
			}

			if (insertionIndex != -1) {
				// There is a previous replacement still going on.
				if (stroke.isComplete()) {
					keyStrokes = insertStrokeAt(keyStrokes, stroke,
							insertionIndex);
					clearInsertionIndex();
				}

			} else if (hasSelection()) {
				// There is a selection that needs to be replaced.
				final KeyStroke[][] deletedKeyStrokes = new KeyStroke[1][];
				insertionIndex = deleteSelection(keyStrokes, stroke
						.isComplete(), deletedKeyStrokes);
				keyStrokes = deletedKeyStrokes[0];
				if ((stroke.isComplete())
						|| (insertionIndex >= keyStrokes.length)) {
					keyStrokes = insertStrokeAt(keyStrokes, stroke,
							insertionIndex);
					clearInsertionIndex();
				}

			} else {
				// No selection, so remove the incomplete stroke, if any
				if ((hasIncompleteStroke()) && (keyStrokes.length > 0)) {
					final KeyStroke[] newKeyStrokes = new KeyStroke[keyStrokes.length - 1];
					System.arraycopy(keyStrokes, 0, newKeyStrokes, 0,
							keyStrokes.length - 1);
					keyStrokes = newKeyStrokes;
				}

				// And then add the new stroke.
				if ((keyStrokes.length == 0)
						|| (insertionIndex >= keyStrokes.length)
						|| (isCursorInLastPosition())) {
					keyStrokes = insertStrokeAt(keyStrokes, stroke,
							keyStrokes.length);
					clearInsertionIndex();
				} else {
					/*
					 * I'm just getting the insertionIndex here. No actual
					 * deletion should occur.
					 */
					final KeyStroke[][] deletedKeyStrokes = new KeyStroke[1][];
					insertionIndex = deleteSelection(keyStrokes, stroke
							.isComplete(), deletedKeyStrokes);
					keyStrokes = deletedKeyStrokes[0];
					if (stroke.isComplete()) {
						keyStrokes = insertStrokeAt(keyStrokes, stroke,
								insertionIndex);
						clearInsertionIndex();
					}
				}

			}

			return keyStrokes;
		}
	}

	/**
	 * A traversal listener that blocks all traversal except for tabs and arrow
	 * keys.
	 */
	private class TraversalFilter implements Listener {
		/**
		 * Handles the traverse event on the text field wrapped by this class.
		 * It swallows all traverse events example for tab and arrow key
		 * navigation. The other forms of navigation can be reached by tabbing
		 * off of the control.
		 * 
		 * @param event
		 *            The trigger event; must not be <code>null</code>.
		 */
		public void handleEvent(Event event) {
			switch (event.detail) {
			case SWT.TRAVERSE_ESCAPE:
			case SWT.TRAVERSE_MNEMONIC:
			case SWT.TRAVERSE_NONE:
			case SWT.TRAVERSE_PAGE_NEXT:
			case SWT.TRAVERSE_PAGE_PREVIOUS:
			case SWT.TRAVERSE_RETURN:
				event.type = SWT.None;
				event.doit = false;
				break;

			case SWT.TRAVERSE_TAB_NEXT:
			case SWT.TRAVERSE_TAB_PREVIOUS:
				// Check if modifiers other than just 'Shift' were
				// down.
				if ((event.stateMask & (SWT.MODIFIER_MASK ^ SWT.SHIFT)) != 0) {
					// Modifiers other than shift were down.
					event.type = SWT.None;
					event.doit = false;
					break;
				}

				// fall through -- either no modifiers, or just shift.

			case SWT.TRAVERSE_ARROW_NEXT:
			case SWT.TRAVERSE_ARROW_PREVIOUS:
			default:
				// Let the traversal happen, but clear the incomplete
				// stroke
				if (hasIncompleteStroke()) {
					final KeyStroke[] oldKeyStrokes = getKeySequence()
							.getKeyStrokes();
					final int newKeyStrokesLength = oldKeyStrokes.length - 1;
					if (newKeyStrokesLength >= 1) {
						final KeyStroke[] newKeyStrokes = new KeyStroke[newKeyStrokesLength];
						System.arraycopy(oldKeyStrokes, 0, newKeyStrokes, 0,
								newKeyStrokesLength);
						setKeySequence(KeySequence.getInstance(newKeyStrokes));
					} else {
						setKeySequence(KeySequence.getInstance());
					}
				}
			}

		}
	}

	/**
	 * The manager resposible for installing and removing the traversal filter
	 * when the key sequence entry widget gains and loses focus.
	 */
	private class TraversalFilterManager implements FocusListener {
		/** The managed filter. We only need one instance. */
		private TraversalFilter filter = new TraversalFilter();
		
		private boolean filtering = false;

		/**
		 * Attaches the global traversal filter.
		 * 
		 * @param event
		 *            Ignored.
		 */
		public void focusGained(FocusEvent event) {
			Display.getCurrent().addFilter(SWT.Traverse, filter);
			filtering = true;
		}

		/**
		 * Detaches the global traversal filter.
		 * 
		 * @param event
		 *            Ignored.
		 */
		public void focusLost(FocusEvent event) {
			Display.getCurrent().removeFilter(SWT.Traverse, filter);
			filtering = false;
		}
		
		/**
		 * Remove the traverse filter if we close without focusOut.
		 */
		public void dispose() {
			if (filtering) {
				Display.getCurrent().removeFilter(SWT.Traverse, filter);
			}
		}
	}

	/**
	 * A modification listener that makes sure that external events to this
	 * class (i.e., direct modification of the underlying text) do not break
	 * this class' view of the world.
	 */
	private class UpdateSequenceListener implements ModifyListener {
		/**
		 * Handles the modify event on the underlying text widget.
		 * 
		 * @param event
		 *            The triggering event; ignored.
		 */
		public void modifyText(ModifyEvent event) {
			try {
				// The original sequence.
				KeySequence originalSequence = getKeySequence();

				// The new sequence drawn from the text.
				String contents = getText();
				KeySequence newSequence = KeySequence.getInstance(contents);

				// Check to see if they're the same.
				if (!originalSequence.equals(newSequence)) {
					setKeySequence(newSequence);
				}

			} catch (ParseException e) {
				// Abort any cut/paste-driven modifications
				setKeySequence(getKeySequence());
			}
		}
	}

	static {
		TreeSet trappedKeys = new TreeSet();
		trappedKeys.add(SWTKeySupport.convertAcceleratorToKeyStroke(SWT.TAB));
		trappedKeys.add(SWTKeySupport.convertAcceleratorToKeyStroke(SWT.TAB
				| SWT.SHIFT));
		trappedKeys.add(SWTKeySupport.convertAcceleratorToKeyStroke(SWT.BS));
		List trappedKeyList = new ArrayList(trappedKeys);
		TRAPPED_KEYS = Collections.unmodifiableList(trappedKeyList);
	}

	/** An empty string instance for use in clearing text values. */
	private static final String EMPTY_STRING = ""; //$NON-NLS-1$

	/**
	 * The special integer value for the maximum number of strokes indicating
	 * that an infinite number should be allowed.
	 */
	public static final int INFINITE = -1;

	/**
	 * The name of the property representing the current key sequence in this
	 * key sequence widget.
	 * 
	 * @since 3.2
	 */
	public static final String P_KEY_SEQUENCE = "org.eclipse.jface.bindings.keys.KeySequenceText.KeySequence"; //$NON-NLS-1$

	/**
	 * The keys trapped by this widget. This list is guaranteed to be roughly
	 * accurate. Perfection is not possible, as SWT does not export traversal
	 * keys as constants.
	 */
	public static final List TRAPPED_KEYS;

	/**
	 * The key filter attached to the underlying widget that traps key events.
	 */
	private final KeyTrapListener keyFilter = new KeyTrapListener();

	/**
	 * The text of the key sequence -- containing only the complete key strokes.
	 */
	private KeySequence keySequence = KeySequence.getInstance();

	/**
	 * Those listening to changes to the key sequence in this widget. This value
	 * may be <code>null</code> if there are no listeners.
	 */
	private Collection listeners = null;

	/** The maximum number of key strokes permitted in the sequence. */
	private int maxStrokes = INFINITE;

	/** The text widget that is wrapped for this class. */
	private final Text text;

	/**
	 * The listener that makes sure that the text widget remains up-to-date with
	 * regards to external modification of the text (e.g., cut & pasting).
	 */
	private final UpdateSequenceListener updateSequenceListener = new UpdateSequenceListener();

	/**
	 * Constructs an instance of <code>KeySequenceTextField</code> with the
	 * text field to use. If the platform is carbon (MacOS X), then the font is
	 * set to be the same font used to display accelerators in the menus.
	 * 
	 * @param wrappedText
	 *            The text widget to wrap; must not be <code>null</code>.
	 */
	public KeySequenceText(Text wrappedText) {
		text = wrappedText;

		// Set the font if the platform is carbon.
		if ("carbon".equals(SWT.getPlatform())) { //$NON-NLS-1$
			// Don't worry about this font name here; it is the official menu
			// font and point size on the Mac.
			final Font font = new Font(text.getDisplay(),
					"Lucida Grande", 13, SWT.NORMAL); //$NON-NLS-1$
			text.setFont(font);
			text.addDisposeListener(new DisposeListener() {
				public void widgetDisposed(DisposeEvent e) {
					font.dispose();
				}
			});
		}

		// Add the key listener.
		text.addListener(SWT.KeyUp, keyFilter);
		text.addListener(SWT.KeyDown, keyFilter);

		final TraversalFilterManager traversalFilterManager = new TraversalFilterManager();
		text.addFocusListener(traversalFilterManager);
		text.addDisposeListener(new DisposeListener() {
			public void widgetDisposed(DisposeEvent e) {
				traversalFilterManager.dispose();
			} 
		});

		// Add an internal modify listener.
		text.addModifyListener(updateSequenceListener);
	}

	/**
	 * Adds a property change listener to this key sequence widget. It will be
	 * notified when the key sequence changes.
	 * 
	 * @param listener
	 *            The listener to be notified when changes occur; must not be
	 *            <code>null</code>.
	 * @since 3.2
	 */
	public final void addPropertyChangeListener(
			final IPropertyChangeListener listener) {
		if (listener == null) {
			return;
		}

		if (listeners == null) {
			listeners = new ArrayList(1);
		}

		listeners.add(listener);
	}

	/**
	 * Clears the text field and resets all the internal values.
	 */
	public void clear() {
		final KeySequence oldKeySequence = keySequence;
		keySequence = KeySequence.getInstance();
		text.setText(EMPTY_STRING);
		firePropertyChangeEvent(oldKeySequence);
	}

	/**
	 * Removes the key strokes from the list corresponding the selection. If
	 * <code>allowIncomplete</code>, then invalid key sequences will be
	 * allowed (i.e., those with incomplete strokes in the non-terminal
	 * position). Otherwise, incomplete strokes will be removed. This modifies
	 * <code>keyStrokes</code> in place, and has no effect on the text widget
	 * this class wraps.
	 * 
	 * @param keyStrokes
	 *            The list of key strokes from which the selection should be
	 *            removed; must not be <code>null</code>.
	 * @param allowIncomplete
	 *            Whether incomplete strokes should be allowed to exist in the
	 *            list after the deletion.
	 * @param deletedKeyStrokes
	 *            The list of keystrokes that were deleted by this operation.
	 *            Declared as final since it will hold a reference to the new
	 *            keyStroke array that has deleted the selected keystrokes.
	 * @return The index at which a subsequent insert should occur. This index
	 *         only has meaning to the <code>insertStrokeAt</code> method.
	 */
	private final int deleteSelection(final KeyStroke[] keyStrokes,
			final boolean allowIncomplete, final KeyStroke[][] deletedKeyStrokes) {
		// Get the current selection.
		Point selection = text.getSelection();
		int start = selection.x;
		int end = selection.y;

		/*
		 * Using the key sequence format method, discover the point at which
		 * adding key strokes passes or equals the start of the selection. In
		 * other words, find the first stroke that is part of the selection.
		 * Keep track of the text range under which the stroke appears (i.e.,
		 * startTextIndex->string.length() is the first selected stroke).
		 */
		String string = new String();
		List currentStrokes = new ArrayList();
		int startTextIndex = 0; // keeps track of the start of the stroke
		final int keyStrokesLength = keyStrokes.length;
		int i;
		for (i = 0; (i < keyStrokesLength) && (string.length() < start); i++) {
			startTextIndex = string.length();
			currentStrokes.add(keyStrokes[i]);
			string = KeySequence.getInstance(currentStrokes).format();
		}

		/*
		 * If string.length() == start, then the cursor is positioned between
		 * strokes (i.e., selection is outside of a stroke).
		 */
		int startStrokeIndex;
		if (string.length() == start) {
			startStrokeIndex = currentStrokes.size();
		} else {
			startStrokeIndex = currentStrokes.size() - 1;
		}

		/*
		 * Check to see if the cursor is only positioned, rather than actually
		 * selecting something. We only need to compute the end if there is a
		 * selection.
		 */
		int endStrokeIndex;
		if (start == end) {
			// return the current keystrokes, nothing has to be deleted
			deletedKeyStrokes[0] = keyStrokes;
			return startStrokeIndex;
		}

		for (; (i < keyStrokesLength) && (string.length() < end); i++) {
			currentStrokes.add(keyStrokes[i]);
			string = KeySequence.getInstance(currentStrokes).format();
		}
		endStrokeIndex = currentStrokes.size() - 1;
		if (endStrokeIndex < 0) {
			endStrokeIndex = 0;
		}

		/*
		 * Remove the strokes that are touched by the selection. Keep track of
		 * the first stroke removed.
		 */
		final int newLength = keyStrokesLength
				- (endStrokeIndex - startStrokeIndex + 1);
		deletedKeyStrokes[0] = new KeyStroke[newLength];
		final KeyStroke startStroke = keyStrokes[startStrokeIndex];
		KeyStroke keyStrokeResult[] = new KeyStroke[newLength];
		System.arraycopy(keyStrokes, 0, keyStrokeResult, 0, startStrokeIndex);
		System.arraycopy(keyStrokes, endStrokeIndex + 1, keyStrokeResult,
				startStrokeIndex, keyStrokesLength - endStrokeIndex - 1);
		System.arraycopy(keyStrokeResult, 0, deletedKeyStrokes[0], 0, newLength);

		/*
		 * Allow the first stroke removed to be replaced by an incomplete
		 * stroke.
		 */
		if (allowIncomplete) {
			final int modifierKeys = startStroke.getModifierKeys();
			KeyStroke incompleteStroke = KeyStroke.getInstance(modifierKeys,
					KeyStroke.NO_KEY);
			int incompleteStrokeLength = incompleteStroke.format().length();
			if ((startTextIndex + incompleteStrokeLength) <= start) {
				final KeyStroke[] added = new KeyStroke[newLength + 1];
				System.arraycopy(deletedKeyStrokes[0], 0, added, 0,
						startStrokeIndex);
				added[startStrokeIndex] = incompleteStroke;
				System.arraycopy(deletedKeyStrokes[0], startStrokeIndex, added,
						startStrokeIndex + 1, newLength - startStrokeIndex);
				deletedKeyStrokes[0] = added;
			}
		}

		return startStrokeIndex;
	}

	/**
	 * Fires a property change event to all of the listeners.
	 * 
	 * @param oldKeySequence
	 *            The old key sequence; must not be <code>null</code>.
	 * @since 3.2
	 */
	protected final void firePropertyChangeEvent(
			final KeySequence oldKeySequence) {
		if (listeners != null) {
			final Iterator listenerItr = listeners.iterator();
			final PropertyChangeEvent event = new PropertyChangeEvent(this,
					P_KEY_SEQUENCE, oldKeySequence, getKeySequence());
			while (listenerItr.hasNext()) {
				final IPropertyChangeListener listener = (IPropertyChangeListener) listenerItr
						.next();
				listener.propertyChange(event);
			}
		}
	}

	/**
	 * An accessor for the <code>KeySequence</code> that corresponds to the
	 * current state of the text field. This includes incomplete strokes.
	 * 
	 * @return The key sequence representation; never <code>null</code>.
	 */
	public KeySequence getKeySequence() {
		return keySequence;
	}

	/**
	 * An accessor for the underlying text widget's contents.
	 * 
	 * @return The text contents of this entry; never <code>null</code>.
	 */
	private String getText() {
		return text.getText();
	}

	/**
	 * Tests whether the current key sequence has a stroke with no natural key.
	 * 
	 * @return <code>true</code> is there is an incomplete stroke;
	 *         <code>false</code> otherwise.
	 */
	private boolean hasIncompleteStroke() {
		return !keySequence.isComplete();
	}

	/**
	 * Tests whether the current text widget has some text selection.
	 * 
	 * @return <code>true</code> if the number of selected characters it
	 *         greater than zero; <code>false</code> otherwise.
	 */
	private boolean hasSelection() {
		return (text.getSelectionCount() > 0);
	}

	/**
	 * Inserts the key stroke at the current insertion point. This does a
	 * regular delete and insert, as if the key had been pressed.
	 * 
	 * @param stroke
	 *            The key stroke to insert; must not be <code>null</code>.
	 */
	public void insert(KeyStroke stroke) {
		if (!stroke.isComplete()) {
			return;
		}

		// Copy the key strokes in the current key sequence.
		final KeySequence keySequence = getKeySequence();
		final KeyStroke[] oldKeyStrokes = keySequence.getKeyStrokes();
		final KeyStroke[] newKeyStrokes;
		if ((hasIncompleteStroke()) && (!keySequence.isEmpty())) {
			final int newKeyStrokesLength = oldKeyStrokes.length - 1;
			newKeyStrokes = new KeyStroke[newKeyStrokesLength];
			System.arraycopy(oldKeyStrokes, 0, newKeyStrokes, 0,
					newKeyStrokesLength);
		} else {
			newKeyStrokes = oldKeyStrokes;
		}

		KeyStroke[][] deletedKeyStrokes = new KeyStroke[1][];
		int index = deleteSelection(newKeyStrokes, false, deletedKeyStrokes);
		if (index == -1) {
			index = 0;
		}

		final KeyStroke[] keyStrokes = insertStrokeAt(newKeyStrokes, stroke, index);
		keyFilter.clearInsertionIndex();
		setKeySequence(KeySequence.getInstance(keyStrokes));
	}

	/**
	 * Inserts the stroke at the given index in the list of strokes. If the
	 * stroke currently at that index is incomplete, then it tries to merge the
	 * two strokes. If merging is a complete failure (unlikely), then it will
	 * simply overwrite the incomplete stroke. If the stroke at the index is
	 * complete, then it simply inserts the stroke independently.
	 * 
	 * @param keyStrokes
	 *            The list of key strokes in which the key stroke should be
	 *            appended; must not be <code>null</code>.
	 * @param stroke
	 *            The stroke to insert; should not be <code>null</code>.
	 * @param index
	 *            The index at which to insert; must be a valid index into the
	 *            list of key strokes.
	 */
	private final KeyStroke[] insertStrokeAt(final KeyStroke[] keyStrokes,
			KeyStroke stroke, int index) {
		final int keyStrokesLength = keyStrokes.length;
		final KeyStroke currentStroke = (index >= keyStrokesLength) ? null
				: keyStrokes[index];
		if ((currentStroke != null) && (!currentStroke.isComplete())) {
			int modifierKeys = currentStroke.getModifierKeys();
			final int naturalKey = stroke.getNaturalKey();
			modifierKeys |= stroke.getModifierKeys();
			keyStrokes[index] = KeyStroke.getInstance(modifierKeys, naturalKey);
			return keyStrokes;
		}

		final KeyStroke[] newKeyStrokes = new KeyStroke[keyStrokesLength + 1];
		System.arraycopy(keyStrokes, 0, newKeyStrokes, 0, index);
		newKeyStrokes[index] = stroke;
		if (index < keyStrokesLength) {
			System.arraycopy(keyStrokes, index, newKeyStrokes, index + 1,
					keyStrokesLength-index);
		}
		return newKeyStrokes;
	}

	/**
	 * Tests whether the cursor is in the last position. This means that the
	 * selection extends to the last position.
	 * 
	 * @return <code>true</code> if the selection extends to the last
	 *         position; <code>false</code> otherwise.
	 */
	private boolean isCursorInLastPosition() {
		return (text.getSelection().y >= getText().length());
	}

	/**
	 * Removes the given listener from this key sequence widget.
	 * 
	 * @param listener
	 *            The listener to be removed; must not be <code>null</code>.
	 * @since 3.2
	 */
	public final void removePropertyChangeListener(
			final IPropertyChangeListener listener) {
		if ((listener == null) || (listeners == null)) {
			return;
		}

		listeners.remove(listener);
	}

	/**
	 * <p>
	 * A mutator for the key sequence stored within this widget. The text and
	 * caret position are updated.
	 * </p>
	 * <p>
	 * All sequences are limited to maxStrokes number of strokes in length. If
	 * there are already that number of strokes, then it does not show
	 * incomplete strokes, and does not keep track of them.
	 * </p>
	 * 
	 * @param newKeySequence
	 *            The new key sequence for this widget; may be <code>null</code>
	 *            if none.
	 */
	public void setKeySequence(KeySequence newKeySequence) {
		final KeySequence oldKeySequence = keySequence;

		if (newKeySequence == null) {
			text.setText(""); //$NON-NLS-1$
		} else {
			keySequence = newKeySequence;			
		}
		
		// Trim any extra strokes.
		if (maxStrokes != INFINITE) {
			final KeyStroke[] oldKeyStrokes = keySequence.getKeyStrokes();
			if (maxStrokes < oldKeyStrokes.length) {
				final KeyStroke[] newKeyStrokes = new KeyStroke[maxStrokes];
				System
						.arraycopy(oldKeyStrokes, 0, newKeyStrokes, 0,
								maxStrokes);
				keySequence = KeySequence.getInstance(newKeyStrokes);
			}
		}

		// Check to see if the text has changed.
		String currentString = getText();
		String newString = keySequence.format();
		if (!currentString.equals(newString)) {
			// We need to update the text
			text.removeModifyListener(updateSequenceListener);
			text.setText(keySequence.format());
			text.addModifyListener(updateSequenceListener);
			text.setSelection(getText().length());
		}

		firePropertyChangeEvent(oldKeySequence);
	}

	/**
	 * Returns the maximum number of strokes that are permitted in this widget
	 * at one time.
	 * 
	 * @return The maximum number of strokes; will be a positive integer or
	 *         <code>INFINITE</code>.
	 */
	public int getKeyStrokeLimit() {
		return maxStrokes;
	}

	/**
	 * A mutator for the maximum number of strokes that are permitted in this
	 * widget at one time.
	 * 
	 * @param keyStrokeLimit
	 *            The maximum number of strokes; must be a positive integer or
	 *            <code>INFINITE</code>.
	 */
	public void setKeyStrokeLimit(int keyStrokeLimit) {
		if (keyStrokeLimit > 0 || keyStrokeLimit == INFINITE) {
			this.maxStrokes = keyStrokeLimit;
		} else {
			throw new IllegalArgumentException();
		}

		// Make sure we are obeying the new limit.
		setKeySequence(getKeySequence());
	}
}
