/*******************************************************************************
 * 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.Iterator;
import java.util.SortedSet;
import java.util.TreeSet;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.widgets.Event;
import org.eclipse.ui.internal.keys.NativeKeyFormatter;

/**
 * A utility class for converting SWT events into key strokes.
 * 
 * @deprecated Please use org.eclipse.jface.bindings.keys.SWTKeySupport
 * @since 3.0
 */
public final class SWTKeySupport {

    /**
     * Given an SWT accelerator value, provide the corresponding key stroke.
     * 
     * @param accelerator
     *            The accelerator to convert; should be a valid SWT accelerator
     *            value.
     * @return The equivalent key stroke; never <code>null</code>.
     */
    public static KeyStroke convertAcceleratorToKeyStroke(int accelerator) {
        final SortedSet modifierKeys = new TreeSet();
        NaturalKey naturalKey = null;

        if ((accelerator & SWT.ALT) != 0) {
			modifierKeys.add(ModifierKey.ALT);
		}

        if ((accelerator & SWT.COMMAND) != 0) {
			modifierKeys.add(ModifierKey.COMMAND);
		}

        if ((accelerator & SWT.CTRL) != 0) {
			modifierKeys.add(ModifierKey.CTRL);
		}

        if ((accelerator & SWT.SHIFT) != 0) {
			modifierKeys.add(ModifierKey.SHIFT);
		}

        if (((accelerator & SWT.KEY_MASK) == 0) && (accelerator != 0)) {
            // There were only accelerators
            naturalKey = null;
        } else {
            // There were other keys.
            accelerator &= SWT.KEY_MASK;

            switch (accelerator) {
            case SWT.ARROW_DOWN:
                naturalKey = SpecialKey.ARROW_DOWN;
                break;
            case SWT.ARROW_LEFT:
                naturalKey = SpecialKey.ARROW_LEFT;
                break;
            case SWT.ARROW_RIGHT:
                naturalKey = SpecialKey.ARROW_RIGHT;
                break;
            case SWT.ARROW_UP:
                naturalKey = SpecialKey.ARROW_UP;
                break;
            case SWT.BREAK:
                naturalKey = SpecialKey.BREAK;
                break;
            case SWT.CAPS_LOCK:
                naturalKey = SpecialKey.CAPS_LOCK;
                break;
            case SWT.END:
                naturalKey = SpecialKey.END;
                break;
            case SWT.F1:
                naturalKey = SpecialKey.F1;
                break;
            case SWT.F10:
                naturalKey = SpecialKey.F10;
                break;
            case SWT.F11:
                naturalKey = SpecialKey.F11;
                break;
            case SWT.F12:
                naturalKey = SpecialKey.F12;
                break;
            case SWT.F2:
                naturalKey = SpecialKey.F2;
                break;
            case SWT.F3:
                naturalKey = SpecialKey.F3;
                break;
            case SWT.F4:
                naturalKey = SpecialKey.F4;
                break;
            case SWT.F5:
                naturalKey = SpecialKey.F5;
                break;
            case SWT.F6:
                naturalKey = SpecialKey.F6;
                break;
            case SWT.F7:
                naturalKey = SpecialKey.F7;
                break;
            case SWT.F8:
                naturalKey = SpecialKey.F8;
                break;
            case SWT.F9:
                naturalKey = SpecialKey.F9;
                break;
            case SWT.HOME:
                naturalKey = SpecialKey.HOME;
                break;
            case SWT.INSERT:
                naturalKey = SpecialKey.INSERT;
                break;
            case SWT.KEYPAD_0:
                naturalKey = SpecialKey.NUMPAD_0;
                break;
            case SWT.KEYPAD_1:
                naturalKey = SpecialKey.NUMPAD_1;
                break;
            case SWT.KEYPAD_2:
                naturalKey = SpecialKey.NUMPAD_2;
                break;
            case SWT.KEYPAD_3:
                naturalKey = SpecialKey.NUMPAD_3;
                break;
            case SWT.KEYPAD_4:
                naturalKey = SpecialKey.NUMPAD_4;
                break;
            case SWT.KEYPAD_5:
                naturalKey = SpecialKey.NUMPAD_5;
                break;
            case SWT.KEYPAD_6:
                naturalKey = SpecialKey.NUMPAD_6;
                break;
            case SWT.KEYPAD_7:
                naturalKey = SpecialKey.NUMPAD_7;
                break;
            case SWT.KEYPAD_8:
                naturalKey = SpecialKey.NUMPAD_8;
                break;
            case SWT.KEYPAD_9:
                naturalKey = SpecialKey.NUMPAD_9;
                break;
            case SWT.KEYPAD_ADD:
                naturalKey = SpecialKey.NUMPAD_ADD;
                break;
            case SWT.KEYPAD_CR:
                naturalKey = SpecialKey.NUMPAD_ENTER;
                break;
            case SWT.KEYPAD_DECIMAL:
                naturalKey = SpecialKey.NUMPAD_DECIMAL;
                break;
            case SWT.KEYPAD_DIVIDE:
                naturalKey = SpecialKey.NUMPAD_DIVIDE;
                break;
            case SWT.KEYPAD_EQUAL:
                naturalKey = SpecialKey.NUMPAD_EQUAL;
                break;
            case SWT.KEYPAD_MULTIPLY:
                naturalKey = SpecialKey.NUMPAD_MULTIPLY;
                break;
            case SWT.KEYPAD_SUBTRACT:
                naturalKey = SpecialKey.NUMPAD_SUBTRACT;
                break;
            case SWT.NUM_LOCK:
                naturalKey = SpecialKey.NUM_LOCK;
                break;
            case SWT.PAGE_DOWN:
                naturalKey = SpecialKey.PAGE_DOWN;
                break;
            case SWT.PAGE_UP:
                naturalKey = SpecialKey.PAGE_UP;
                break;
            case SWT.PAUSE:
                naturalKey = SpecialKey.PAUSE;
                break;
            case SWT.PRINT_SCREEN:
                naturalKey = SpecialKey.PRINT_SCREEN;
                break;
            case SWT.SCROLL_LOCK:
                naturalKey = SpecialKey.SCROLL_LOCK;
                break;
            default:
                naturalKey = CharacterKey
                        .getInstance((char) (accelerator & 0xFFFF));
            }
        }

        return KeyStroke.getInstance(modifierKeys, naturalKey);
    }

