/*
 * Copyright (C) 2006-2009 Google 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:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * 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.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "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 THE COPYRIGHT
 * OWNER 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.
 */

#include "config.h"
#include "WebInputEventFactory.h"

#include "core/platform/chromium/KeyCodeConversion.h"
#include "platform/KeyboardCodes.h"

#include "WebInputEvent.h"

#include <gdk/gdk.h>
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
#include <stdlib.h>

#include "wtf/Assertions.h"

namespace {

// For click count tracking.
static int gNumClicks = 0;
static GdkWindow* gLastClickEventWindow = 0;
static gint gLastClickTime = 0;
static gint gLastClickX = 0;
static gint gLastClickY = 0;
static blink::WebMouseEvent::Button gLastClickButton = blink::WebMouseEvent::ButtonNone;

bool shouldForgetPreviousClick(GdkWindow* window, gint time, gint x, gint y)
{
    static GtkSettings* settings = gtk_settings_get_default();

    if (window != gLastClickEventWindow)
      return true;

    gint doubleClickTime = 250;
    gint doubleClickDistance = 5;
    g_object_get(G_OBJECT(settings),
                 "gtk-double-click-time", &doubleClickTime,
                 "gtk-double-click-distance", &doubleClickDistance, NULL);
    return (time - gLastClickTime) > doubleClickTime
           || abs(x - gLastClickX) > doubleClickDistance
           || abs(y - gLastClickY) > doubleClickDistance;
}

void resetClickCountState()
{
    gNumClicks = 0;
    gLastClickEventWindow = 0;
    gLastClickTime = 0;
    gLastClickX = 0;
    gLastClickY = 0;
    gLastClickButton = blink::WebMouseEvent::ButtonNone;
}

bool isKeyPadKeyval(guint keyval)
{
    // Keypad keyvals all fall into one range.
    return keyval >= GDK_KP_Space && keyval <= GDK_KP_9;
}

}  // namespace

