/*
 * Copyright (C) 2010, 2011, 2014-2015 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. 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 "EventSendingController.h"

#include "DictionaryFunctions.h"
#include "InjectedBundle.h"
#include "InjectedBundlePage.h"
#include "JSEventSendingController.h"
#include <WebKit/WKBundle.h>
#include <WebKit/WKBundleFrame.h>
#include <WebKit/WKBundlePagePrivate.h>
#include <WebKit/WKBundlePrivate.h>
#include <WebKit/WKContextMenuItem.h>
#include <WebKit/WKMutableDictionary.h>
#include <WebKit/WKNumber.h>
#include <wtf/StdLibExtras.h>

namespace WTR {

static const float ZoomMultiplierRatio = 1.2f;

struct MenuItemPrivateData {
    MenuItemPrivateData(WKBundlePageRef page, WKContextMenuItemRef item) :
        m_page(page),
        m_item(item) { }
    WKBundlePageRef m_page;
    WKRetainPtr<WKContextMenuItemRef> m_item;
};

#if ENABLE(CONTEXT_MENUS)

static JSValueRef menuItemClickCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t, const JSValueRef[], JSValueRef*)
{
    MenuItemPrivateData* privateData = static_cast<MenuItemPrivateData*>(JSObjectGetPrivate(thisObject));
    WKBundlePageClickMenuItem(privateData->m_page, privateData->m_item.get());
    return JSValueMakeUndefined(context);
}

static JSValueRef getMenuItemTitleCallback(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
{
    MenuItemPrivateData* privateData = static_cast<MenuItemPrivateData*>(JSObjectGetPrivate(object));
    auto wkTitle = adoptWK(WKContextMenuItemCopyTitle(privateData->m_item.get()));
    return JSValueMakeString(context, toJS(wkTitle).get());
}

static JSValueRef getMenuItemEnabledCallback(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
{
    auto* privateData = static_cast<MenuItemPrivateData*>(JSObjectGetPrivate(object));
    return JSValueMakeBoolean(context, WKContextMenuItemGetEnabled(privateData->m_item.get()));
}

static JSClassRef getMenuItemClass();

static JSValueRef getMenuItemChildrenCallback(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
{
    MenuItemPrivateData* privateData = static_cast<MenuItemPrivateData*>(JSObjectGetPrivate(object));
    auto children = adoptWK(WKContextMenuCopySubmenuItems(privateData->m_item.get()));
    auto array = JSObjectMakeArray(context, 0, 0, 0);
    for (size_t i = 0; i < WKArrayGetSize(children.get()); ++i) {
        auto item = static_cast<WKContextMenuItemRef>(WKArrayGetItemAtIndex(children.get(), i));
        auto* privateData = new MenuItemPrivateData(InjectedBundle::singleton().page()->page(), item);
        JSObjectSetPropertyAtIndex(context, array, i, JSObjectMake(context, getMenuItemClass(), privateData), 0);
    }
    return array;
}

static JSStaticFunction staticMenuItemFunctions[] = {
    { "click", menuItemClickCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    { 0, 0, 0 }
};

static JSStaticValue staticMenuItemValues[] = {
    { "title", getMenuItemTitleCallback, 0, kJSPropertyAttributeReadOnly },
    { "children", getMenuItemChildrenCallback, 0, kJSPropertyAttributeReadOnly },
    { "enabled", getMenuItemEnabledCallback, 0, kJSPropertyAttributeReadOnly },
    { 0, 0, 0, 0 }
};

static void staticMenuItemFinalize(JSObjectRef object)
{
    delete static_cast<MenuItemPrivateData*>(JSObjectGetPrivate(object));
}

static JSValueRef staticConvertMenuItemToType(JSContextRef context, JSObjectRef object, JSType type, JSValueRef*)
{
    if (kJSTypeString == type)
        return getMenuItemTitleCallback(context, object, 0, 0);
    return 0;
}

static JSClassRef getMenuItemClass()
{
    static JSClassRef menuItemClass = 0;

    if (!menuItemClass) {
        JSClassDefinition classDefinition = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
        classDefinition.staticFunctions = staticMenuItemFunctions;
        classDefinition.staticValues = staticMenuItemValues;
        classDefinition.finalize = staticMenuItemFinalize;
        classDefinition.convertToType = staticConvertMenuItemToType;

        menuItemClass = JSClassCreate(&classDefinition);
    }

    return menuItemClass;
}

#endif

static WKEventModifiers parseModifier(const JSRetainPtr<JSStringRef>& modifier)
{
    if (JSStringIsEqualToUTF8CString(modifier.get(), "ctrlKey"))
        return kWKEventModifiersControlKey;
    if (JSStringIsEqualToUTF8CString(modifier.get(), "shiftKey") || JSStringIsEqualToUTF8CString(modifier.get(), "rangeSelectionKey"))
        return kWKEventModifiersShiftKey;
    if (JSStringIsEqualToUTF8CString(modifier.get(), "altKey"))
        return kWKEventModifiersAltKey;
    if (JSStringIsEqualToUTF8CString(modifier.get(), "metaKey"))
        return kWKEventModifiersMetaKey;
    if (JSStringIsEqualToUTF8CString(modifier.get(), "capsLockKey"))
        return kWKEventModifiersCapsLockKey;
    if (JSStringIsEqualToUTF8CString(modifier.get(), "addSelectionKey")) {
#if OS(MAC_OS_X)
        return kWKEventModifiersMetaKey;
#else
        return kWKEventModifiersControlKey;
#endif
    }
    return 0;
}

#if ENABLE(TOUCH_EVENTS)

static uint64_t parseTouchModifier(JSStringRef modifier)
{
    if (JSStringIsEqualToUTF8CString(modifier, "ctrl"))
        return kWKEventModifiersControlKey;
    if (JSStringIsEqualToUTF8CString(modifier, "shift"))
        return kWKEventModifiersShiftKey;
    if (JSStringIsEqualToUTF8CString(modifier, "alt"))
        return kWKEventModifiersAltKey;
    if (JSStringIsEqualToUTF8CString(modifier, "metaKey"))
        return kWKEventModifiersMetaKey;
    return 0;
}

#endif

static WKEventModifiers parseModifierArray(JSContextRef context, JSValueRef arrayValue)
{
    if (!arrayValue)
        return 0;

    // The value may either be a string with a single modifier or an array of modifiers.
    if (JSValueIsString(context, arrayValue))
        return parseModifier(createJSString(context, arrayValue));

    if (!JSValueIsObject(context, arrayValue))
        return 0;
    JSObjectRef array = const_cast<JSObjectRef>(arrayValue);
    unsigned length = arrayLength(context, array);
    WKEventModifiers modifiers = 0;
    for (unsigned i = 0; i < length; i++) {
        if (auto value = JSObjectGetPropertyAtIndex(context, array, i, nullptr))
            modifiers |= parseModifier(createJSString(context, value));
    }
    return modifiers;
}

static WKEventModifiers parseModifierArray(JSValueRef arrayValue)
{
    return parseModifierArray(WKBundleFrameGetJavaScriptContext(WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page())), arrayValue);
}

Ref<EventSendingController> EventSendingController::create()
{
    return adoptRef(*new EventSendingController);
}

JSClassRef EventSendingController::wrapperClass()
{
    return JSEventSendingController::eventSendingControllerClass();
}

enum MouseState { MouseUp, MouseDown };

static WKRetainPtr<WKDictionaryRef> createMouseMessageBody(MouseState state, int button, WKEventModifiers modifiers, JSStringRef pointerType)
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "SubMessage", state == MouseUp ? "MouseUp" : "MouseDown");
    setValue(body, "Button", adoptWK(WKUInt64Create(button)));
    setValue(body, "Modifiers", adoptWK(WKUInt64Create(modifiers)));
    if (pointerType)
        setValue(body, "PointerType", pointerType);
    return body;
}

void EventSendingController::mouseDown(int button, JSValueRef modifierArray, JSStringRef pointerType)
{
    postSynchronousPageMessage("EventSender", createMouseMessageBody(MouseDown, button, parseModifierArray(modifierArray), pointerType));
}

void EventSendingController::mouseUp(int button, JSValueRef modifierArray, JSStringRef pointerType)
{
    postSynchronousPageMessage("EventSender", createMouseMessageBody(MouseUp, button, parseModifierArray(modifierArray), pointerType));
}

void EventSendingController::mouseMoveTo(int x, int y, JSStringRef pointerType)
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "SubMessage", "MouseMoveTo");
    setValue(body, "X", adoptWK(WKDoubleCreate(x)));
    setValue(body, "Y", adoptWK(WKDoubleCreate(y)));
    if (pointerType)
        setValue(body, "PointerType", pointerType);
    m_position = WKPointMake(x, y);
    postSynchronousPageMessage("EventSender", body);
}

void EventSendingController::mouseForceClick()
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "SubMessage", "MouseForceClick");
    postSynchronousPageMessage("EventSender", body);
}

void EventSendingController::startAndCancelMouseForceClick()
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "SubMessage", "StartAndCancelMouseForceClick");
    postSynchronousPageMessage("EventSender", body);
}

void EventSendingController::mouseForceDown()
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "SubMessage", "MouseForceDown");
    postSynchronousPageMessage("EventSender", body);
}

void EventSendingController::mouseForceUp()
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "SubMessage", "MouseForceUp");
    postSynchronousPageMessage("EventSender", body);
}

void EventSendingController::mouseForceChanged(double force)
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "SubMessage", "MouseForceChanged");
    setValue(body, "Force", force);
    postSynchronousPageMessage("EventSender", body);
}

void EventSendingController::leapForward(int milliseconds)
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "SubMessage", "LeapForward");
    setValue(body, "TimeInMilliseconds", adoptWK(WKUInt64Create(milliseconds)));
    postSynchronousPageMessage("EventSender", body);
}

void EventSendingController::scheduleAsynchronousClick()
{
    postPageMessage("EventSender", createMouseMessageBody(MouseDown, 0, 0, nullptr));
    postPageMessage("EventSender", createMouseMessageBody(MouseUp, 0, 0, nullptr));
}

static WKRetainPtr<WKMutableDictionaryRef> createKeyDownMessageBody(JSStringRef key, WKEventModifiers modifiers, int location)
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "SubMessage", "KeyDown");
    setValue(body, "Key", key);
    setValue(body, "Modifiers", adoptWK(WKUInt64Create(modifiers)));
    setValue(body, "Location", adoptWK(WKUInt64Create(location)));
    return body;
}

void EventSendingController::keyDown(JSStringRef key, JSValueRef modifierArray, int location)
{
    postSynchronousPageMessage("EventSender", createKeyDownMessageBody(key, parseModifierArray(modifierArray), location));
}

void EventSendingController::scheduleAsynchronousKeyDown(JSStringRef key)
{
    postPageMessage("EventSender", createKeyDownMessageBody(key, 0, 0));
}

void EventSendingController::mouseScrollBy(int x, int y)
{
    WKBundlePageForceRepaint(InjectedBundle::singleton().page()->page()); // Triggers a scrolling tree commit.

    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "SubMessage", "MouseScrollBy");
    setValue(body, "X", adoptWK(WKDoubleCreate(x)));
    setValue(body, "Y", adoptWK(WKDoubleCreate(y)));
    postPageMessage("EventSender", body);
}

static uint64_t cgEventPhaseFromString(JSStringRef phaseStr)
{
    if (JSStringIsEqualToUTF8CString(phaseStr, "none"))
        return 0;
    if (JSStringIsEqualToUTF8CString(phaseStr, "began"))
        return 1; // kCGScrollPhaseBegan
    if (JSStringIsEqualToUTF8CString(phaseStr, "changed"))
        return 2; // kCGScrollPhaseChanged
    if (JSStringIsEqualToUTF8CString(phaseStr, "ended"))
        return 4; // kCGScrollPhaseEnded
    if (JSStringIsEqualToUTF8CString(phaseStr, "cancelled"))
        return 8; // kCGScrollPhaseCancelled
    if (JSStringIsEqualToUTF8CString(phaseStr, "maybegin"))
        return 128; // kCGScrollPhaseMayBegin

    ASSERT_NOT_REACHED();
    return 0;
}

static uint64_t cgEventMomentumPhaseFromString(JSStringRef phaseStr)
{
    if (JSStringIsEqualToUTF8CString(phaseStr, "none"))
        return 0; // kCGMomentumScrollPhaseNone
    if (JSStringIsEqualToUTF8CString(phaseStr, "begin"))
        return 1; // kCGMomentumScrollPhaseBegin
    if (JSStringIsEqualToUTF8CString(phaseStr, "continue"))
        return 2; // kCGMomentumScrollPhaseContinue
    if (JSStringIsEqualToUTF8CString(phaseStr, "end"))
        return 3; // kCGMomentumScrollPhaseEnd

    ASSERT_NOT_REACHED();
    return 0;
}

void EventSendingController::mouseScrollByWithWheelAndMomentumPhases(int x, int y, JSStringRef phaseStr, JSStringRef momentumStr)
{
    uint64_t phase = cgEventPhaseFromString(phaseStr);
    uint64_t momentum = cgEventMomentumPhaseFromString(momentumStr);

    if (phase == 4 /* kCGScrollPhaseEnded */ || phase == 8 /* kCGScrollPhaseCancelled */)
        m_sentWheelPhaseEndOrCancel = true;
    if (momentum == 3 /* kCGMomentumScrollPhaseEnd */)
        m_sentWheelMomentumPhaseEnd = true;

    WKBundlePageForceRepaint(InjectedBundle::singleton().page()->page()); // Triggers a scrolling tree commit.

    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "SubMessage", "MouseScrollByWithWheelAndMomentumPhases");
    setValue(body, "X", adoptWK(WKDoubleCreate(x)));
    setValue(body, "Y", adoptWK(WKDoubleCreate(y)));
    setValue(body, "Phase", phase);
    setValue(body, "Momentum", momentum);
    postPageMessage("EventSender", body);
}

