/*
 * Copyright (C) 2004, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#import "config.h"
#import "PlatformKeyboardEvent.h"

#if PLATFORM(IOS_FAMILY)

#import "KeyEventCocoa.h"
#import "KeyEventCodesIOS.h"
#import "NotImplemented.h"
#import "WebEvent.h"
#import "WindowsKeyboardCodes.h"
#import <pal/spi/cocoa/IOKitSPI.h>
#import <wtf/MainThread.h>

namespace WebCore {

int windowsKeyCodeForKeyCode(uint16_t keyCode)
{
    static const int windowsKeyCode[] = {
        /* 0 */ 0, // n/a
        /* 1 */ 0, // n/a
        /* 2 */ 0, // n/a
        /* 3 */ 0, // n/a
        /* 4 */ VK_A,
        /* 5 */ VK_B,
        /* 6 */ VK_C,
        /* 7 */ VK_D,
        /* 8 */ VK_E,
        /* 9 */ VK_F,
        /* 0x0A */ VK_G,
        /* 0x0B */ VK_H,
        /* 0x0C */ VK_I,
        /* 0x0D */ VK_J,
        /* 0x0E */ VK_K,
        /* 0x0F */ VK_L,
        /* 0x10 */ VK_M,
        /* 0x11 */ VK_N,
        /* 0x12 */ VK_O,
        /* 0x13 */ VK_P,
        /* 0x14 */ VK_Q,
        /* 0x15 */ VK_R,
        /* 0x16 */ VK_S,
        /* 0x17 */ VK_T,
        /* 0x18 */ VK_U,
        /* 0x19 */ VK_V,
        /* 0x1A */ VK_W,
        /* 0x1B */ VK_X,
        /* 0x1C */ VK_Y,
        /* 0x1D */ VK_Z,
        /* 0x1E */ VK_1,
        /* 0x1F */ VK_2,
        /* 0x20 */ VK_3,
        /* 0x21 */ VK_4,
        /* 0x22 */ VK_5,
        /* 0x23 */ VK_6,
        /* 0x24 */ VK_7,
        /* 0x25 */ VK_8,
        /* 0x26 */ VK_9,
        /* 0x27 */ VK_0,
        /* 0x28 */ VK_RETURN, // Return
        /* 0x29 */ VK_ESCAPE,
        /* 0x2A */ VK_BACK, // Backspace
        /* 0x2B */ VK_TAB,
        /* 0x2C */ VK_SPACE,
        /* 0x2D */ VK_OEM_MINUS, // -_
        /* 0x2E */ VK_OEM_PLUS, // =+
        /* 0x2F */ VK_OEM_4, // [{
        /* 0x30 */ VK_OEM_6, // ]}
        /* 0x31 */ VK_OEM_5, // \|
        /* 0x32 */ 0, // kHIDUsage_KeyboardNonUSPound
        /* 0x33 */ VK_OEM_1, // ;:
        /* 0x34 */ VK_OEM_7, // '"
        /* 0x35 */ VK_OEM_3, // `~
        /* 0x36 */ VK_OEM_COMMA, // ,<
        /* 0x37 */ VK_OEM_PERIOD, // .>
        /* 0x38 */ VK_OEM_2, // /?
        /* 0x39 */ VK_CAPITAL, // Caps Lock
        /* 0x3A */ VK_F1,
        /* 0x3B */ VK_F2,
        /* 0x3C */ VK_F3,
        /* 0x3D */ VK_F4,
        /* 0x3E */ VK_F5,
        /* 0x3F */ VK_F6,
        /* 0x40 */ VK_F7,
        /* 0x41 */ VK_F8,
        /* 0x42 */ VK_F9,
        /* 0x43 */ VK_F10,
        /* 0x44 */ VK_F11,
        /* 0x45 */ VK_F12,
        /* 0x46 */ VK_SNAPSHOT, // Print Screen
        /* 0x47 */ VK_SCROLL, // Scroll Lock
        /* 0x48 */ VK_PAUSE,
        /* 0x49 */ VK_INSERT,
        /* 0x4A */ VK_HOME, // Home
        /* 0x4B */ VK_PRIOR, // Page Up
        /* 0x4C */ VK_DELETE, // Forward Delete
        /* 0x4D */ VK_END, // End
        /* 0x4E */ VK_NEXT, // Page Down
        /* 0x4F */ VK_RIGHT, // Right Arrow
        /* 0x50 */ VK_LEFT, // Left Arrow
        /* 0x51 */ VK_DOWN, // Down Arrow
        /* 0x52 */ VK_UP, // Up Arrow
        /* 0x53 */ VK_CLEAR, // Num Pad Clear
        /* 0x54 */ VK_DIVIDE, // Num Pad /
        /* 0x55 */ VK_MULTIPLY, // Num Pad *
        /* 0x56 */ VK_SUBTRACT, // Num Pad -
        /* 0x57 */ VK_ADD, // Num Pad +
        /* 0x58 */ VK_RETURN, // Num Pad Enter
        /* 0x59 */ VK_NUMPAD1,
        /* 0x5A */ VK_NUMPAD2,
        /* 0x5B */ VK_NUMPAD3,
        /* 0x5C */ VK_NUMPAD4,
        /* 0x5D */ VK_NUMPAD5,
        /* 0x5E */ VK_NUMPAD6,
        /* 0x5F */ VK_NUMPAD7,
        /* 0x60 */ VK_NUMPAD8,
        /* 0x61 */ VK_NUMPAD9,
        /* 0x62 */ VK_NUMPAD0,
        /* 0x63 */ VK_DECIMAL, // Num Pad .
        /* 0x64 */ 0, // Non-ANSI \|
        /* 0x65 */ 0, // Application
        /* 0x66 */ 0, // Power
        /* 0x67 */ VK_OEM_PLUS, // Num Pad =. There is no such key on common PC keyboards, mapping to normal "+=".
        /* 0x68 */ VK_F13,
        /* 0x69 */ VK_F14,
        /* 0x6A */ VK_F15,
        /* 0x6B */ VK_F16,
        /* 0x6C */ VK_F17,
        /* 0x6D */ VK_F18,
        /* 0x6E */ VK_F19,
        /* 0x6F */ VK_F20,
        /* 0x70 */ VK_F21,
        /* 0x71 */ VK_F22,
        /* 0x72 */ VK_F23,
        /* 0x73 */ VK_F24,
        /* 0x74 */ VK_EXECUTE,
        /* 0x75 */ VK_INSERT, // Help
        /* 0x76 */ 0, // Menu
        /* 0x77 */ VK_SELECT,
        /* 0x78 */ 0, // Stop
        /* 0x79 */ 0, // Again
        /* 0x7A */ 0, // Undo
        /* 0x7B */ 0, // Cut
        /* 0x7C */ 0, // Copy
        /* 0x7D */ 0, // Paste
        /* 0x7E */ 0, // Find
        /* 0x7F */ VK_VOLUME_MUTE, // Mute
        /* 0x80 */ VK_VOLUME_UP, // Volume Up
        /* 0x81 */ VK_VOLUME_DOWN, // Volume Down
    };
    // Check if key is a modifier or the keypad comma (on JIS keyboard).
    switch (keyCode) {
    case kHIDUsage_KeypadComma:
        return VK_SEPARATOR;
    case kHIDUsage_KeyboardLeftControl:
        return VK_LCONTROL;
    case kHIDUsage_KeyboardLeftShift:
        return VK_LSHIFT;
    case kHIDUsage_KeyboardLeftAlt: // Left Option
        return VK_LMENU;
    case kHIDUsage_KeyboardLeftGUI: // Left Command
        return VK_LWIN;
    case kHIDUsage_KeyboardRightControl:
        return VK_RCONTROL;
    case kHIDUsage_KeyboardRightShift:
        return VK_RSHIFT;
    case kHIDUsage_KeyboardRightAlt: // Right Option
        return VK_RMENU;
    case kHIDUsage_KeyboardRightGUI: // Right Command
        return VK_APPS;
    }
    // Otherwise check all other known keys.
    if (keyCode < WTF_ARRAY_LENGTH(windowsKeyCode))
        return windowsKeyCode[keyCode];
    return 0; // Unknown key
}

