/*
 * Copyright (C) 2014 Igalia S.L.
 * Copyright (C) 2018 Sony Interactive Entertainment Inc.
 *
 * 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 "EventSenderProxy.h"

#include "PlatformWebView.h"
#include "TestController.h"
#include <WebCore/NotImplemented.h>

namespace WTR {

LRESULT EventSenderProxy::dispatchMessage(UINT message, WPARAM wParam, LPARAM lParam)
{
    MSG msg { };
    msg.hwnd = WKViewGetWindow(m_testController->mainWebView()->platformView());
    msg.message = message;
    msg.wParam = wParam;
    msg.lParam = lParam;
    msg.time = GetTickCount() + static_cast<DWORD>(m_time);
    msg.pt = positionInPoint();

    TranslateMessage(&msg);
    return DispatchMessage(&msg);
}

EventSenderProxy::EventSenderProxy(TestController* testController)
    : m_testController(testController)
    , m_time(0)
    , m_leftMouseButtonDown(false)
    , m_clickCount(0)
    , m_clickTime(0)
    , m_clickButton(kWKEventMouseButtonNoButton)
{
}

EventSenderProxy::~EventSenderProxy()
{
}

void EventSenderProxy::mouseDown(unsigned button, WKEventModifiers wkModifiers)
{
    int messageType;
    switch (button) {
    case 0:
        messageType = WM_LBUTTONDOWN;
        break;
    case 1:
        messageType = WM_MBUTTONDOWN;
        break;
    case 2:
        messageType = WM_RBUTTONDOWN;
        break;
    case 3:
        // fast/events/mouse-click-events expects the 4th button has event.button = 1, so send an WM_MBUTTONDOWN
        messageType = WM_MBUTTONDOWN;
        break;
    default:
        messageType = WM_LBUTTONDOWN;
        break;
    }
    WPARAM wparam = 0;
    dispatchMessage(messageType, wparam, MAKELPARAM(positionInPoint().x, positionInPoint().y));
}

void EventSenderProxy::mouseUp(unsigned button, WKEventModifiers wkModifiers)
{
    int messageType;
    switch (button) {
    case 0:
        messageType = WM_LBUTTONUP;
        break;
    case 1:
        messageType = WM_MBUTTONUP;
        break;
    case 2:
        messageType = WM_RBUTTONUP;
        break;
    case 3:
        // fast/events/mouse-click-events expects the 4th button has event.button = 1, so send an WM_MBUTTONUP
        messageType = WM_MBUTTONUP;
        break;
    default:
        messageType = WM_LBUTTONUP;
        break;
    }
    WPARAM wparam = 0;
    dispatchMessage(messageType, wparam, MAKELPARAM(positionInPoint().x, positionInPoint().y));
}

void EventSenderProxy::mouseMoveTo(double x, double y)
{
    m_position.x = x;
    m_position.y = y;
    dispatchMessage(WM_MOUSEMOVE, 0, MAKELPARAM(positionInPoint().x, positionInPoint().y));
}

void EventSenderProxy::mouseScrollBy(int x, int y)
{
    RECT rect;
    GetWindowRect(WKViewGetWindow(m_testController->mainWebView()->platformView()), &rect);

    if (x) {
        UINT scrollChars = 1;
        SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &scrollChars, 0);
        x *= WHEEL_DELTA / scrollChars;
        dispatchMessage(WM_MOUSEHWHEEL, MAKEWPARAM(0, x), MAKELPARAM(rect.left + positionInPoint().x, rect.top + positionInPoint().y));
    }

    if (y) {
        UINT scrollLines = 3;
        SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &scrollLines, 0);
        y *= WHEEL_DELTA / scrollLines;
        dispatchMessage(WM_MOUSEWHEEL, MAKEWPARAM(0, y), MAKELPARAM(rect.left + positionInPoint().x, rect.top + positionInPoint().y));
    }
}

void EventSenderProxy::mouseScrollByWithWheelAndMomentumPhases(int, int, int, int)
{
    notImplemented();
}

void EventSenderProxy::continuousMouseScrollBy(int, int, bool)
{
}

void EventSenderProxy::leapForward(int milliseconds)
{
    m_time += milliseconds / 1000.0;
}

static unsigned makeKeyDataForScanCode(int virtualKeyCode)
{
    unsigned scancode = MapVirtualKey(virtualKeyCode, MAPVK_VK_TO_VSC);
    int keyData = scancode & 0xFF;

    bool forceExtended = false;
    switch (virtualKeyCode) {
    case VK_LEFT:
    case VK_UP:
    case VK_RIGHT:
    case VK_DOWN:
    case VK_PRIOR:
    case VK_NEXT:
    case VK_END:
    case VK_HOME:
    case VK_INSERT:
    case VK_DELETE:
    case VK_DIVIDE:
    case VK_NUMLOCK:
    case VK_RCONTROL:
    case VK_RMENU:
        // Some keys need to turn on KF_EXTENDED explicitly
        forceExtended = true;
        break;
    default:
        break;
    }

    scancode = scancode >> 8;
    if (scancode == 0xe0 || scancode == 0xe1 || forceExtended)
        keyData += KF_EXTENDED;
    unsigned repeat = 1;
    return keyData << 16 | repeat;
}

static void pumpMessageQueue()
{
    MSG msg;
    while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

void EventSenderProxy::keyDown(WKStringRef keyRef, WKEventModifiers wkModifiers, unsigned location)
{
    int virtualKeyCode = 0;
    int charCode = 0;

    bool needsShiftKeyModifier = false;
    if (WKStringIsEqualToUTF8CString(keyRef, "leftArrow"))
        virtualKeyCode = VK_LEFT;
    else if (WKStringIsEqualToUTF8CString(keyRef, "rightArrow"))
        virtualKeyCode = VK_RIGHT;
    else if (WKStringIsEqualToUTF8CString(keyRef, "upArrow"))
        virtualKeyCode = VK_UP;
    else if (WKStringIsEqualToUTF8CString(keyRef, "downArrow"))
        virtualKeyCode = VK_DOWN;
    else if (WKStringIsEqualToUTF8CString(keyRef, "pageUp"))
        virtualKeyCode = VK_PRIOR;
    else if (WKStringIsEqualToUTF8CString(keyRef, "pageDown"))
        virtualKeyCode = VK_NEXT;
    else if (WKStringIsEqualToUTF8CString(keyRef, "home"))
        virtualKeyCode = VK_HOME;
    else if (WKStringIsEqualToUTF8CString(keyRef, "end"))
        virtualKeyCode = VK_END;
    else if (WKStringIsEqualToUTF8CString(keyRef, "insert"))
        virtualKeyCode = VK_INSERT;
    else if (WKStringIsEqualToUTF8CString(keyRef, "delete"))
        virtualKeyCode = VK_DELETE;
    else if (WKStringIsEqualToUTF8CString(keyRef, "printScreen"))
        virtualKeyCode = VK_SNAPSHOT;
    else if (WKStringIsEqualToUTF8CString(keyRef, "menu"))
        virtualKeyCode = VK_APPS;
    else if (WKStringIsEqualToUTF8CString(keyRef, "leftControl"))
        virtualKeyCode = VK_LCONTROL;
    else if (WKStringIsEqualToUTF8CString(keyRef, "leftShift"))
        virtualKeyCode = VK_LSHIFT;
    else if (WKStringIsEqualToUTF8CString(keyRef, "leftAlt"))
        virtualKeyCode = VK_LMENU;
    else if (WKStringIsEqualToUTF8CString(keyRef, "rightControl"))
        virtualKeyCode = VK_RCONTROL;
    else if (WKStringIsEqualToUTF8CString(keyRef, "rightShift"))
        virtualKeyCode = VK_RSHIFT;
    else if (WKStringIsEqualToUTF8CString(keyRef, "rightAlt"))
        virtualKeyCode = VK_RMENU;
    else {
        size_t keyLength = WKStringGetLength(keyRef);
        static const char shiftedUSCharacters[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ~!@#$%^&*()_+{}|:\"<>?";
        wchar_t keyStr[3];
        WKStringGetCharacters(keyRef, keyStr, _countof(keyStr));
        if (keyLength == 1) {
            charCode = keyStr[0];
            virtualKeyCode = LOBYTE(VkKeyScan(charCode));
            if (strchr(shiftedUSCharacters, charCode))
                needsShiftKeyModifier = true;
        } else if (keyStr[0] == 'F') {
            if (keyLength == 2 && isASCIIDigit(keyStr[1]))
                virtualKeyCode = VK_F1 + keyStr[1] - '1';
            else if (keyLength == 3 && keyStr[1] == '1' && isASCIIDigit(keyStr[2]))
                virtualKeyCode = VK_F10 + keyStr[2] - '0';
        }
    }

    unsigned keyData = makeKeyDataForScanCode(virtualKeyCode);

    switch (virtualKeyCode) {
    case VK_LCONTROL:
    case VK_RCONTROL:
        virtualKeyCode = VK_CONTROL;
        break;
    case VK_LSHIFT:
    case VK_RSHIFT:
        virtualKeyCode = VK_SHIFT;
        break;
    case VK_LMENU:
    case VK_RMENU:
        virtualKeyCode = VK_MENU;
        break;
    default:
        break;
    }

    bool isSysKey = false;
    BYTE keyState[256];
    if (wkModifiers || needsShiftKeyModifier) {
        GetKeyboardState(keyState);

        BYTE newKeyState[256];
        memcpy(newKeyState, keyState, sizeof(keyState));

        if (wkModifiers & kWKEventModifiersControlKey)
            newKeyState[VK_CONTROL] = 0x80;
        if (wkModifiers & kWKEventModifiersShiftKey || needsShiftKeyModifier)
            newKeyState[VK_SHIFT] = 0x80;
        if (wkModifiers & kWKEventModifiersAltKey) {
            newKeyState[VK_MENU] = 0x80;
            isSysKey = true;
        }

        SetKeyboardState(newKeyState);
    }

    if (virtualKeyCode != 255)
        dispatchMessage(isSysKey ? WM_SYSKEYDOWN : WM_KEYDOWN, virtualKeyCode, keyData);
    else {
        // For characters that do not exist in the active keyboard layout,
        // ::TranslateMessage will not work, so we post an WM_CHAR event ourselves.
        dispatchMessage(WM_CHAR, charCode, 0);
    }
    pumpMessageQueue();

    keyData |= (KF_UP | KF_REPEAT) << 16;
    dispatchMessage(isSysKey ? WM_SYSKEYUP : WM_KEYUP, virtualKeyCode, keyData);
    pumpMessageQueue();

    if (wkModifiers || needsShiftKeyModifier)
        SetKeyboardState(keyState);
}

} // namespace WTR