void EventSendingController::setWheelHasPreciseDeltas(bool hasPreciseDeltas)
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "SubMessage", "SetWheelHasPreciseDeltas");
    setValue(body, "HasPreciseDeltas", hasPreciseDeltas);
    postPageMessage("EventSender", body);
}

void EventSendingController::continuousMouseScrollBy(int x, int y, bool paged)
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "SubMessage", "ContinuousMouseScrollBy");
    setValue(body, "X", adoptWK(WKDoubleCreate(x)));
    setValue(body, "Y", adoptWK(WKDoubleCreate(y)));
    setValue(body, "Paged", paged);
    // FIXME: This message should be asynchronous, as scrolling is intrinsically asynchronous.
    // See also: <https://bugs.webkit.org/show_bug.cgi?id=148256>.
    postSynchronousPageMessage("EventSender", body);
}

JSValueRef EventSendingController::contextClick()
{
    auto page = InjectedBundle::singleton().page()->page();
    WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(page);
    JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
#if ENABLE(CONTEXT_MENUS)
    auto menuEntries = adoptWK(WKBundlePageCopyContextMenuAtPointInWindow(page, m_position));
    auto array = JSObjectMakeArray(context, 0, 0, 0);
    if (!menuEntries)
        return array;

    size_t entriesSize = WKArrayGetSize(menuEntries.get());
    for (size_t i = 0; i < entriesSize; ++i) {
        ASSERT(WKGetTypeID(WKArrayGetItemAtIndex(menuEntries.get(), i)) == WKContextMenuItemGetTypeID());

        WKContextMenuItemRef item = static_cast<WKContextMenuItemRef>(WKArrayGetItemAtIndex(menuEntries.get(), i));
        MenuItemPrivateData* privateData = new MenuItemPrivateData(page, item);
        JSObjectSetPropertyAtIndex(context, array, i, JSObjectMake(context, getMenuItemClass(), privateData), 0);
    }

    return array;
#else
    return JSValueMakeUndefined(context);
#endif
}

