/*
    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(INDEXED_DATABASE)

#include "JSIDBVersionChangeEvent.h"

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

using namespace JSC;

namespace WebCore {

// Attributes

JSC::EncodedJSValue jsIDBVersionChangeEventOldVersion(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsIDBVersionChangeEventNewVersion(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsIDBVersionChangeEventConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSIDBVersionChangeEventConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);

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

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

typedef JSDOMConstructor<JSIDBVersionChangeEvent> JSIDBVersionChangeEventConstructor;

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

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

    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());

    IDBVersionChangeEventInit 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 (!fillIDBVersionChangeEventInit(eventInit, dictionary))
            return JSValue::encode(jsUndefined());
    }

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

bool fillIDBVersionChangeEventInit(IDBVersionChangeEventInit& eventInit, JSDictionary& dictionary)
{
    if (!fillEventInit(eventInit, dictionary))
        return false;

    if (!dictionary.tryGetProperty("oldVersion", eventInit.oldVersion))
        return false;
    if (!dictionary.tryGetProperty("newVersion", eventInit.newVersion))
        return false;
    return true;
}

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

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

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

/* Hash table for prototype */

static const HashTableValue JSIDBVersionChangeEventPrototypeTableValues[] =
{
    { "constructor", DontEnum, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsIDBVersionChangeEventConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSIDBVersionChangeEventConstructor) } },
    { "oldVersion", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsIDBVersionChangeEventOldVersion), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "newVersion", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsIDBVersionChangeEventNewVersion), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
};

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

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

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

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

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

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

EncodedJSValue jsIDBVersionChangeEventOldVersion(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<JSIDBVersionChangeEvent*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "IDBVersionChangeEvent", "oldVersion");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsNumber(impl.oldVersion());
    return JSValue::encode(result);
}


EncodedJSValue jsIDBVersionChangeEventNewVersion(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<JSIDBVersionChangeEvent*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "IDBVersionChangeEvent", "newVersion");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = toNullableJSNumber(impl.newVersion());
    return JSValue::encode(result);
}


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

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


}

#endif // ENABLE(INDEXED_DATABASE)