int windowsKeyCodeForCharCode(unichar charCode)
{
    switch (charCode) {
    case 8: case 0x7F: return VK_BACK;
    case 9: return VK_TAB;
    case 0xD: case 3: return VK_RETURN;
    case ' ': return VK_SPACE;

    case '0': case ')': return VK_0;
    case '1': case '!': return VK_1;
    case '2': case '@': return VK_2;
    case '3': case '#': return VK_3;
    case '4': case '$': return VK_4;
    case '5': case '%': return VK_5;
    case '6': case '^': return VK_6;
    case '7': case '&': return VK_7;
    case '8': case '*': return VK_8;
    case '9': case '(': return VK_9;
    case 'a': case 'A': return VK_A;
    case 'b': case 'B': return VK_B;
    case 'c': case 'C': return VK_C;
    case 'd': case 'D': return VK_D;
    case 'e': case 'E': return VK_E;
    case 'f': case 'F': return VK_F;
    case 'g': case 'G': return VK_G;
    case 'h': case 'H': return VK_H;
    case 'i': case 'I': return VK_I;
    case 'j': case 'J': return VK_J;
    case 'k': case 'K': return VK_K;
    case 'l': case 'L': return VK_L;
    case 'm': case 'M': return VK_M;
    case 'n': case 'N': return VK_N;
    case 'o': case 'O': return VK_O;
    case 'p': case 'P': return VK_P;
    case 'q': case 'Q': return VK_Q;
    case 'r': case 'R': return VK_R;
    case 's': case 'S': return VK_S;
    case 't': case 'T': return VK_T;
    case 'u': case 'U': return VK_U;
    case 'v': case 'V': return VK_V;
    case 'w': case 'W': return VK_W;
    case 'x': case 'X': return VK_X;
    case 'y': case 'Y': return VK_Y;
    case 'z': case 'Z': return VK_Z;

    case 0x1B: return VK_ESCAPE; // WebKit generated code for Escape.

    // WebKit uses Unicode PUA codes in the OpenStep reserve range for some special keys.
    case NSUpArrowFunctionKey: return VK_UP;
    case NSDownArrowFunctionKey: return VK_DOWN;
    case NSLeftArrowFunctionKey: return VK_LEFT;
    case NSRightArrowFunctionKey: return VK_RIGHT;
    case NSPageUpFunctionKey: return VK_PRIOR;
    case NSPageDownFunctionKey: return VK_NEXT;

    // This is for U.S. keyboard mapping, and doesn't necessarily make sense for different keyboard layouts.
    // For example, '"' on Windows Russian layout is VK_2, not VK_OEM_7.
    case ';': case ':': return VK_OEM_1;
    case '=': case '+': return VK_OEM_PLUS;
    case ',': case '<': return VK_OEM_COMMA;
    case '-': case '_': return VK_OEM_MINUS;
    case '.': case '>': return VK_OEM_PERIOD;
    case '/': case '?': return VK_OEM_2;
    case '`': case '~': return VK_OEM_3;
    case '[': case '{': return VK_OEM_4;
    case '\\': case '|': return VK_OEM_5;
    case ']': case '}': return VK_OEM_6;
    case '\'': case '"': return VK_OEM_7;
    }
    return 0;
}

