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

#include "JSWebKitPlaybackTargetAvailabilityEvent.h"

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

using namespace JSC;

namespace WebCore {

// Attributes

JSC::EncodedJSValue jsWebKitPlaybackTargetAvailabilityEventAvailability(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsWebKitPlaybackTargetAvailabilityEventConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSWebKitPlaybackTargetAvailabilityEventConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);

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

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

typedef JSDOMConstructor<JSWebKitPlaybackTargetAvailabilityEvent> JSWebKitPlaybackTargetAvailabilityEventConstructor;

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

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

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

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

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

bool fillWebKitPlaybackTargetAvailabilityEventInit(WebKitPlaybackTargetAvailabilityEventInit& eventInit, JSDictionary& dictionary)
{
    if (!fillEventInit(eventInit, dictionary))
        return false;

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

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

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

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

/* Hash table for prototype */

static const HashTableValue JSWebKitPlaybackTargetAvailabilityEventPrototypeTableValues[] =
{
    { "constructor", DontEnum, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsWebKitPlaybackTargetAvailabilityEventConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSWebKitPlaybackTargetAvailabilityEventConstructor) } },
    { "availability", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsWebKitPlaybackTargetAvailabilityEventAvailability), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
};

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

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

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

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

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

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

EncodedJSValue jsWebKitPlaybackTargetAvailabilityEventAvailability(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<JSWebKitPlaybackTargetAvailabilityEvent*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "WebKitPlaybackTargetAvailabilityEvent", "availability");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.availability());
    return JSValue::encode(result);
}


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

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


}

#endif // ENABLE(WIRELESS_PLAYBACK_TARGET)