    /**
     * <p>
     * Converts the given event into an SWT accelerator value -- considering the
     * modified character with the shift modifier. This is the third accelerator
     * value that should be checked.
     * </p>
     * <p>
     * For example, on a standard US keyboard, "Ctrl+Shift+5" would be viewed as
     * "Ctrl+Shift+%".
     * </p>
     * 
     * @param event
     *            The event to be converted; must not be <code>null</code>.
     * @return The combination of the state mask and the unmodified character.
     */
    public static int convertEventToModifiedAccelerator(Event event) {
        int modifiers = event.stateMask & SWT.MODIFIER_MASK;
        char character = topKey(event);
        return modifiers + toUpperCase(character);
    }

    /**
     * <p>
     * Converts the given event into an SWT accelerator value -- considering the
     * unmodified character with all modifier keys. This is the first
     * accelerator value that should be checked. However, all alphabetic
     * characters are considered as their uppercase equivalents.
     * </p>
     * <p>
     * For example, on a standard US keyboard, "Ctrl+Shift+5" would be viewed as
     * "Ctrl+Shift+5".
     * </p>
     * 
     * @param event
     *            The event to be converted; must not be <code>null</code>.
     * @return The combination of the state mask and the unmodified character.
     */
    public static int convertEventToUnmodifiedAccelerator(Event event) {
        return convertEventToUnmodifiedAccelerator(event.stateMask,
                event.keyCode);
    }