void EventSendingController::textZoomIn()
{
    auto& injectedBundle = InjectedBundle::singleton();
    // Ensure page zoom is reset.
    WKBundlePageSetPageZoomFactor(injectedBundle.page()->page(), 1);

    double zoomFactor = WKBundlePageGetTextZoomFactor(injectedBundle.page()->page());
    WKBundlePageSetTextZoomFactor(injectedBundle.page()->page(), zoomFactor * ZoomMultiplierRatio);
}

void EventSendingController::textZoomOut()
{
    auto& injectedBundle = InjectedBundle::singleton();
    // Ensure page zoom is reset.
    WKBundlePageSetPageZoomFactor(injectedBundle.page()->page(), 1);

    double zoomFactor = WKBundlePageGetTextZoomFactor(injectedBundle.page()->page());
    WKBundlePageSetTextZoomFactor(injectedBundle.page()->page(), zoomFactor / ZoomMultiplierRatio);
}

void EventSendingController::zoomPageIn()
{
    auto& injectedBundle = InjectedBundle::singleton();
    // Ensure text zoom is reset.
    WKBundlePageSetTextZoomFactor(injectedBundle.page()->page(), 1);

    double zoomFactor = WKBundlePageGetPageZoomFactor(injectedBundle.page()->page());
    WKBundlePageSetPageZoomFactor(injectedBundle.page()->page(), zoomFactor * ZoomMultiplierRatio);
}