namespace blink {

static double gdkEventTimeToWebEventTime(guint32 time)
{
    // Convert from time in ms to time in sec.
    return time / 1000.0;
}

static int gdkStateToWebEventModifiers(guint state)
{
    int modifiers = 0;
    if (state & GDK_SHIFT_MASK)
        modifiers |= WebInputEvent::ShiftKey;
    if (state & GDK_CONTROL_MASK)
        modifiers |= WebInputEvent::ControlKey;
    if (state & GDK_MOD1_MASK)
        modifiers |= WebInputEvent::AltKey;
    if (state & GDK_META_MASK)
        modifiers |= WebInputEvent::MetaKey;
    if (state & GDK_BUTTON1_MASK)
        modifiers |= WebInputEvent::LeftButtonDown;
    if (state & GDK_BUTTON2_MASK)
        modifiers |= WebInputEvent::MiddleButtonDown;
    if (state & GDK_BUTTON3_MASK)
        modifiers |= WebInputEvent::RightButtonDown;
    if (state & GDK_LOCK_MASK)
        modifiers |= WebInputEvent::CapsLockOn;
    if (state & GDK_MOD2_MASK)
        modifiers |= WebInputEvent::NumLockOn;
    return modifiers;
}

static int gdkEventToWindowsKeyCode(const GdkEventKey* event)
{
    static const unsigned int hardwareCodeToGDKKeyval[] = {
        0,                 // 0x00:
        0,                 // 0x01:
        0,                 // 0x02:
        0,                 // 0x03:
        0,                 // 0x04:
        0,                 // 0x05:
        0,                 // 0x06:
        0,                 // 0x07:
        0,                 // 0x08:
        0,                 // 0x09: GDK_Escape
        GDK_1,             // 0x0A: GDK_1
        GDK_2,             // 0x0B: GDK_2
        GDK_3,             // 0x0C: GDK_3
        GDK_4,             // 0x0D: GDK_4
        GDK_5,             // 0x0E: GDK_5
        GDK_6,             // 0x0F: GDK_6
        GDK_7,             // 0x10: GDK_7
        GDK_8,             // 0x11: GDK_8
        GDK_9,             // 0x12: GDK_9
        GDK_0,             // 0x13: GDK_0
        GDK_minus,         // 0x14: GDK_minus
        GDK_equal,         // 0x15: GDK_equal
        0,                 // 0x16: GDK_BackSpace
        0,                 // 0x17: GDK_Tab
        GDK_q,             // 0x18: GDK_q
        GDK_w,             // 0x19: GDK_w
        GDK_e,             // 0x1A: GDK_e
        GDK_r,             // 0x1B: GDK_r
        GDK_t,             // 0x1C: GDK_t
        GDK_y,             // 0x1D: GDK_y
        GDK_u,             // 0x1E: GDK_u
        GDK_i,             // 0x1F: GDK_i
        GDK_o,             // 0x20: GDK_o
        GDK_p,             // 0x21: GDK_p
        GDK_bracketleft,   // 0x22: GDK_bracketleft
        GDK_bracketright,  // 0x23: GDK_bracketright
        0,                 // 0x24: GDK_Return
        0,                 // 0x25: GDK_Control_L
        GDK_a,             // 0x26: GDK_a
        GDK_s,             // 0x27: GDK_s
        GDK_d,             // 0x28: GDK_d
        GDK_f,             // 0x29: GDK_f
        GDK_g,             // 0x2A: GDK_g
        GDK_h,             // 0x2B: GDK_h
        GDK_j,             // 0x2C: GDK_j
        GDK_k,             // 0x2D: GDK_k
        GDK_l,             // 0x2E: GDK_l
        GDK_semicolon,     // 0x2F: GDK_semicolon
        GDK_apostrophe,    // 0x30: GDK_apostrophe
        GDK_grave,         // 0x31: GDK_grave
        0,                 // 0x32: GDK_Shift_L
        GDK_backslash,     // 0x33: GDK_backslash
        GDK_z,             // 0x34: GDK_z
        GDK_x,             // 0x35: GDK_x
        GDK_c,             // 0x36: GDK_c
        GDK_v,             // 0x37: GDK_v
        GDK_b,             // 0x38: GDK_b
        GDK_n,             // 0x39: GDK_n
        GDK_m,             // 0x3A: GDK_m
        GDK_comma,         // 0x3B: GDK_comma
        GDK_period,        // 0x3C: GDK_period
        GDK_slash,         // 0x3D: GDK_slash
        0,                 // 0x3E: GDK_Shift_R
        0,                 // 0x3F:
        0,                 // 0x40:
        0,                 // 0x41:
        0,                 // 0x42:
        0,                 // 0x43:
        0,                 // 0x44:
        0,                 // 0x45:
        0,                 // 0x46:
        0,                 // 0x47:
        0,                 // 0x48:
        0,                 // 0x49:
        0,                 // 0x4A:
        0,                 // 0x4B:
        0,                 // 0x4C:
        0,                 // 0x4D:
        0,                 // 0x4E:
        0,                 // 0x4F:
        0,                 // 0x50:
        0,                 // 0x51:
        0,                 // 0x52:
        0,                 // 0x53:
        0,                 // 0x54:
        0,                 // 0x55:
        0,                 // 0x56:
        0,                 // 0x57:
        0,                 // 0x58:
        0,                 // 0x59:
        0,                 // 0x5A:
        0,                 // 0x5B:
        0,                 // 0x5C:
        0,                 // 0x5D:
        0,                 // 0x5E:
        0,                 // 0x5F:
        0,                 // 0x60:
        0,                 // 0x61:
        0,                 // 0x62:
        0,                 // 0x63:
        0,                 // 0x64:
        0,                 // 0x65:
        0,                 // 0x66:
        0,                 // 0x67:
        0,                 // 0x68:
        0,                 // 0x69:
        0,                 // 0x6A:
        0,                 // 0x6B:
        0,                 // 0x6C:
        0,                 // 0x6D:
        0,                 // 0x6E:
        0,                 // 0x6F:
        0,                 // 0x70:
        0,                 // 0x71:
        0,                 // 0x72:
        GDK_Super_L,       // 0x73: GDK_Super_L
        GDK_Super_R,       // 0x74: GDK_Super_R
    };

    // |windowsKeyCode| has to include a valid virtual-key code even when we
    // use non-US layouts, e.g. even when we type an 'A' key of a US keyboard
    // on the Hebrew layout, |windowsKeyCode| should be VK_A.
    // On the other hand, |event->keyval| value depends on the current
    // GdkKeymap object, i.e. when we type an 'A' key of a US keyboard on
    // the Hebrew layout, |event->keyval| becomes GDK_hebrew_shin and this
    // WebCore::windowsKeyCodeForKeyEvent() call returns 0.
    // To improve compatibilty with Windows, we use |event->hardware_keycode|
    // for retrieving its Windows key-code for the keys when the
    // WebCore::windowsKeyCodeForEvent() call returns 0.
    // We shouldn't use |event->hardware_keycode| for keys that GdkKeymap
    // objects cannot change because |event->hardware_keycode| doesn't change
    // even when we change the layout options, e.g. when we swap a control
    // key and a caps-lock key, GTK doesn't swap their
    // |event->hardware_keycode| values but swap their |event->keyval| values.
    int windowsKeyCode = WebCore::windowsKeyCodeForKeyEvent(event->keyval);
    if (windowsKeyCode)
        return windowsKeyCode;

    const int tableSize = sizeof(hardwareCodeToGDKKeyval) / sizeof(hardwareCodeToGDKKeyval[0]);
    if (event->hardware_keycode < tableSize) {
        int keyval = hardwareCodeToGDKKeyval[event->hardware_keycode];
        if (keyval)
            return WebCore::windowsKeyCodeForKeyEvent(keyval);
    }

    // This key is one that keyboard-layout drivers cannot change.
    // Use |event->keyval| to retrieve its |windowsKeyCode| value.
    return WebCore::windowsKeyCodeForKeyEvent(event->keyval);
}

// Normalizes event->state to make it Windows/Mac compatible. Since the way
// of setting modifier mask on X is very different than Windows/Mac as shown
// in http://crbug.com/127142#c8, the normalization is necessary.
static guint normalizeEventState(const GdkEventKey* event)
{
    guint mask = 0;
    switch (gdkEventToWindowsKeyCode(event)) {
    case WebCore::VKEY_CONTROL:
    case WebCore::VKEY_LCONTROL:
    case WebCore::VKEY_RCONTROL:
        mask = GDK_CONTROL_MASK;
        break;
    case WebCore::VKEY_SHIFT:
    case WebCore::VKEY_LSHIFT:
    case WebCore::VKEY_RSHIFT:
        mask = GDK_SHIFT_MASK;
        break;
    case WebCore::VKEY_MENU:
    case WebCore::VKEY_LMENU:
    case WebCore::VKEY_RMENU:
        mask = GDK_MOD1_MASK;
        break;
    case WebCore::VKEY_CAPITAL:
        mask = GDK_LOCK_MASK;
        break;
    default:
        return event->state;
    }
    if (event->type == GDK_KEY_PRESS)
        return event->state | mask;
    return event->state & ~mask;
}

// Gets the corresponding control character of a specified key code. See:
// http://en.wikipedia.org/wiki/Control_characters
// We emulate Windows behavior here.
static WebUChar getControlCharacter(int windowsKeyCode, bool shift)
{
    if (windowsKeyCode >= WebCore::VKEY_A && windowsKeyCode <= WebCore::VKEY_Z) {
        // ctrl-A ~ ctrl-Z map to \x01 ~ \x1A
        return windowsKeyCode - WebCore::VKEY_A + 1;
    }
    if (shift) {
        // following graphics chars require shift key to input.
        switch (windowsKeyCode) {
        // ctrl-@ maps to \x00 (Null byte)
        case WebCore::VKEY_2:
            return 0;
        // ctrl-^ maps to \x1E (Record separator, Information separator two)
        case WebCore::VKEY_6:
            return 0x1E;
        // ctrl-_ maps to \x1F (Unit separator, Information separator one)
        case WebCore::VKEY_OEM_MINUS:
            return 0x1F;
        // Returns 0 for all other keys to avoid inputting unexpected chars.
        default:
            return 0;
        }
    } else {
        switch (windowsKeyCode) {
        // ctrl-[ maps to \x1B (Escape)
        case WebCore::VKEY_OEM_4:
            return 0x1B;
        // ctrl-\ maps to \x1C (File separator, Information separator four)
        case WebCore::VKEY_OEM_5:
            return 0x1C;
        // ctrl-] maps to \x1D (Group separator, Information separator three)
        case WebCore::VKEY_OEM_6:
            return 0x1D;
        // ctrl-Enter maps to \x0A (Line feed)
        case WebCore::VKEY_RETURN:
            return 0x0A;
        // Returns 0 for all other keys to avoid inputting unexpected chars.
        default:
            return 0;
        }
    }
}

// WebKeyboardEvent -----------------------------------------------------------

WebKeyboardEvent WebInputEventFactory::keyboardEvent(const GdkEventKey* event)
{
    WebKeyboardEvent result;

    result.timeStampSeconds = gdkEventTimeToWebEventTime(event->time);
    result.modifiers = gdkStateToWebEventModifiers(normalizeEventState(event));

    switch (event->type) {
    case GDK_KEY_RELEASE:
        result.type = WebInputEvent::KeyUp;
        break;
    case GDK_KEY_PRESS:
        result.type = WebInputEvent::RawKeyDown;
        break;
    default:
        ASSERT_NOT_REACHED();
    }

    result.isSystemKey = WebInputEventFactory::isSystemKeyEvent(result);

    // The key code tells us which physical key was pressed (for example, the
    // A key went down or up).  It does not determine whether A should be lower
    // or upper case.  This is what text does, which should be the keyval.
    int windowsKeyCode = gdkEventToWindowsKeyCode(event);
    result.windowsKeyCode = WebKeyboardEvent::windowsKeyCodeWithoutLocation(windowsKeyCode);
    result.modifiers |= WebKeyboardEvent::locationModifiersFromWindowsKeyCode(windowsKeyCode);
    result.nativeKeyCode = event->hardware_keycode;

    if (result.windowsKeyCode == WebCore::VKEY_RETURN)
        // We need to treat the enter key as a key press of character \r.  This
        // is apparently just how webkit handles it and what it expects.
        result.unmodifiedText[0] = '\r';
    else
        // FIXME: fix for non BMP chars
        result.unmodifiedText[0] =
            static_cast<WebUChar>(gdk_keyval_to_unicode(event->keyval));

    // If ctrl key is pressed down, then control character shall be input.
    if (result.modifiers & WebInputEvent::ControlKey)
        result.text[0] = getControlCharacter(
            result.windowsKeyCode, result.modifiers & WebInputEvent::ShiftKey);
    else
        result.text[0] = result.unmodifiedText[0];

    result.setKeyIdentifierFromWindowsKeyCode();

    // FIXME: Do we need to set IsAutoRepeat?
    if (isKeyPadKeyval(event->keyval))
        result.modifiers |= WebInputEvent::IsKeyPad;

    return result;
}

bool WebInputEventFactory::isSystemKeyEvent(const WebKeyboardEvent& event)
{
    // On Windows all keys with Alt modifier will be marked as system key.
    // We keep the same behavior on Linux and everywhere non-Mac.
    return event.modifiers & WebInputEvent::AltKey;
}

WebKeyboardEvent WebInputEventFactory::keyboardEvent(wchar_t character, int state, double timeStampSeconds)
{
    // keyboardEvent(const GdkEventKey*) depends on the GdkEventKey object and
    // it is hard to use/ it from signal handlers which don't use GdkEventKey
    // objects (e.g. GtkIMContext signal handlers.) For such handlers, this
    // function creates a WebInputEvent::Char event without using a
    // GdkEventKey object.
    WebKeyboardEvent result;
    result.type = blink::WebInputEvent::Char;
    result.timeStampSeconds = timeStampSeconds;
    result.modifiers = gdkStateToWebEventModifiers(state);
    result.windowsKeyCode = character;
    result.nativeKeyCode = character;
    result.text[0] = character;
    result.unmodifiedText[0] = character;

    // According to MSDN:
    // http://msdn.microsoft.com/en-us/library/ms646286(VS.85).aspx
    // Key events with Alt modifier and F10 are system key events.
    // We just emulate this behavior. It's necessary to prevent webkit from
    // processing keypress event generated by alt-d, etc.
    // F10 is not special on Linux, so don't treat it as system key.
    if (result.modifiers & WebInputEvent::AltKey)
        result.isSystemKey = true;

    return result;
}

// WebMouseEvent --------------------------------------------------------------

WebMouseEvent WebInputEventFactory::mouseEvent(const GdkEventButton* event)
{
    WebMouseEvent result;

    result.timeStampSeconds = gdkEventTimeToWebEventTime(event->time);

    result.modifiers = gdkStateToWebEventModifiers(event->state);
    result.x = static_cast<int>(event->x);
    result.y = static_cast<int>(event->y);
    result.windowX = result.x;
    result.windowY = result.y;
    result.globalX = static_cast<int>(event->x_root);
    result.globalY = static_cast<int>(event->y_root);
    result.clickCount = 0;

    switch (event->type) {
    case GDK_BUTTON_PRESS:
        result.type = WebInputEvent::MouseDown;
        break;
    case GDK_BUTTON_RELEASE:
        result.type = WebInputEvent::MouseUp;
        break;
    case GDK_3BUTTON_PRESS:
    case GDK_2BUTTON_PRESS:
    default:
        ASSERT_NOT_REACHED();
    };

    result.button = WebMouseEvent::ButtonNone;
    if (event->button == 1)
        result.button = WebMouseEvent::ButtonLeft;
    else if (event->button == 2)
        result.button = WebMouseEvent::ButtonMiddle;
    else if (event->button == 3)
        result.button = WebMouseEvent::ButtonRight;

    if (result.type == WebInputEvent::MouseDown) {
        bool forgetPreviousClick = shouldForgetPreviousClick(event->window, event->time, event->x, event->y);

        if (!forgetPreviousClick && result.button == gLastClickButton)
            ++gNumClicks;
        else {
            gNumClicks = 1;

            gLastClickEventWindow = event->window;
            gLastClickX = event->x;
            gLastClickY = event->y;
            gLastClickButton = result.button;
        }
        gLastClickTime = event->time;
    }
    result.clickCount = gNumClicks;

    return result;
}

WebMouseEvent WebInputEventFactory::mouseEvent(const GdkEventMotion* event)
{
    WebMouseEvent result;

    result.timeStampSeconds = gdkEventTimeToWebEventTime(event->time);
    result.modifiers = gdkStateToWebEventModifiers(event->state);
    result.x = static_cast<int>(event->x);
    result.y = static_cast<int>(event->y);
    result.windowX = result.x;
    result.windowY = result.y;
    result.globalX = static_cast<int>(event->x_root);
    result.globalY = static_cast<int>(event->y_root);

    switch (event->type) {
    case GDK_MOTION_NOTIFY:
        result.type = WebInputEvent::MouseMove;
        break;
    default:
        ASSERT_NOT_REACHED();
    }

    result.button = WebMouseEvent::ButtonNone;
    if (event->state & GDK_BUTTON1_MASK)
        result.button = WebMouseEvent::ButtonLeft;
    else if (event->state & GDK_BUTTON2_MASK)
        result.button = WebMouseEvent::ButtonMiddle;
    else if (event->state & GDK_BUTTON3_MASK)
        result.button = WebMouseEvent::ButtonRight;

    if (shouldForgetPreviousClick(event->window, event->time, event->x, event->y))
        resetClickCountState();

    return result;
}

WebMouseEvent WebInputEventFactory::mouseEvent(const GdkEventCrossing* event)
{
    WebMouseEvent result;

    result.timeStampSeconds = gdkEventTimeToWebEventTime(event->time);
    result.modifiers = gdkStateToWebEventModifiers(event->state);
    result.x = static_cast<int>(event->x);
    result.y = static_cast<int>(event->y);
    result.windowX = result.x;
    result.windowY = result.y;
    result.globalX = static_cast<int>(event->x_root);
    result.globalY = static_cast<int>(event->y_root);

    switch (event->type) {
    case GDK_ENTER_NOTIFY:
    case GDK_LEAVE_NOTIFY:
        // Note that if we sent MouseEnter or MouseLeave to WebKit, it
        // wouldn't work - they don't result in the proper JavaScript events.
        // MouseMove does the right thing.
        result.type = WebInputEvent::MouseMove;
        break;
    default:
        ASSERT_NOT_REACHED();
    }

    result.button = WebMouseEvent::ButtonNone;
    if (event->state & GDK_BUTTON1_MASK)
        result.button = WebMouseEvent::ButtonLeft;
    else if (event->state & GDK_BUTTON2_MASK)
        result.button = WebMouseEvent::ButtonMiddle;
    else if (event->state & GDK_BUTTON3_MASK)
        result.button = WebMouseEvent::ButtonRight;

    if (shouldForgetPreviousClick(event->window, event->time, event->x, event->y))
        resetClickCountState();

    return result;
}

// WebMouseWheelEvent ---------------------------------------------------------

WebMouseWheelEvent WebInputEventFactory::mouseWheelEvent(const GdkEventScroll* event)
{
    WebMouseWheelEvent result;

    result.type = WebInputEvent::MouseWheel;
    result.button = WebMouseEvent::ButtonNone;

    result.timeStampSeconds = gdkEventTimeToWebEventTime(event->time);
    result.modifiers = gdkStateToWebEventModifiers(event->state);
    result.x = static_cast<int>(event->x);
    result.y = static_cast<int>(event->y);
    result.windowX = result.x;
    result.windowY = result.y;
    result.globalX = static_cast<int>(event->x_root);
    result.globalY = static_cast<int>(event->y_root);

    // How much should we scroll per mouse wheel event?
    // - Windows uses 3 lines by default and obeys a system setting.
    // - Mozilla has a pref that lets you either use the "system" number of lines
    //   to scroll, or lets the user override it.
    //   For the "system" number of lines, it appears they've hardcoded 3.
    //   See case NS_MOUSE_SCROLL in content/events/src/nsEventStateManager.cpp
    //   and InitMouseScrollEvent in widget/src/gtk2/nsCommonWidget.cpp .
    // - Gtk makes the scroll amount a function of the size of the scroll bar,
    //   which is not available to us here.
    // Instead, we pick a number that empirically matches Firefox's behavior.
    static const float scrollbarPixelsPerTick = 160.0f / 3.0f;

    switch (event->direction) {
    case GDK_SCROLL_UP:
        result.deltaY = scrollbarPixelsPerTick;
        result.wheelTicksY = 1;
        break;
    case GDK_SCROLL_DOWN:
        result.deltaY = -scrollbarPixelsPerTick;
        result.wheelTicksY = -1;
        break;
    case GDK_SCROLL_LEFT:
        result.deltaX = scrollbarPixelsPerTick;
        result.wheelTicksX = 1;
        break;
    case GDK_SCROLL_RIGHT:
        result.deltaX = -scrollbarPixelsPerTick;
        result.wheelTicksX = -1;
        break;
    }

    return result;
}

} // namespace blink
