/*
    This file is part of the WebKit open source project.
    This file has been generated by generate-bindings.pl. DO NOT MODIFY!

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#include "config.h"
#include "JSUIEvent.h"

#include "ExceptionCode.h"
#include "JSDOMBinding.h"
#include "JSDOMConstructor.h"
#include "JSDOMConvert.h"
#include "JSDOMWindow.h"
#include "JSDictionary.h"
#include <runtime/Error.h>
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

// Functions

JSC::EncodedJSValue JSC_HOST_CALL jsUIEventPrototypeFunctionInitUIEvent(JSC::ExecState*);

// Attributes

JSC::EncodedJSValue jsUIEventView(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsUIEventDetail(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsUIEventKeyCode(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsUIEventCharCode(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsUIEventLayerX(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsUIEventLayerY(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsUIEventPageX(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsUIEventPageY(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsUIEventWhich(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsUIEventConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSUIEventConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);

class JSUIEventPrototype : public JSC::JSNonFinalObject {
public:
    typedef JSC::JSNonFinalObject Base;
    static JSUIEventPrototype* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
    {
        JSUIEventPrototype* ptr = new (NotNull, JSC::allocateCell<JSUIEventPrototype>(vm.heap)) JSUIEventPrototype(vm, globalObject, structure);
        ptr->finishCreation(vm);
        return ptr;
    }

    DECLARE_INFO;
    static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
    {
        return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
    }

private:
    JSUIEventPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
        : JSC::JSNonFinalObject(vm, structure)
    {
    }

    void finishCreation(JSC::VM&);
};

typedef JSDOMConstructor<JSUIEvent> JSUIEventConstructor;

template<> EncodedJSValue JSC_HOST_CALL JSUIEventConstructor::construct(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    auto* jsConstructor = jsCast<JSUIEventConstructor*>(state->callee());
    ASSERT(jsConstructor);

    if (!jsConstructor->scriptExecutionContext())
        return throwConstructorScriptExecutionContextUnavailableError(*state, throwScope, "UIEvent");

    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));

    AtomicString eventType = state->uncheckedArgument(0).toString(state)->toAtomicString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());

    UIEventInit eventInit;

    JSValue initializerValue = state->argument(1);
    if (!initializerValue.isUndefinedOrNull()) {
        // Given the above test, this will always yield an object.
        JSObject* initializerObject = initializerValue.toObject(state);
        ASSERT(!throwScope.exception());

        // Create the dictionary wrapper from the initializer object.
        JSDictionary dictionary(state, initializerObject);

        // Attempt to fill in the EventInit.
        if (!fillUIEventInit(eventInit, dictionary))
            return JSValue::encode(jsUndefined());
    }

    Ref<UIEvent> event = UIEvent::createForBindings(eventType, eventInit);
    return JSValue::encode(createWrapper<UIEvent>(jsConstructor->globalObject(), WTFMove(event)));
}

bool fillUIEventInit(UIEventInit& eventInit, JSDictionary& dictionary)
{
    if (!fillEventInit(eventInit, dictionary))
        return false;

    if (!dictionary.tryGetProperty("view", eventInit.view))
        return false;
    if (!dictionary.tryGetProperty("detail", eventInit.detail))
        return false;
    return true;
}

template<> JSValue JSUIEventConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
{
    return JSEvent::getConstructor(vm, &globalObject);
}

template<> void JSUIEventConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
{
    putDirect(vm, vm.propertyNames->prototype, JSUIEvent::prototype(vm, &globalObject), DontDelete | ReadOnly | DontEnum);
    putDirect(vm, vm.propertyNames->name, jsNontrivialString(&vm, String(ASCIILiteral("UIEvent"))), ReadOnly | DontEnum);
    putDirect(vm, vm.propertyNames->length, jsNumber(1), ReadOnly | DontEnum);
}

template<> ConstructType JSUIEventConstructor::getConstructData(JSCell* cell, ConstructData& constructData)
{
#if ENABLE(DOM4_EVENTS_CONSTRUCTOR)
    UNUSED_PARAM(cell);
    constructData.native.function = construct;
    return ConstructType::Host;
#else
    return Base::getConstructData(cell, constructData);
#endif
}

template<> const ClassInfo JSUIEventConstructor::s_info = { "UIEvent", &Base::s_info, 0, CREATE_METHOD_TABLE(JSUIEventConstructor) };

/* Hash table for prototype */

static const HashTableValue JSUIEventPrototypeTableValues[] =
{
    { "constructor", DontEnum, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsUIEventConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSUIEventConstructor) } },
    { "view", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsUIEventView), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "detail", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsUIEventDetail), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "keyCode", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsUIEventKeyCode), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "charCode", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsUIEventCharCode), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "layerX", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsUIEventLayerX), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "layerY", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsUIEventLayerY), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "pageX", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsUIEventPageX), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "pageY", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsUIEventPageY), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "which", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsUIEventWhich), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "initUIEvent", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsUIEventPrototypeFunctionInitUIEvent), (intptr_t) (0) } },
};