void EventSendingController::zoomPageOut()
{
    auto& injectedBundle = InjectedBundle::singleton();
    // Ensure text zoom is reset.
    WKBundlePageSetTextZoomFactor(injectedBundle.page()->page(), 1);

    double zoomFactor = WKBundlePageGetPageZoomFactor(injectedBundle.page()->page());
    WKBundlePageSetPageZoomFactor(injectedBundle.page()->page(), zoomFactor / ZoomMultiplierRatio);
}

void EventSendingController::scalePageBy(double scale, double x, double y)
{
    WKPoint origin = { x, y };
    WKBundlePageSetScaleAtOrigin(InjectedBundle::singleton().page()->page(), scale, origin);
}

MonitorWheelEventsOptions* toMonitorWheelEventsOptions(JSContextRef context, JSValueRef argument)
{
    if (!JSValueIsObject(context, argument))
        return nullptr;

    static MonitorWheelEventsOptions options;
    options.resetLatching = booleanProperty(context, (JSObjectRef)argument, "resetLatching", true);
    return &options;
}

void EventSendingController::monitorWheelEvents(MonitorWheelEventsOptions* options)
{
    auto page = InjectedBundle::singleton().page()->page();
    
    m_sentWheelPhaseEndOrCancel = false;
    m_sentWheelMomentumPhaseEnd = false;
    WKBundlePageStartMonitoringScrollOperations(page, options ? options->resetLatching : true);
}

