/*
 * Copyright (C) 2010 Apple Inc. All rights reserved.
 * 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:
 * 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. AND ITS 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 APPLE INC. OR ITS 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 "WebEventFactory.h"

#include <windowsx.h>
#include <wtf/ASCIICType.h>

using namespace WebCore;

namespace WebKit {

static const unsigned short HIGH_BIT_MASK_SHORT = 0x8000;
static const unsigned short SPI_GETWHEELSCROLLCHARS = 0x006C;

static const unsigned WM_VISTA_MOUSEHWHEEL = 0x20E;

static inline LPARAM relativeCursorPosition(HWND hwnd)
{
    POINT point = { -1, -1 };
    ::GetCursorPos(&point);
    ::ScreenToClient(hwnd, &point);
    return MAKELPARAM(point.x, point.y);
}

static inline POINT point(LPARAM lParam)
{
    POINT point = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
    return point;
}

static int horizontalScrollChars()
{
    static ULONG scrollChars;
    if (!scrollChars && !::SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &scrollChars, 0))
        scrollChars = 1;
    return scrollChars;
}

static int verticalScrollLines()
{
    static ULONG scrollLines;
    if (!scrollLines && !::SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &scrollLines, 0))
        scrollLines = 3;
    return scrollLines;
}

static inline int clickCount(WebEvent::Type type, WebMouseEvent::Button button, const POINT& position, double timeStampSeconds)
{
    static int gLastClickCount;
    static double gLastClickTime;
    static POINT lastClickPosition;
    static WebMouseEvent::Button lastClickButton = WebMouseEvent::LeftButton;

    bool cancelPreviousClick = (abs(lastClickPosition.x - position.x) > (::GetSystemMetrics(SM_CXDOUBLECLK) / 2))
                            || (abs(lastClickPosition.y - position.y) > (::GetSystemMetrics(SM_CYDOUBLECLK) / 2))
                            || ((timeStampSeconds - gLastClickTime) * 1000.0 > ::GetDoubleClickTime());

    if (type == WebEvent::MouseDown) {
        if (!cancelPreviousClick && (button == lastClickButton))
            ++gLastClickCount;
        else {
            gLastClickCount = 1;
            lastClickPosition = position;
        }
        gLastClickTime = timeStampSeconds;
        lastClickButton = button;
    } else if (type == WebEvent::MouseMove) {
        if (cancelPreviousClick) {
            gLastClickCount = 0;
            lastClickPosition.x = 0;
            lastClickPosition.y = 0;
            gLastClickTime = 0;
        }
    }

    return gLastClickCount;
}

static inline WebEvent::Modifiers modifiersForEvent(WPARAM wparam)
{
    unsigned modifiers = 0;
    if (wparam & MK_CONTROL)
        modifiers |= WebEvent::ControlKey;
    if (wparam & MK_SHIFT)
        modifiers |= WebEvent::ShiftKey;
    if (::GetKeyState(VK_MENU) & HIGH_BIT_MASK_SHORT)
        modifiers |= WebEvent::AltKey;
    return static_cast<WebEvent::Modifiers>(modifiers);
}

static inline WebEvent::Modifiers modifiersForCurrentKeyState()
{
    unsigned modifiers = 0;
    if (::GetKeyState(VK_CONTROL) & HIGH_BIT_MASK_SHORT)
        modifiers |= WebEvent::ControlKey;
    if (::GetKeyState(VK_SHIFT) & HIGH_BIT_MASK_SHORT)
        modifiers |= WebEvent::ShiftKey;
    if (::GetKeyState(VK_MENU) & HIGH_BIT_MASK_SHORT)
        modifiers |= WebEvent::AltKey;
    return static_cast<WebEvent::Modifiers>(modifiers);
}

static inline WebEvent::Type keyboardEventTypeForEvent(UINT message)
{
    switch (message) {
    case WM_SYSKEYDOWN:
    case WM_KEYDOWN:
        return WebEvent::RawKeyDown;
        break;
    case WM_SYSKEYUP:
    case WM_KEYUP:
        return WebEvent::KeyUp;
        break;
    case WM_IME_CHAR:
    case WM_SYSCHAR:
    case WM_CHAR:
        return WebEvent::Char;
        break;
    default:
        ASSERT_NOT_REACHED();
        return WebEvent::Char;
    }
}

static inline bool isSystemKeyEvent(UINT message)
{
    switch (message) {
    case WM_SYSKEYDOWN:
    case WM_SYSKEYUP:
    case WM_SYSCHAR:
        return true;
    default:
        return false;
    }
}

static bool isKeypadEvent(WPARAM wParam, LPARAM lParam, WebEvent::Type type)
{
    if (type != WebEvent::RawKeyDown && type != WebEvent::KeyUp)
        return false;

    switch (wParam) {
    case VK_NUMLOCK:
    case VK_NUMPAD0:
    case VK_NUMPAD1:
    case VK_NUMPAD2:
    case VK_NUMPAD3:
    case VK_NUMPAD4:
    case VK_NUMPAD5:
    case VK_NUMPAD6:
    case VK_NUMPAD7:
    case VK_NUMPAD8:
    case VK_NUMPAD9:
    case VK_MULTIPLY:
    case VK_ADD:
    case VK_SEPARATOR:
    case VK_SUBTRACT:
    case VK_DECIMAL:
    case VK_DIVIDE:
        return true;
    case VK_RETURN:
        return HIWORD(lParam) & KF_EXTENDED;
    case VK_INSERT:
    case VK_DELETE:
    case VK_PRIOR:
    case VK_NEXT:
    case VK_END:
    case VK_HOME:
    case VK_LEFT:
    case VK_UP:
    case VK_RIGHT:
    case VK_DOWN:
        return !(HIWORD(lParam) & KF_EXTENDED);
    default:
        return false;
    }
}

static String textFromEvent(WPARAM wparam, WebEvent::Type type)
{
    if (type != WebEvent::Char)
        return String();

    UChar c = static_cast<UChar>(wparam);
    return String(&c, 1);
}

static String unmodifiedTextFromEvent(WPARAM wparam, WebEvent::Type type)
{
    if (type != WebEvent::Char)
        return String();

    UChar c = static_cast<UChar>(wparam);
    return String(&c, 1);
}

static String keyIdentifierFromEvent(WPARAM wparam, WebEvent::Type type)
{
    if (type == WebEvent::Char)
        return String();
    
    unsigned short keyCode = static_cast<unsigned short>(wparam);
    switch (keyCode) {
    case VK_MENU:
        return String("Alt");
    case VK_CONTROL:
        return String("Control");
    case VK_SHIFT:
        return String("Shift");
    case VK_CAPITAL:
        return String("CapsLock");
    case VK_LWIN:
    case VK_RWIN:
        return String("Win");
    case VK_CLEAR:
        return String("Clear");
    case VK_DOWN:
        return String("Down");
    case VK_END:
        return String("End");
    case VK_RETURN:
        return String("Enter");
    case VK_EXECUTE:
        return String("Execute");
    case VK_F1:
        return String("F1");
    case VK_F2:
        return String("F2");
    case VK_F3:
        return String("F3");
    case VK_F4:
        return String("F4");
    case VK_F5:
        return String("F5");
    case VK_F6:
        return String("F6");
    case VK_F7:
        return String("F7");
    case VK_F8:
        return String("F8");
    case VK_F9:
        return String("F9");
    case VK_F10:
        return String("F11");
    case VK_F12:
        return String("F12");
    case VK_F13:
        return String("F13");
    case VK_F14:
        return String("F14");
    case VK_F15:
        return String("F15");
    case VK_F16:
        return String("F16");
    case VK_F17:
        return String("F17");
    case VK_F18:
        return String("F18");
    case VK_F19:
        return String("F19");
    case VK_F20:
        return String("F20");
    case VK_F21:
        return String("F21");
    case VK_F22:
        return String("F22");
    case VK_F23:
        return String("F23");
    case VK_F24:
        return String("F24");
    case VK_HELP:
        return String("Help");
    case VK_HOME:
        return String("Home");
    case VK_INSERT:
        return String("Insert");
    case VK_LEFT:
        return String("Left");
    case VK_NEXT:
        return String("PageDown");
    case VK_PRIOR:
        return String("PageUp");
    case VK_PAUSE:
        return String("Pause");
    case VK_SNAPSHOT:
        return String("PrintScreen");
    case VK_RIGHT:
        return String("Right");
    case VK_SCROLL:
        return String("Scroll");
    case VK_SELECT:
        return String("Select");
    case VK_UP:
        return String("Up");
    case VK_DELETE:
        return String("U+007F"); // Standard says that DEL becomes U+007F.
    default:
        return String::format("U+%04X", toASCIIUpper(keyCode));
    }
}

WebMouseEvent WebEventFactory::createWebMouseEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool didActivateWebView)
{
    WebEvent::Type type;
    WebMouseEvent::Button button = WebMouseEvent::NoButton;
    switch (message) {
    case WM_MOUSEMOVE:
        type = WebEvent::MouseMove;
        if (wParam & MK_LBUTTON)
            button = WebMouseEvent::LeftButton;
        else if (wParam & MK_MBUTTON)
            button = WebMouseEvent::MiddleButton;
        else if (wParam & MK_RBUTTON)
            button = WebMouseEvent::RightButton;
        break;
    case WM_MOUSELEAVE:
        type = WebEvent::MouseMove;
        if (wParam & MK_LBUTTON)
            button = WebMouseEvent::LeftButton;
        else if (wParam & MK_MBUTTON)
            button = WebMouseEvent::MiddleButton;
        else if (wParam & MK_RBUTTON)
            button = WebMouseEvent::RightButton;

        // Set the current mouse position (relative to the client area of the
        // current window) since none is specified for this event.
        lParam = relativeCursorPosition(hWnd);
        break;
    case WM_LBUTTONDOWN:
    case WM_LBUTTONDBLCLK:
        type = WebEvent::MouseDown;
        button = WebMouseEvent::LeftButton;
        break;
    case WM_MBUTTONDOWN:
    case WM_MBUTTONDBLCLK:
        type = WebEvent::MouseDown;
        button = WebMouseEvent::MiddleButton;
        break;
    case WM_RBUTTONDOWN:
    case WM_RBUTTONDBLCLK:
        type = WebEvent::MouseDown;
        button = WebMouseEvent::RightButton;
        break;
    case WM_LBUTTONUP:
        type = WebEvent::MouseUp;
        button = WebMouseEvent::LeftButton;
        break;
    case WM_MBUTTONUP:
        type = WebEvent::MouseUp;
        button = WebMouseEvent::MiddleButton;
        break;
    case WM_RBUTTONUP:
        type = WebEvent::MouseUp;
        button = WebMouseEvent::RightButton;
        break;
    default:
        ASSERT_NOT_REACHED();
        type = WebEvent::KeyDown;
    }

    POINT position = point(lParam);
    POINT globalPosition = position;
    ::ClientToScreen(hWnd, &globalPosition);

    double timestamp = ::GetTickCount() * 0.001; // ::GetTickCount returns milliseconds (Chrome uses GetMessageTime() / 1000.0)

    int clickCount = WebKit::clickCount(type, button, position, timestamp);
    WebEvent::Modifiers modifiers = modifiersForEvent(wParam);

    return WebMouseEvent(type, button, position, globalPosition, 0, 0, 0, clickCount, modifiers, timestamp, didActivateWebView);
}

WebWheelEvent WebEventFactory::createWebWheelEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    // Taken from WebCore
    static const float cScrollbarPixelsPerLine = 100.0f / 3.0f;

    POINT globalPosition = point(lParam);
    POINT position = globalPosition;
    ::ScreenToClient(hWnd, &position);

    WebWheelEvent::Granularity granularity  = WebWheelEvent::ScrollByPixelWheelEvent;

    WebEvent::Modifiers modifiers = modifiersForEvent(wParam);
    double timestamp = ::GetTickCount() * 0.001; // ::GetTickCount returns milliseconds (Chrome uses GetMessageTime() / 1000.0)

    int deltaX = 0;
    int deltaY = 0;
    int wheelTicksX = 0;
    int wheelTicksY = 0;

    float delta = GET_WHEEL_DELTA_WPARAM(wParam) / static_cast<float>(WHEEL_DELTA);
    bool isMouseHWheel = (message == WM_VISTA_MOUSEHWHEEL);
    if (isMouseHWheel) {
        wheelTicksX = delta;
        wheelTicksY = 0;
        delta = -delta;
    } else {
        wheelTicksX = 0;
        wheelTicksY = delta;
    }
    if (isMouseHWheel || (modifiers & WebEvent::ShiftKey)) {
        deltaX = delta * static_cast<float>(horizontalScrollChars()) * cScrollbarPixelsPerLine;
        deltaY = 0;
        granularity = WebWheelEvent::ScrollByPixelWheelEvent;
    } else {
        deltaX = 0;
        deltaY = delta;
        int verticalMultiplier = verticalScrollLines();
        if (verticalMultiplier == WHEEL_PAGESCROLL)
            granularity = WebWheelEvent::ScrollByPageWheelEvent;
        else {
            granularity = WebWheelEvent::ScrollByPixelWheelEvent;
            deltaY *= static_cast<float>(verticalMultiplier) * cScrollbarPixelsPerLine;
        }
    }

    return WebWheelEvent(WebEvent::Wheel, position, globalPosition, FloatSize(deltaX, deltaY), FloatSize(wheelTicksX, wheelTicksY), granularity, modifiers, timestamp);
}

WebKeyboardEvent WebEventFactory::createWebKeyboardEvent(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
    WebEvent::Type type             = keyboardEventTypeForEvent(message);
    String text                     = textFromEvent(wparam, type);
    String unmodifiedText           = unmodifiedTextFromEvent(wparam, type);
    String keyIdentifier            = keyIdentifierFromEvent(wparam, type);
    int windowsVirtualKeyCode       = static_cast<int>(wparam);
    int nativeVirtualKeyCode        = static_cast<int>(wparam);
    int macCharCode                 = 0;
    bool autoRepeat                 = HIWORD(lparam) & KF_REPEAT;
    bool isKeypad                   = isKeypadEvent(wparam, lparam, type);
    bool isSystemKey                = isSystemKeyEvent(message);
    WebEvent::Modifiers modifiers   = modifiersForCurrentKeyState();
    double timestamp                = ::GetTickCount() * 0.001; // ::GetTickCount returns milliseconds (Chrome uses GetMessageTime() / 1000.0)

    return WebKeyboardEvent(type, text, unmodifiedText, keyIdentifier, windowsVirtualKeyCode, nativeVirtualKeyCode, macCharCode, autoRepeat, isKeypad, isSystemKey, modifiers, timestamp);
}

} // namespace WebKit