    /**
     * <p>
     * Converts the given state mask and key code into an SWT accelerator value --
     * considering the unmodified character with all modifier keys. All
     * alphabetic characters are considered as their uppercase equivalents.
     * </p>
     * <p>
     * For example, on a standard US keyboard, "Ctrl+Shift+5" would be viewed as
     * "Ctrl+Shift+5".
     * </p>
     * 
     * @param stateMask
     *            The integer mask of modifiers keys depressed when this was
     *            pressed.
     * @param keyCode
     *            The key that was pressed, before being modified.
     * @return The combination of the state mask and the unmodified character.
     */
    private static int convertEventToUnmodifiedAccelerator(int stateMask,
            int keyCode) {
        int modifiers = stateMask & SWT.MODIFIER_MASK;
        int character = keyCode;
        return modifiers + toUpperCase(character);
    }

    /**
     * <p>
     * Converts the given event into an SWT accelerator value -- considering the
     * unmodified character with all modifier keys. This is the first
     * accelerator value that should be checked. However, all alphabetic
     * characters are considered as their uppercase equivalents.
     * </p>
     * <p>
     * For example, on a standard US keyboard, "Ctrl+Shift+5" would be viewed as
     * "Ctrl+%".
     * </p>
     * 
     * @param event
     *            The event to be converted; must not be <code>null</code>.
     * @return The combination of the state mask and the unmodified character.
     */
    public static int convertEventToUnmodifiedAccelerator(KeyEvent event) {
        return convertEventToUnmodifiedAccelerator(event.stateMask,
                event.keyCode);
    }

    /**
     * Converts the given event into an SWT accelerator value -- considering
     * the modified character without the shift modifier. This is the second
     * accelerator value that should be checked. Key strokes with alphabetic
     * natural keys are run through <code>convertEventToUnmodifiedAccelerator</code>
     * 
     * @param event
     *            The event to be converted; must not be <code>null</code>.
     * @return The combination of the state mask without shift, and the
     *         modified character.
     */
    public static int convertEventToUnshiftedModifiedAccelerator(Event event) {
        // Disregard alphabetic key strokes.
        if (Character.isLetter((char) event.keyCode)) {
            return convertEventToUnmodifiedAccelerator(event);
        }

        int modifiers = event.stateMask & (SWT.MODIFIER_MASK ^ SWT.SHIFT);
        char character = topKey(event);
        return modifiers + toUpperCase(character);
    }