struct ScrollCompletionCallbackData {
    WTF_MAKE_STRUCT_FAST_ALLOCATED;
    JSContextRef m_context;
    JSObjectRef m_function;

    ScrollCompletionCallbackData(JSContextRef context, JSObjectRef function)
        : m_context(context), m_function(function)
    {
    }
};

static void executeCallback(void* context)
{
    if (!context)
        return;

    std::unique_ptr<ScrollCompletionCallbackData> callbackData(reinterpret_cast<ScrollCompletionCallbackData*>(context));

    JSObjectCallAsFunction(callbackData->m_context, callbackData->m_function, nullptr, 0, nullptr, nullptr);
    JSValueUnprotect(callbackData->m_context, callbackData->m_function);
}

void EventSendingController::callAfterScrollingCompletes(JSValueRef functionCallback)
{
    if (!functionCallback)
        return;

    auto page = InjectedBundle::singleton().page()->page();
    WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(page);
    JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
    
    JSObjectRef functionCallbackObject = JSValueToObject(context, functionCallback, nullptr);
    if (!functionCallbackObject)
        return;
    
    JSValueProtect(context, functionCallbackObject);

    auto scrollCompletionCallbackData = makeUnique<ScrollCompletionCallbackData>(context, functionCallbackObject);
    auto scrollCompletionCallbackDataPtr = scrollCompletionCallbackData.release();
    bool callbackWillBeCalled = WKBundlePageRegisterScrollOperationCompletionCallback(page, executeCallback, m_sentWheelPhaseEndOrCancel, m_sentWheelMomentumPhaseEnd, scrollCompletionCallbackDataPtr);
    if (!callbackWillBeCalled) {
        // Reassign raw pointer to std::unique_ptr<> so it will not be leaked.
        scrollCompletionCallbackData.reset(scrollCompletionCallbackDataPtr);
    }
}

