/*
 * Copyright (C) 2007, 2008, 2014 Apple Inc. All rights reserved.
 * Copyright (C) 2012 Baidu 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. 
 * 3.  Neither the name of Apple Inc. ("Apple") 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 APPLE 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 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 "EventSender.h"

#include "DRTDataObject.h"
#include "DRTDropSource.h"
#include "DraggingInfo.h"
#include "DumpRenderTree.h"
#include "WebCoreTestSupport.h"

#include <JavaScriptCore/JavaScriptCore.h>
#include <WebCore/COMPtr.h>
#include <WebCore/PlatformWheelEvent.h>
#include <WebKitLegacy/WebFrame.h>
#include <WebKitLegacy/WebKit.h>
#include <windows.h>
#include <wtf/ASCIICType.h>
#include <wtf/Assertions.h>
#include <wtf/Platform.h>
#include <wtf/text/WTFString.h>

#define WM_DRT_SEND_QUEUED_EVENT (WM_APP+1)
#ifndef MAPVK_VK_TO_VSC
#define MAPVK_VK_TO_VSC 0
#endif

static bool down;
static bool dragMode = true;
static bool replayingSavedEvents;
static int timeOffset;
static POINT lastMousePosition;

struct DelayedMessage {
    WTF_MAKE_STRUCT_FAST_ALLOCATED;
    MSG msg;
    unsigned delay;
};

static DelayedMessage msgQueue[1024];
static unsigned endOfQueue;
static unsigned startOfQueue;

static bool didDragEnter;
DraggingInfo* draggingInfo = 0;

static JSValueRef getDragModeCallback(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
{
    return JSValueMakeBoolean(context, dragMode);
}

static bool setDragModeCallback(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
{
    dragMode = JSValueToBoolean(context, value);
    return true;
}

static JSValueRef getConstantCallback(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
{
    if (JSStringIsEqualToUTF8CString(propertyName, "WM_KEYDOWN"))
        return JSValueMakeNumber(context, WM_KEYDOWN);
    if (JSStringIsEqualToUTF8CString(propertyName, "WM_KEYUP"))
        return JSValueMakeNumber(context, WM_KEYUP);
    if (JSStringIsEqualToUTF8CString(propertyName, "WM_CHAR"))
        return JSValueMakeNumber(context, WM_CHAR);
    if (JSStringIsEqualToUTF8CString(propertyName, "WM_DEADCHAR"))
        return JSValueMakeNumber(context, WM_DEADCHAR);
    if (JSStringIsEqualToUTF8CString(propertyName, "WM_SYSKEYDOWN"))
        return JSValueMakeNumber(context, WM_SYSKEYDOWN);
    if (JSStringIsEqualToUTF8CString(propertyName, "WM_SYSKEYUP"))
        return JSValueMakeNumber(context, WM_SYSKEYUP);
    if (JSStringIsEqualToUTF8CString(propertyName, "WM_SYSCHAR"))
        return JSValueMakeNumber(context, WM_SYSCHAR);
    if (JSStringIsEqualToUTF8CString(propertyName, "WM_SYSDEADCHAR"))
        return JSValueMakeNumber(context, WM_SYSDEADCHAR);
    ASSERT_NOT_REACHED();
    return JSValueMakeUndefined(context);
}

static JSValueRef leapForwardCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    if (argumentCount > 0) {
        msgQueue[endOfQueue].delay = JSValueToNumber(context, arguments[0], exception);
        ASSERT(!exception || !*exception);
    }

    return JSValueMakeUndefined(context);
}

static DWORD currentEventTime()
{
    return ::GetTickCount() + timeOffset;
}

static MSG makeMsg(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    MSG result { };
    result.hwnd = hwnd;
    result.message = message;
    result.wParam = wParam;
    result.lParam = lParam;
    result.time = currentEventTime();
    result.pt = lastMousePosition;

    return result;
}

static LRESULT dispatchMessage(const MSG* msg)
{
    ASSERT(msg);
    ::TranslateMessage(msg);
    return ::DispatchMessage(msg);
}

static JSValueRef contextClickCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    COMPtr<IWebFramePrivate> framePrivate;
    if (SUCCEEDED(frame->QueryInterface(&framePrivate)))
        framePrivate->layout();

    down = true;
    MSG msg = makeMsg(webViewWindow, WM_RBUTTONDOWN, 0, MAKELPARAM(lastMousePosition.x, lastMousePosition.y));
    dispatchMessage(&msg);
    down = false;
    msg = makeMsg(webViewWindow, WM_RBUTTONUP, 0, MAKELPARAM(lastMousePosition.x, lastMousePosition.y));
    dispatchMessage(&msg);
    
    return JSValueMakeUndefined(context);
}

static WPARAM buildModifierFlags(JSContextRef context, const JSValueRef modifiers)
{
    JSObjectRef modifiersArray = JSValueToObject(context, modifiers, 0);
    if (!modifiersArray)
        return 0;

    WPARAM flags = 0;
    int modifiersCount = JSValueToNumber(context, JSObjectGetProperty(context, modifiersArray, JSStringCreateWithUTF8CString("length"), 0), 0);
    for (int i = 0; i < modifiersCount; ++i) {
        JSValueRef value = JSObjectGetPropertyAtIndex(context, modifiersArray, i, 0);
        JSStringRef string = JSValueToStringCopy(context, value, 0);
        if (JSStringIsEqualToUTF8CString(string, "ctrlKey")
            || JSStringIsEqualToUTF8CString(string, "addSelectionKey"))
            flags |= MK_CONTROL;
        else if (JSStringIsEqualToUTF8CString(string, "shiftKey")
                 || JSStringIsEqualToUTF8CString(string, "rangeSelectionKey"))
            flags |= MK_SHIFT;
        // No way to specifiy altKey in a MSG.

        JSStringRelease(string);
    }
    return flags;
}

static JSValueRef mouseDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    COMPtr<IWebFramePrivate> framePrivate;
    if (SUCCEEDED(frame->QueryInterface(&framePrivate)))
        framePrivate->layout();

    down = true;
    int mouseType = WM_LBUTTONDOWN;
    if (argumentCount >= 1) {
        int mouseNumber = JSValueToNumber(context, arguments[0], exception);
        switch (mouseNumber) {
        case 0:
            mouseType = WM_LBUTTONDOWN;
            break;
        case 1:
            mouseType = WM_MBUTTONDOWN;
            break;
        case 2:
            mouseType = WM_RBUTTONDOWN;
            break;
        case 3:
            // fast/events/mouse-click-events expects the 4th button has event.button = 1, so send an WM_BUTTONDOWN
            mouseType = WM_MBUTTONDOWN;
            break;
        default:
            mouseType = WM_LBUTTONDOWN;
            break;
        }
    }

    WPARAM wparam = 0;
    if (argumentCount >= 2)
        wparam |= buildModifierFlags(context, arguments[1]);
        
    MSG msg = makeMsg(webViewWindow, mouseType, wparam, MAKELPARAM(lastMousePosition.x, lastMousePosition.y));
    if (!msgQueue[endOfQueue].delay)
        dispatchMessage(&msg);
    else {
        // replaySavedEvents has the required logic to make leapForward delays work
        msgQueue[endOfQueue++].msg = msg;
        replaySavedEvents();
    }

    return JSValueMakeUndefined(context);
}

static inline POINTL pointl(const POINT& point)
{
    POINTL result;
    result.x = point.x;
    result.y = point.y;
    return result;
}

static void doMouseUp(MSG msg, HRESULT* oleDragAndDropReturnValue = 0)
{
    COMPtr<IWebFramePrivate> framePrivate;
    if (SUCCEEDED(frame->QueryInterface(&framePrivate)))
        framePrivate->layout();

    dispatchMessage(&msg);
    down = false;

    if (draggingInfo) {
        COMPtr<IWebView> webView;
        COMPtr<IDropTarget> webViewDropTarget;
        if (SUCCEEDED(frame->webView(&webView)) && SUCCEEDED(webView->QueryInterface(IID_IDropTarget, (void**)&webViewDropTarget))) {
            POINT screenPoint = msg.pt;
            DWORD effect = 0;
            ::ClientToScreen(webViewWindow, &screenPoint);
            if (!didDragEnter) {
                webViewDropTarget->DragEnter(draggingInfo->dataObject(), 0, pointl(screenPoint), &effect);
                didDragEnter = true;
            }
            HRESULT hr = draggingInfo->dropSource()->QueryContinueDrag(0, 0);
            if (oleDragAndDropReturnValue)
                *oleDragAndDropReturnValue = hr;
            webViewDropTarget->DragOver(0, pointl(screenPoint), &effect);
            if (hr == DRAGDROP_S_DROP && effect != DROPEFFECT_NONE) {
                DWORD effect = 0;
                webViewDropTarget->Drop(draggingInfo->dataObject(), 0, pointl(screenPoint), &effect);
                draggingInfo->setPerformedDropEffect(effect);
            } else
                webViewDropTarget->DragLeave();

            // Reset didDragEnter so that another drag started within the same frame works properly.
            didDragEnter = false;
        }
    }
}

static JSValueRef mouseUpCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    int mouseType = WM_LBUTTONUP;
    if (argumentCount >= 1) {
        int mouseNumber = JSValueToNumber(context, arguments[0], exception);
        switch (mouseNumber) {
        case 0:
            mouseType = WM_LBUTTONUP;
            break;
        case 1:
            mouseType = WM_MBUTTONUP;
            break;
        case 2:
            mouseType = WM_RBUTTONUP;
            break;
        case 3:
            // fast/events/mouse-click-events expects the 4th button has event.button = 1, so send an WM_MBUTTONUP
            mouseType = WM_MBUTTONUP;
            break;
        default:
            mouseType = WM_LBUTTONUP;
            break;
        }
    }

    WPARAM wparam = 0;
    if (argumentCount >= 2)
        wparam |= buildModifierFlags(context, arguments[1]);

    MSG msg = makeMsg(webViewWindow, mouseType, wparam, MAKELPARAM(lastMousePosition.x, lastMousePosition.y));

    if ((dragMode && !replayingSavedEvents) || msgQueue[endOfQueue].delay) {
        msgQueue[endOfQueue++].msg = msg;
        replaySavedEvents();
    } else
        doMouseUp(msg);

    return JSValueMakeUndefined(context);
}

static void doMouseMove(MSG msg)
{
    COMPtr<IWebFramePrivate> framePrivate;
    if (SUCCEEDED(frame->QueryInterface(&framePrivate)))
        framePrivate->layout();

    dispatchMessage(&msg);

    if (down && draggingInfo) {
        POINT screenPoint = msg.pt;
        ::ClientToScreen(webViewWindow, &screenPoint);

        IWebView* webView;
        COMPtr<IDropTarget> webViewDropTarget;
        if (SUCCEEDED(frame->webView(&webView)) && SUCCEEDED(webView->QueryInterface(IID_IDropTarget, (void**)&webViewDropTarget))) {
            DWORD effect = 0;
            if (didDragEnter)
                webViewDropTarget->DragOver(MK_LBUTTON, pointl(screenPoint), &effect);
            else {
                webViewDropTarget->DragEnter(draggingInfo->dataObject(), 0, pointl(screenPoint), &effect);
                didDragEnter = true;
            }
            draggingInfo->dropSource()->GiveFeedback(effect);
        }
    }
}

static JSValueRef mouseMoveToCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    if (argumentCount < 2)
        return JSValueMakeUndefined(context);

    lastMousePosition.x = (int)JSValueToNumber(context, arguments[0], exception);
    ASSERT(!exception || !*exception);
    lastMousePosition.y = (int)JSValueToNumber(context, arguments[1], exception);
    ASSERT(!exception || !*exception);

    MSG msg = makeMsg(webViewWindow, WM_MOUSEMOVE, down ? MK_LBUTTON : 0, MAKELPARAM(lastMousePosition.x, lastMousePosition.y));

    if (dragMode && down && !replayingSavedEvents) {
        msgQueue[endOfQueue++].msg = msg;
        return JSValueMakeUndefined(context);
    }

    doMouseMove(msg);

    return JSValueMakeUndefined(context);
}

void replaySavedEvents(HRESULT* oleDragAndDropReturnValue)
{
    replayingSavedEvents = true;
  
    MSG msg { };

    while (startOfQueue < endOfQueue && !msgQueue[startOfQueue].delay) {
        msg = msgQueue[startOfQueue++].msg;
        switch (msg.message) {
            case WM_LBUTTONUP:
            case WM_RBUTTONUP:
            case WM_MBUTTONUP:
                doMouseUp(msg, oleDragAndDropReturnValue);
                break;
            case WM_MOUSEMOVE:
                doMouseMove(msg);
                break;
            case WM_LBUTTONDOWN:
            case WM_RBUTTONDOWN:
            case WM_MBUTTONDOWN:
                dispatchMessage(&msg);
                break;
            default:
                // Not reached
                break;
        }
    }

    int numQueuedMessages = endOfQueue - startOfQueue;
    if (!numQueuedMessages) {
        startOfQueue = 0;
        endOfQueue = 0;
        replayingSavedEvents = false;
        ASSERT(!down);
        return;
    }

    if (msgQueue[startOfQueue].delay) {
        ::Sleep(msgQueue[startOfQueue].delay);
        msgQueue[startOfQueue].delay = 0;
    }

    ::PostMessage(webViewWindow, WM_DRT_SEND_QUEUED_EVENT, 0, 0);
    while (::GetMessage(&msg, webViewWindow, 0, 0)) {
        // FIXME: Why do we get a WM_MOUSELEAVE? it breaks tests
        if (msg.message == WM_MOUSELEAVE)
            continue;
        if (msg.message != WM_DRT_SEND_QUEUED_EVENT) {
            dispatchMessage(&msg);
            continue;
        }
        msg = msgQueue[startOfQueue++].msg;
        switch (msg.message) {
            case WM_LBUTTONUP:
            case WM_RBUTTONUP:
            case WM_MBUTTONUP:
                doMouseUp(msg, oleDragAndDropReturnValue);
                break;
            case WM_MOUSEMOVE:
                doMouseMove(msg);
                break;
            case WM_LBUTTONDOWN:
            case WM_RBUTTONDOWN:
            case WM_MBUTTONDOWN:
                dispatchMessage(&msg);
                break;
            default:
                // Not reached
                break;
        }
        if (startOfQueue >= endOfQueue)
            break;
        ::Sleep(msgQueue[startOfQueue].delay);
        msgQueue[startOfQueue].delay = 0;
        ::PostMessage(webViewWindow, WM_DRT_SEND_QUEUED_EVENT, 0, 0);
    }
    startOfQueue = 0;
    endOfQueue = 0;

    replayingSavedEvents = false;
}

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 JSValueRef keyDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    if (argumentCount < 1)
        return JSValueMakeUndefined(context);

    static const JSStringRef lengthProperty = JSStringCreateWithUTF8CString("length");

    COMPtr<IWebFramePrivate> framePrivate;
    if (SUCCEEDED(frame->QueryInterface(&framePrivate)))
        framePrivate->layout();
    
    JSStringRef character = JSValueToStringCopy(context, arguments[0], exception);
    ASSERT(!*exception);
    int virtualKeyCode = 0;
    int charCode = 0;
    bool needsShiftKeyModifier = false;
    if (JSStringIsEqualToUTF8CString(character, "leftArrow"))
        virtualKeyCode = VK_LEFT;
    else if (JSStringIsEqualToUTF8CString(character, "rightArrow"))
        virtualKeyCode = VK_RIGHT;
    else if (JSStringIsEqualToUTF8CString(character, "upArrow"))
        virtualKeyCode = VK_UP;
    else if (JSStringIsEqualToUTF8CString(character, "downArrow"))
        virtualKeyCode = VK_DOWN;
    else if (JSStringIsEqualToUTF8CString(character, "pageUp"))
        virtualKeyCode = VK_PRIOR;
    else if (JSStringIsEqualToUTF8CString(character, "pageDown"))
        virtualKeyCode = VK_NEXT;
    else if (JSStringIsEqualToUTF8CString(character, "home"))
        virtualKeyCode = VK_HOME;
    else if (JSStringIsEqualToUTF8CString(character, "end"))
        virtualKeyCode = VK_END;
    else if (JSStringIsEqualToUTF8CString(character, "insert"))
        virtualKeyCode = VK_INSERT;
    else if (JSStringIsEqualToUTF8CString(character, "delete"))
        virtualKeyCode = VK_DELETE;
    else if (JSStringIsEqualToUTF8CString(character, "printScreen"))
        virtualKeyCode = VK_SNAPSHOT;
    else if (JSStringIsEqualToUTF8CString(character, "menu"))
        virtualKeyCode = VK_APPS;
    else if (JSStringIsEqualToUTF8CString(character, "leftControl"))
        virtualKeyCode = VK_LCONTROL;
    else if (JSStringIsEqualToUTF8CString(character, "leftShift"))
        virtualKeyCode = VK_LSHIFT;
    else if (JSStringIsEqualToUTF8CString(character, "leftAlt"))
        virtualKeyCode = VK_LMENU;
    else if (JSStringIsEqualToUTF8CString(character, "rightControl"))
        virtualKeyCode = VK_RCONTROL;
    else if (JSStringIsEqualToUTF8CString(character, "rightShift"))
        virtualKeyCode = VK_RSHIFT;
    else if (JSStringIsEqualToUTF8CString(character, "rightAlt"))
        virtualKeyCode = VK_RMENU;
    else {
        size_t characterLength = JSStringGetLength(character);
        static const char shiftedUSCharacters[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ~!@#$%^&*()_+{}|:\"<>?";
        const wchar_t* characterPtr = JSStringGetCharactersPtr(character);
        if (characterLength == 1) {
            charCode = characterPtr[0];
            virtualKeyCode = LOBYTE(VkKeyScan(charCode));
            if (strchr(shiftedUSCharacters, charCode))
                needsShiftKeyModifier = true;
        } else if (characterPtr[0] == 'F') {
            if (characterLength == 2 && isASCIIDigit(characterPtr[1]))
                virtualKeyCode = VK_F1 + characterPtr[1] - '1';
            else if (characterLength == 3 && characterPtr[1] == '1' && isASCIIDigit(characterPtr[2]))
                virtualKeyCode = VK_F10 + characterPtr[2] - '0';
        }
    }
    JSStringRelease(character);

    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;
    }

    BYTE keyState[256];
    if (argumentCount > 1 || needsShiftKeyModifier) {
        ::GetKeyboardState(keyState);

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

        if (needsShiftKeyModifier)
            newKeyState[VK_SHIFT] = 0x80;

        if (argumentCount > 1) {
            JSObjectRef modifiersArray = JSValueToObject(context, arguments[1], 0);
            if (modifiersArray) {
                int modifiersCount = JSValueToNumber(context, JSObjectGetProperty(context, modifiersArray, lengthProperty, 0), 0);
                for (int i = 0; i < modifiersCount; ++i) {
                    JSValueRef value = JSObjectGetPropertyAtIndex(context, modifiersArray, i, 0);
                    JSStringRef string = JSValueToStringCopy(context, value, 0);
                    if (JSStringIsEqualToUTF8CString(string, "ctrlKey") || JSStringIsEqualToUTF8CString(string, "addSelectionKey"))
                        newKeyState[VK_CONTROL] = 0x80;
                    else if (JSStringIsEqualToUTF8CString(string, "shiftKey") || JSStringIsEqualToUTF8CString(string, "rangeSelectionKey"))
                        newKeyState[VK_SHIFT] = 0x80;
                    else if (JSStringIsEqualToUTF8CString(string, "altKey"))
                        newKeyState[VK_MENU] = 0x80;

                    JSStringRelease(string);
                }
            }
        }

        ::SetKeyboardState(newKeyState);
    }

    MSG msg = makeMsg(webViewWindow, (::GetKeyState(VK_MENU) & 0x8000) ? WM_SYSKEYDOWN : WM_KEYDOWN, virtualKeyCode, keyData);
    if (virtualKeyCode != 255)
        dispatchMessage(&msg);
    else {
        // For characters that do not exist in the active keyboard layout,
        // ::Translate will not work, so we post an WM_CHAR event ourselves.
        ::PostMessage(webViewWindow, WM_CHAR, charCode, 0);
    }

    // Tests expect that all messages are processed by the time keyDown() returns.
    if (::PeekMessage(&msg, webViewWindow, WM_CHAR, WM_CHAR, PM_REMOVE) || ::PeekMessage(&msg, webViewWindow, WM_SYSCHAR, WM_SYSCHAR, PM_REMOVE))
        ::DispatchMessage(&msg);

    MSG msgUp = makeMsg(webViewWindow, (::GetKeyState(VK_MENU) & 0x8000) ? WM_SYSKEYUP : WM_KEYUP, virtualKeyCode, keyData);
    ::DispatchMessage(&msgUp);

    if (argumentCount > 1 || needsShiftKeyModifier)
        ::SetKeyboardState(keyState);

    return JSValueMakeUndefined(context);
}

// eventSender.dispatchMessage(message, wParam, lParam, time = currentEventTime(), x = lastMousePosition.x, y = lastMousePosition.y)
static JSValueRef dispatchMessageCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    if (argumentCount < 3)
        return JSValueMakeUndefined(context);

    COMPtr<IWebFramePrivate> framePrivate;
    if (SUCCEEDED(frame->QueryInterface(&framePrivate)))
        framePrivate->layout();
    
    MSG msg = {};
    msg.hwnd = webViewWindow;
    msg.message = JSValueToNumber(context, arguments[0], exception);
    ASSERT(!*exception);
    msg.wParam = JSValueToNumber(context, arguments[1], exception);
    ASSERT(!*exception);
    msg.lParam = static_cast<ULONG_PTR>(JSValueToNumber(context, arguments[2], exception));
    ASSERT(!*exception);
    if (argumentCount >= 4) {
        msg.time = JSValueToNumber(context, arguments[3], exception);
        ASSERT(!*exception);
    }
    if (!msg.time)
        msg.time = currentEventTime();
    if (argumentCount >= 6) {
        msg.pt.x = JSValueToNumber(context, arguments[4], exception);
        ASSERT(!*exception);
        msg.pt.y = JSValueToNumber(context, arguments[5], exception);
        ASSERT(!*exception);
    } else
        msg.pt = lastMousePosition;

    ::DispatchMessage(&msg);

    return JSValueMakeUndefined(context);
}

static JSValueRef textZoomInCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    COMPtr<IWebView> webView;
    if (FAILED(frame->webView(&webView)))
        return JSValueMakeUndefined(context);

    COMPtr<IWebIBActions> webIBActions(Query, webView);
    if (!webIBActions)
        return JSValueMakeUndefined(context);

    webIBActions->makeTextLarger(0);
    return JSValueMakeUndefined(context);
}

static JSValueRef textZoomOutCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    COMPtr<IWebView> webView;
    if (FAILED(frame->webView(&webView)))
        return JSValueMakeUndefined(context);

    COMPtr<IWebIBActions> webIBActions(Query, webView);
    if (!webIBActions)
        return JSValueMakeUndefined(context);

    webIBActions->makeTextSmaller(0);
    return JSValueMakeUndefined(context);
}

static JSValueRef zoomPageInCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    COMPtr<IWebView> webView;
    if (FAILED(frame->webView(&webView)))
        return JSValueMakeUndefined(context);

    COMPtr<IWebIBActions> webIBActions(Query, webView);
    if (!webIBActions)
        return JSValueMakeUndefined(context);

    webIBActions->zoomPageIn(0);
    return JSValueMakeUndefined(context);
}

static JSValueRef zoomPageOutCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    COMPtr<IWebView> webView;
    if (FAILED(frame->webView(&webView)))
        return JSValueMakeUndefined(context);

    COMPtr<IWebIBActions> webIBActions(Query, webView);
    if (!webIBActions)
        return JSValueMakeUndefined(context);

    webIBActions->zoomPageOut(0);
    return JSValueMakeUndefined(context);
}

static JSValueRef beginDragWithFilesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    if (argumentCount < 1)
        return JSValueMakeUndefined(context);

    JSObjectRef filesArray = JSValueToObject(context, arguments[0], 0);

    if (!filesArray)
        return JSValueMakeUndefined(context);

    JSStringRef lengthProperty = JSStringCreateWithUTF8CString("length");
    Vector<UChar> files;
    int filesCount = JSValueToNumber(context, JSObjectGetProperty(context, filesArray, lengthProperty, 0), 0);
    for (int i = 0; i < filesCount; ++i) {
        JSValueRef value = JSObjectGetPropertyAtIndex(context, filesArray, i, 0);
        JSStringRef file = JSValueToStringCopy(context, value, 0);
        files.append(JSStringGetCharactersPtr(file), JSStringGetLength(file));
        files.append(0);
        JSStringRelease(file);
    }

    if (files.isEmpty())
        return JSValueMakeUndefined(context);

    // We should append "0" in the end of |files| so that |DragQueryFileW| retrieved the number of files correctly from Ole Clipboard.
    files.append(0);

    STGMEDIUM hDropMedium { };
    hDropMedium.tymed = TYMED_HGLOBAL;
    SIZE_T dropFilesSize = sizeof(DROPFILES) + (sizeof(WCHAR) * files.size());
    hDropMedium.hGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, dropFilesSize);
    if (!hDropMedium.hGlobal)
        return JSValueMakeUndefined(context);

    DROPFILES* dropFiles = reinterpret_cast<DROPFILES*>(GlobalLock(hDropMedium.hGlobal));
    memset(dropFiles, 0, sizeof(DROPFILES));
    dropFiles->pFiles = sizeof(DROPFILES);
    dropFiles->fWide = TRUE;

    UChar* data = reinterpret_cast<UChar*>(reinterpret_cast<BYTE*>(dropFiles) + sizeof(DROPFILES));
    for (size_t i = 0; i < files.size(); ++i)
        data[i] = files[i];
    GlobalUnlock(hDropMedium.hGlobal); 

    STGMEDIUM hFileNameMedium { };
    hFileNameMedium.tymed = TYMED_HGLOBAL;
    SIZE_T hFileNameSize = sizeof(WCHAR) * files.size();
    hFileNameMedium.hGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, hFileNameSize);
    if (!hFileNameMedium.hGlobal)
        return JSValueMakeUndefined(context);

    WCHAR* hFileName = static_cast<WCHAR*>(GlobalLock(hFileNameMedium.hGlobal));
    for (size_t i = 0; i < files.size(); i++)
        hFileName[i] = files[i];
    GlobalUnlock(hFileNameMedium.hGlobal);

    if (draggingInfo) {
        delete draggingInfo;
        draggingInfo = 0;
    }

    COMPtr<DRTDataObject> dataObeject;
    COMPtr<IDropSource> source;
    if (FAILED(DRTDataObject::createInstance(&dataObeject)))
        dataObeject = 0;

    if (FAILED(DRTDropSource::createInstance(&source)))
        source = 0;

    if (dataObeject && source) {
        draggingInfo = new DraggingInfo(dataObeject.get(), source.get());
        draggingInfo->setPerformedDropEffect(DROPEFFECT_COPY);
    }

    if (draggingInfo) {
        draggingInfo->dataObject()->SetData(cfHDropFormat(), &hDropMedium, FALSE);
        draggingInfo->dataObject()->SetData(cfFileNameWFormat(), &hFileNameMedium, FALSE);
        draggingInfo->dataObject()->SetData(cfUrlWFormat(), &hFileNameMedium, FALSE);
        OleSetClipboard(draggingInfo->dataObject());
        down = true;
    }

    JSStringRelease(lengthProperty);
    return JSValueMakeUndefined(context);
}

static JSValueRef scalePageByCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    if (argumentCount < 1)
        return JSValueMakeUndefined(context);

    COMPtr<IWebView> webView;
    if (FAILED(frame->webView(&webView)))
        return JSValueMakeUndefined(context);

    COMPtr<IWebViewPrivate2> webViewPrivate;
    if (FAILED(webView->QueryInterface(&webViewPrivate)))
        return JSValueMakeUndefined(context);

    POINT origin;
    origin.x = 0;
    origin.y = 0;

    double scale = JSValueToNumber(context, arguments[0], exception);

    if (argumentCount > 1)
        origin.x = JSValueToNumber(context, arguments[1], exception);
    if (argumentCount > 2)
        origin.y = JSValueToNumber(context, arguments[2], exception);

    webViewPrivate->scaleWebView(scale, origin);

    return JSValueMakeUndefined(context);
}

void mouseScrollBy(double x, double y, bool continuous)
{
    RECT rect;
    ::GetWindowRect(webViewWindow, &rect);

    COMPtr<IWebFramePrivate> framePrivate;
    if (SUCCEEDED(frame->QueryInterface(&framePrivate)))
        framePrivate->layout();

    if (x) {
        UINT scrollChars = 1;
        ::SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &scrollChars, 0);
        x *= WHEEL_DELTA / scrollChars;
        if (continuous)
            x /= WebCore::cScrollbarPixelsPerLine;
        MSG msg = makeMsg(webViewWindow, WM_MOUSEHWHEEL, MAKEWPARAM(0, x), MAKELPARAM(rect.left + lastMousePosition.x, rect.top + lastMousePosition.y));
        dispatchMessage(&msg);
    }

    if (y) {
        UINT scrollLines = 3;
        ::SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &scrollLines, 0);
        y *= WHEEL_DELTA / scrollLines;
        if (continuous)
            y /= WebCore::cScrollbarPixelsPerLine;
        MSG msg = makeMsg(webViewWindow, WM_MOUSEWHEEL, MAKEWPARAM(0, y), MAKELPARAM(rect.left + lastMousePosition.x, rect.top + lastMousePosition.y));
        dispatchMessage(&msg);
    }
}

static JSValueRef mouseScrollBy(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    if (argumentCount < 1)
        return JSValueMakeUndefined(context);

    double deltaX = JSValueToNumber(context, arguments[0], exception);

    double deltaY = 0;

    if (argumentCount >= 2)
        deltaY = JSValueToNumber(context, arguments[1], exception);

    mouseScrollBy(deltaX, deltaY, false);

    return JSValueMakeUndefined(context);
}

static JSValueRef mouseScrollByWithWheelAndMomentumPhasesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    return mouseScrollBy(context, function, thisObject, argumentCount, arguments, exception);
}

static JSValueRef continuousMouseScrollBy(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    if (argumentCount < 1)
        return JSValueMakeUndefined(context);

    double deltaX = JSValueToNumber(context, arguments[0], exception);

    double deltaY = 0;

    if (argumentCount >= 2)
        deltaY = JSValueToNumber(context, arguments[1], exception);

    mouseScrollBy(deltaX, deltaY, true);

    return JSValueMakeUndefined(context);
}

static JSValueRef monitorWheelEvents(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    COMPtr<IWebFrame2> frame2;
    if (FAILED(frame->QueryInterface(&frame2)))
        return JSValueMakeUndefined(context);

    WebCore::Frame* coreFrame = core(static_cast<WebFrame*>(frame2.get()));
    WebCoreTestSupport::monitorWheelEvents(*coreFrame);
    
    return JSValueMakeUndefined(context);
}

static JSValueRef callAfterScrollingCompletes(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    if (argumentCount < 1)
        return JSValueMakeUndefined(context);
    
    JSObjectRef jsCallbackFunction = JSValueToObject(context, arguments[0], exception);
    if (!jsCallbackFunction)
        return JSValueMakeUndefined(context);
    
    if (!frame)
        return JSValueMakeUndefined(context);
    
    JSGlobalContextRef globalContext = frame->globalContext();
    
    COMPtr<IWebFrame2> frame2;
    if (FAILED(frame->QueryInterface(&frame2)))
        return JSValueMakeUndefined(context);

    WebCore::Frame* coreFrame = core(static_cast<WebFrame*>(frame2.get()));
    WebCoreTestSupport::setWheelEventMonitorTestCallbackAndStartMonitoring(false, false, *coreFrame, globalContext, jsCallbackFunction);

    return JSValueMakeUndefined(context);
}

static JSStaticFunction staticFunctions[] = {
    { "contextClick", contextClickCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    { "mouseDown", mouseDownCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    { "mouseUp", mouseUpCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    { "mouseMoveTo", mouseMoveToCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    { "leapForward", leapForwardCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    { "keyDown", keyDownCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    { "dispatchMessage", dispatchMessageCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    { "textZoomIn", textZoomInCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    { "textZoomOut", textZoomOutCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    { "zoomPageIn", zoomPageInCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    { "zoomPageOut", zoomPageOutCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    { "beginDragWithFiles", beginDragWithFilesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    { "scalePageBy", scalePageByCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    { "mouseScrollBy", mouseScrollBy, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    { "mouseScrollByWithWheelAndMomentumPhases", mouseScrollByWithWheelAndMomentumPhasesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    { "continuousMouseScrollBy", continuousMouseScrollBy,  kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    { "monitorWheelEvents", monitorWheelEvents, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    { "callAfterScrollingCompletes", callAfterScrollingCompletes, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    { 0, 0, 0 }
};

static JSStaticValue staticValues[] = {
    { "dragMode", getDragModeCallback, setDragModeCallback, kJSPropertyAttributeNone },
    { "WM_KEYDOWN", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone },
    { "WM_KEYUP", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone },
    { "WM_CHAR", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone },
    { "WM_DEADCHAR", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone },
    { "WM_SYSKEYDOWN", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone },
    { "WM_SYSKEYUP", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone },
    { "WM_SYSCHAR", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone },
    { "WM_SYSDEADCHAR", getConstantCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeNone },
    { 0, 0, 0, 0 }
};

static JSClassRef getClass(JSContextRef context)
{
    static JSClassRef eventSenderClass = 0;

    if (!eventSenderClass) {
        JSClassDefinition classDefinition { };
        classDefinition.staticFunctions = staticFunctions;
        classDefinition.staticValues = staticValues;

        eventSenderClass = JSClassCreate(&classDefinition);
    }

    return eventSenderClass;
}

JSObjectRef makeEventSender(JSContextRef context, bool isTopFrame)
{
    if (isTopFrame) {
        down = false;
        dragMode = true;
        replayingSavedEvents = false;
        timeOffset = 0;
        lastMousePosition.x = 0;
        lastMousePosition.y = 0;

        endOfQueue = 0;
        startOfQueue = 0;

        didDragEnter = false;
        draggingInfo = 0;
    }
    return JSObjectMake(context, getClass(context), 0);
}
