/*
    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"

#if ENABLE(DEVICE_ORIENTATION)

#include "JSDeviceMotionEvent.h"

#include "JSDOMBinding.h"
#include "JSDOMConstructor.h"
#include <runtime/Error.h>
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

// Functions

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

// Attributes

JSC::EncodedJSValue jsDeviceMotionEventAcceleration(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsDeviceMotionEventAccelerationIncludingGravity(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsDeviceMotionEventRotationRate(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsDeviceMotionEventInterval(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsDeviceMotionEventConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSDeviceMotionEventConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);

class JSDeviceMotionEventPrototype : public JSC::JSNonFinalObject {
public:
    typedef JSC::JSNonFinalObject Base;
    static JSDeviceMotionEventPrototype* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
    {
        JSDeviceMotionEventPrototype* ptr = new (NotNull, JSC::allocateCell<JSDeviceMotionEventPrototype>(vm.heap)) JSDeviceMotionEventPrototype(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:
    JSDeviceMotionEventPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
        : JSC::JSNonFinalObject(vm, structure)
    {
    }

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

typedef JSDOMConstructorNotConstructable<JSDeviceMotionEvent> JSDeviceMotionEventConstructor;

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

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

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

/* Hash table for prototype */

static const HashTableValue JSDeviceMotionEventPrototypeTableValues[] =
{
    { "constructor", DontEnum, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsDeviceMotionEventConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSDeviceMotionEventConstructor) } },
    { "acceleration", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsDeviceMotionEventAcceleration), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "accelerationIncludingGravity", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsDeviceMotionEventAccelerationIncludingGravity), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "rotationRate", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsDeviceMotionEventRotationRate), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "interval", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsDeviceMotionEventInterval), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "initDeviceMotionEvent", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsDeviceMotionEventPrototypeFunctionInitDeviceMotionEvent), (intptr_t) (0) } },
};

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

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

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

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

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

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

EncodedJSValue jsDeviceMotionEventAcceleration(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<JSDeviceMotionEvent*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "DeviceMotionEvent", "acceleration");
    }
    return JSValue::encode(castedThis->acceleration(*state));
}


EncodedJSValue jsDeviceMotionEventAccelerationIncludingGravity(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<JSDeviceMotionEvent*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "DeviceMotionEvent", "accelerationIncludingGravity");
    }
    return JSValue::encode(castedThis->accelerationIncludingGravity(*state));
}


EncodedJSValue jsDeviceMotionEventRotationRate(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<JSDeviceMotionEvent*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "DeviceMotionEvent", "rotationRate");
    }
    return JSValue::encode(castedThis->rotationRate(*state));
}


EncodedJSValue jsDeviceMotionEventInterval(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<JSDeviceMotionEvent*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "DeviceMotionEvent", "interval");
    }
    return JSValue::encode(castedThis->interval(*state));
}


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

bool setJSDeviceMotionEventConstructor(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    JSValue value = JSValue::decode(encodedValue);
    JSDeviceMotionEventPrototype* domObject = jsDynamicCast<JSDeviceMotionEventPrototype*>(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 JSDeviceMotionEvent::getConstructor(VM& vm, const JSGlobalObject* globalObject)
{
    return getDOMConstructor<JSDeviceMotionEventConstructor>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
}

EncodedJSValue JSC_HOST_CALL jsDeviceMotionEventPrototypeFunctionInitDeviceMotionEvent(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSDeviceMotionEvent*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "DeviceMotionEvent", "initDeviceMotionEvent");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSDeviceMotionEvent::info());
    return JSValue::encode(castedThis->initDeviceMotionEvent(*state));
}


}

#endif // ENABLE(DEVICE_ORIENTATION)