const ClassInfo JSUIEventPrototype::s_info = { "UIEventPrototype", &Base::s_info, 0, CREATE_METHOD_TABLE(JSUIEventPrototype) };

void JSUIEventPrototype::finishCreation(VM& vm)
{
    Base::finishCreation(vm);
    reifyStaticProperties(vm, JSUIEventPrototypeTableValues, *this);
}

const ClassInfo JSUIEvent::s_info = { "UIEvent", &Base::s_info, 0, CREATE_METHOD_TABLE(JSUIEvent) };

JSUIEvent::JSUIEvent(Structure* structure, JSDOMGlobalObject& globalObject, Ref<UIEvent>&& impl)
    : JSEvent(structure, globalObject, WTFMove(impl))
{
}

JSObject* JSUIEvent::createPrototype(VM& vm, JSGlobalObject* globalObject)
{
    return JSUIEventPrototype::create(vm, globalObject, JSUIEventPrototype::createStructure(vm, globalObject, JSEvent::prototype(vm, globalObject)));
}

JSObject* JSUIEvent::prototype(VM& vm, JSGlobalObject* globalObject)
{
    return getDOMPrototype<JSUIEvent>(vm, globalObject);
}

EncodedJSValue jsUIEventView(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSUIEvent*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "UIEvent", "view");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = toJS(state, castedThis->globalObject(), impl.view());
    return JSValue::encode(result);
}


EncodedJSValue jsUIEventDetail(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSUIEvent*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "UIEvent", "detail");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsNumber(impl.detail());
    return JSValue::encode(result);
}


EncodedJSValue jsUIEventKeyCode(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSUIEvent*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "UIEvent", "keyCode");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsNumber(impl.keyCode());
    return JSValue::encode(result);
}


EncodedJSValue jsUIEventCharCode(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSUIEvent*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "UIEvent", "charCode");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsNumber(impl.charCode());
    return JSValue::encode(result);
}


EncodedJSValue jsUIEventLayerX(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSUIEvent*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "UIEvent", "layerX");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsNumber(impl.layerX());
    return JSValue::encode(result);
}


EncodedJSValue jsUIEventLayerY(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSUIEvent*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "UIEvent", "layerY");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsNumber(impl.layerY());
    return JSValue::encode(result);
}


EncodedJSValue jsUIEventPageX(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSUIEvent*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "UIEvent", "pageX");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsNumber(impl.pageX());
    return JSValue::encode(result);
}


EncodedJSValue jsUIEventPageY(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSUIEvent*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "UIEvent", "pageY");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsNumber(impl.pageY());
    return JSValue::encode(result);
}


EncodedJSValue jsUIEventWhich(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSUIEvent*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "UIEvent", "which");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsNumber(impl.which());
    return JSValue::encode(result);
}


EncodedJSValue jsUIEventConstructor(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    JSUIEventPrototype* domObject = jsDynamicCast<JSUIEventPrototype*>(JSValue::decode(thisValue));
    if (UNLIKELY(!domObject))
        return throwVMTypeError(state, throwScope);
    return JSValue::encode(JSUIEvent::getConstructor(state->vm(), domObject->globalObject()));
}

bool setJSUIEventConstructor(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    JSValue value = JSValue::decode(encodedValue);
    JSUIEventPrototype* domObject = jsDynamicCast<JSUIEventPrototype*>(JSValue::decode(thisValue));
    if (UNLIKELY(!domObject)) {
        throwVMTypeError(state, throwScope);
        return false;
    }
    // Shadowing a built-in constructor
    return domObject->putDirect(state->vm(), state->propertyNames().constructor, value);
}

JSValue JSUIEvent::getConstructor(VM& vm, const JSGlobalObject* globalObject)
{
    return getDOMConstructor<JSUIEventConstructor>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
}

EncodedJSValue JSC_HOST_CALL jsUIEventPrototypeFunctionInitUIEvent(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSUIEvent*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "UIEvent", "initUIEvent");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSUIEvent::info());
    auto& impl = castedThis->wrapped();
    auto type = state->argument(0).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    auto canBubble = state->argument(1).toBoolean(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    auto cancelable = state->argument(2).toBoolean(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    DOMWindow* view = nullptr;
    if (!state->argument(3).isUndefinedOrNull()) {
        view = JSDOMWindow::toWrapped(*state, state->uncheckedArgument(3));
        RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
        if (UNLIKELY(!view))
            return throwArgumentTypeError(*state, throwScope, 3, "view", "UIEvent", "initUIEvent", "DOMWindow");
    }
    auto detail = convert<int32_t>(*state, state->argument(4), NormalConversion);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    impl.initUIEvent(WTFMove(type), WTFMove(canBubble), WTFMove(cancelable), WTFMove(view), WTFMove(detail));
    return JSValue::encode(jsUndefined());
}


}