    /**
     * Given a key stroke, this method provides the equivalent SWT accelerator
     * value. The functional inverse of <code>convertAcceleratorToKeyStroke</code>.
     * 
     * @param keyStroke
     *            The key stroke to convert; must not be <code>null</code>.
     * @return The SWT accelerator value
     */
    public static final int convertKeyStrokeToAccelerator(
            final KeyStroke keyStroke) {
        int accelerator = 0;
        final Iterator iterator = keyStroke.getModifierKeys().iterator();

        while (iterator.hasNext()) {
            final ModifierKey modifierKey = (ModifierKey) iterator.next();

            if (modifierKey == ModifierKey.ALT) {
				accelerator |= SWT.ALT;
			} else if (modifierKey == ModifierKey.COMMAND) {
				accelerator |= SWT.COMMAND;
			} else if (modifierKey == ModifierKey.CTRL) {
				accelerator |= SWT.CTRL;
			} else if (modifierKey == ModifierKey.SHIFT) {
				accelerator |= SWT.SHIFT;
			}
        }

        final NaturalKey naturalKey = keyStroke.getNaturalKey();

        if (naturalKey instanceof CharacterKey) {
			accelerator |= ((CharacterKey) naturalKey).getCharacter();
		} else if (naturalKey instanceof SpecialKey) {
            final SpecialKey specialKey = (SpecialKey) naturalKey;

            if (specialKey == SpecialKey.ARROW_DOWN) {
				accelerator |= SWT.ARROW_DOWN;
			} else if (specialKey == SpecialKey.ARROW_LEFT) {
				accelerator |= SWT.ARROW_LEFT;
			} else if (specialKey == SpecialKey.ARROW_RIGHT) {
				accelerator |= SWT.ARROW_RIGHT;
			} else if (specialKey == SpecialKey.ARROW_UP) {
				accelerator |= SWT.ARROW_UP;
			} else if (specialKey == SpecialKey.END) {
				accelerator |= SWT.END;
			} else if (specialKey == SpecialKey.F1) {
				accelerator |= SWT.F1;
			} else if (specialKey == SpecialKey.F10) {
				accelerator |= SWT.F10;
			} else if (specialKey == SpecialKey.F11) {
				accelerator |= SWT.F11;
			} else if (specialKey == SpecialKey.F12) {
				accelerator |= SWT.F12;
			} else if (specialKey == SpecialKey.F2) {
				accelerator |= SWT.F2;
			} else if (specialKey == SpecialKey.F3) {
				accelerator |= SWT.F3;
			} else if (specialKey == SpecialKey.F4) {
				accelerator |= SWT.F4;
			} else if (specialKey == SpecialKey.F5) {
				accelerator |= SWT.F5;
			} else if (specialKey == SpecialKey.F6) {
				accelerator |= SWT.F6;
			} else if (specialKey == SpecialKey.F7) {
				accelerator |= SWT.F7;
			} else if (specialKey == SpecialKey.F8) {
				accelerator |= SWT.F8;
			} else if (specialKey == SpecialKey.F9) {
				accelerator |= SWT.F9;
			} else if (specialKey == SpecialKey.HOME) {
				accelerator |= SWT.HOME;
			} else if (specialKey == SpecialKey.INSERT) {
				accelerator |= SWT.INSERT;
			} else if (specialKey == SpecialKey.PAGE_DOWN) {
				accelerator |= SWT.PAGE_DOWN;
			} else if (specialKey == SpecialKey.PAGE_UP) {
				accelerator |= SWT.PAGE_UP;
			}
        }

        return accelerator;
    }

    private static final IKeyFormatter NATIVE_FORMATTER = new NativeKeyFormatter();

    /**
     * Provides an instance of <code>IKeyFormatter</code> appropriate for the
     * current instance.
     * 
     * @return an instance of <code>IKeyFormatter</code> appropriate for the
     *         current instance; never <code>null</code>.
     */
    public static IKeyFormatter getKeyFormatterForPlatform() {
        return NATIVE_FORMATTER;
    }

    /**
     * Makes sure that a fully-modified character is converted to the normal
     * form. This means that "Ctrl+" key strokes must reverse the modification
     * caused by control-escaping. Also, all lower case letters are converted
     * to uppercase.
     * 
     * @param event
     *            The event from which the fully-modified character should be
     *            pulled.
     * @return The modified character, uppercase and without control-escaping.
     */
    private static char topKey(Event event) {
        char character = event.character;
        boolean ctrlDown = (event.stateMask & SWT.CTRL) != 0;

        if (ctrlDown && event.character != event.keyCode
                && event.character < 0x20) {
			character += 0x40;
		}

        return character;
    }

    /**
     * Makes the given character uppercase if it is a letter.
     * 
     * @param keyCode
     *            The character to convert.
     * @return The uppercase equivalent, if any; otherwise, the character
     *         itself.
     */
    private static int toUpperCase(int keyCode) {
        // Will this key code be truncated?
        if (keyCode > 0xFFFF) {
            return keyCode;
        }

        // Downcast in safety. Only make characters uppercase.
        char character = (char) keyCode;
        return Character.isLetter(character) ? Character.toUpperCase(character)
                : keyCode;
    }

    /**
     * This class should never be instantiated.
     */
    private SWTKeySupport() {
        // This class should never be instantiated.
    }
}