#if ENABLE(TOUCH_EVENTS)

void EventSendingController::addTouchPoint(int x, int y)
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "SubMessage", "AddTouchPoint");
    setValue(body, "X", static_cast<uint64_t>(x));
    setValue(body, "Y", static_cast<uint64_t>(y));
    postSynchronousPageMessage("EventSender", body);
}

void EventSendingController::updateTouchPoint(int index, int x, int y)
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "SubMessage", "UpdateTouchPoint");
    setValue(body, "Index", static_cast<uint64_t>(index));
    setValue(body, "X", static_cast<uint64_t>(x));
    setValue(body, "Y", static_cast<uint64_t>(y));
    postSynchronousPageMessage("EventSender", body);
}

void EventSendingController::setTouchModifier(JSStringRef modifier, bool enable)
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "SubMessage", "SetTouchModifier");
    setValue(body, "Modifier", parseTouchModifier(modifier));
    setValue(body, "Enable", enable);
    postSynchronousPageMessage("EventSender", body);
}

void EventSendingController::setTouchPointRadius(int radiusX, int radiusY)
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "SubMessage", "SetTouchPointRadius");
    setValue(body, "RadiusX", static_cast<uint64_t>(radiusX));
    setValue(body, "RadiusY", static_cast<uint64_t>(radiusY));
    postSynchronousPageMessage("EventSender", body);
}

void EventSendingController::touchStart()
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "SubMessage", "TouchStart");
    postSynchronousPageMessage("EventSender", body);
}

void EventSendingController::touchMove()
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "SubMessage", "TouchMove");
    postSynchronousPageMessage("EventSender", body);
}

void EventSendingController::touchEnd()
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "SubMessage", "TouchEnd");
    postSynchronousPageMessage("EventSender", body);
}

void EventSendingController::touchCancel()
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "SubMessage", "TouchCancel");
    postSynchronousPageMessage("EventSender", body);
}

void EventSendingController::clearTouchPoints()
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "SubMessage", "ClearTouchPoints");
    postSynchronousPageMessage("EventSender", body);
}

void EventSendingController::releaseTouchPoint(int index)
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "SubMessage", "ReleaseTouchPoint");
    setValue(body, "Index", static_cast<uint64_t>(index));
    postSynchronousPageMessage("EventSender", body);
}

void EventSendingController::cancelTouchPoint(int index)
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "SubMessage", "CancelTouchPoint");
    setValue(body, "Index", static_cast<uint64_t>(index));
    postSynchronousPageMessage("EventSender", body);
}

#endif

#if ENABLE(MAC_GESTURE_EVENTS)

void EventSendingController::scaleGestureStart(double scale)
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "SubMessage", "ScaleGestureStart");
    setValue(body, "Scale", scale);
    postSynchronousPageMessage("EventSender", body);
}

void EventSendingController::scaleGestureChange(double scale)
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "SubMessage", "ScaleGestureChange");
    setValue(body, "Scale", scale);
    postSynchronousPageMessage("EventSender", body);
}

void EventSendingController::scaleGestureEnd(double scale)
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "SubMessage", "ScaleGestureEnd");
    setValue(body, "Scale", scale);
    postSynchronousPageMessage("EventSender", body);
}

#endif // ENABLE(MAC_GESTURE_EVENTS)

// Object Creation

void EventSendingController::makeWindowObject(JSContextRef context)
{
    setGlobalObjectProperty(context, "eventSender", this);
}

} // namespace WTR