static bool isFunctionKey(UChar charCode)
{
    switch (charCode) {
    // WebKit uses Unicode PUA codes in the OpenStep reserve range for some special keys.
    case NSUpArrowFunctionKey:
    case NSDownArrowFunctionKey:
    case NSLeftArrowFunctionKey:
    case NSRightArrowFunctionKey:
    case NSPageUpFunctionKey:
    case NSPageDownFunctionKey:
    case NSClearLineFunctionKey: // Num Lock / Clear
    case NSDeleteFunctionKey: // Forward delete
    case NSEndFunctionKey:
    case NSInsertFunctionKey:
    case NSHomeFunctionKey:
        return true;
    }
    if (charCode >= NSF1FunctionKey && charCode <= NSF24FunctionKey)
        return true;
    return false;
}

void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type type, bool backwardCompatibilityMode)
{
    // Can only change type from KeyDown to RawKeyDown or Char, as we lack information for other conversions.
    ASSERT(m_type == KeyDown);
    ASSERT(type == RawKeyDown || type == Char);
    m_type = type;
    if (backwardCompatibilityMode)
        return;

    if (type == PlatformEvent::RawKeyDown) {
        m_text = String();
        m_unmodifiedText = String();
    } else {
        m_keyIdentifier = String();
        m_windowsVirtualKeyCode = 0;
        if (m_text.length() == 1 && isFunctionKey(m_text[0U])) {
            m_text = String();
            m_unmodifiedText = String();
        }
    }
}

OptionSet<PlatformEvent::Modifier> PlatformKeyboardEvent::currentStateOfModifierKeys()
{
    // s_currentModifiers is only set in the WebContent process, not in the UI process.
    if (s_currentModifiers) {
        ASSERT(isMainThread());
        return *s_currentModifiers;
    }

    ::WebEventFlags currentModifiers = [::WebEvent modifierFlags];

    OptionSet<PlatformEvent::Modifier> modifiers;
    if (currentModifiers & ::WebEventFlagMaskShiftKey)
        modifiers.add(PlatformEvent::Modifier::ShiftKey);
    if (currentModifiers & ::WebEventFlagMaskControlKey)
        modifiers.add(PlatformEvent::Modifier::ControlKey);
    if (currentModifiers & ::WebEventFlagMaskOptionKey)
        modifiers.add(PlatformEvent::Modifier::AltKey);
    if (currentModifiers & ::WebEventFlagMaskCommandKey)
        modifiers.add(PlatformEvent::Modifier::MetaKey);
    if (currentModifiers & ::WebEventFlagMaskLeftCapsLockKey)
        modifiers.add(PlatformEvent::Modifier::CapsLockKey);

    return modifiers;
}

}

#endif // PLATFORM(IOS_FAMILY)
