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

#include "JSTextTrackList.h"

#include "Element.h"
#include "EventNames.h"
#include "ExceptionCode.h"
#include "JSDOMBinding.h"
#include "JSDOMConstructor.h"
#include "JSDOMConvert.h"
#include "JSEventListener.h"
#include "JSNodeCustom.h"
#include "JSTextTrack.h"
#include "TextTrack.h"
#include <runtime/Error.h>
#include <runtime/PropertyNameArray.h>
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

// Functions

JSC::EncodedJSValue JSC_HOST_CALL jsTextTrackListPrototypeFunctionItem(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsTextTrackListPrototypeFunctionGetTrackById(JSC::ExecState*);

// Attributes

JSC::EncodedJSValue jsTextTrackListLength(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsTextTrackListOnaddtrack(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSTextTrackListOnaddtrack(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsTextTrackListOnchange(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSTextTrackListOnchange(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsTextTrackListOnremovetrack(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSTextTrackListOnremovetrack(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsTextTrackListConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSTextTrackListConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);

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

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

typedef JSDOMConstructorNotConstructable<JSTextTrackList> JSTextTrackListConstructor;

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

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

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

/* Hash table for prototype */

static const HashTableValue JSTextTrackListPrototypeTableValues[] =
{
    { "constructor", DontEnum, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTextTrackListConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSTextTrackListConstructor) } },
    { "length", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTextTrackListLength), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "onaddtrack", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTextTrackListOnaddtrack), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSTextTrackListOnaddtrack) } },
    { "onchange", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTextTrackListOnchange), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSTextTrackListOnchange) } },
    { "onremovetrack", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTextTrackListOnremovetrack), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSTextTrackListOnremovetrack) } },
    { "item", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTextTrackListPrototypeFunctionItem), (intptr_t) (1) } },
    { "getTrackById", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTextTrackListPrototypeFunctionGetTrackById), (intptr_t) (1) } },
};

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

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

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

JSTextTrackList::JSTextTrackList(Structure* structure, JSDOMGlobalObject& globalObject, Ref<TextTrackList>&& impl)
    : JSEventTarget(structure, globalObject, WTFMove(impl))
{
}

JSObject* JSTextTrackList::createPrototype(VM& vm, JSGlobalObject* globalObject)
{
    return JSTextTrackListPrototype::create(vm, globalObject, JSTextTrackListPrototype::createStructure(vm, globalObject, JSEventTarget::prototype(vm, globalObject)));
}

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

bool JSTextTrackList::getOwnPropertySlot(JSObject* object, ExecState* state, PropertyName propertyName, PropertySlot& slot)
{
    auto* thisObject = jsCast<JSTextTrackList*>(object);
    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
    Optional<uint32_t> optionalIndex = parseIndex(propertyName);
    if (optionalIndex && optionalIndex.value() < thisObject->wrapped().length()) {
        unsigned index = optionalIndex.value();
        unsigned attributes = ReadOnly;
        slot.setValue(thisObject, attributes, toJS(state, thisObject->globalObject(), thisObject->wrapped().item(index)));
        return true;
    }
    if (Base::getOwnPropertySlot(thisObject, state, propertyName, slot))
        return true;
    return false;
}

bool JSTextTrackList::getOwnPropertySlotByIndex(JSObject* object, ExecState* state, unsigned index, PropertySlot& slot)
{
    auto* thisObject = jsCast<JSTextTrackList*>(object);
    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
    if (LIKELY(index < thisObject->wrapped().length())) {
        unsigned attributes = DontDelete | ReadOnly;
        slot.setValue(thisObject, attributes, toJS(state, thisObject->globalObject(), thisObject->wrapped().item(index)));
        return true;
    }
    return Base::getOwnPropertySlotByIndex(thisObject, state, index, slot);
}

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


EncodedJSValue jsTextTrackListOnaddtrack(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<JSTextTrackList*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "TextTrackList", "onaddtrack");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().addtrackEvent));
}


EncodedJSValue jsTextTrackListOnchange(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<JSTextTrackList*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "TextTrackList", "onchange");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().changeEvent));
}


EncodedJSValue jsTextTrackListOnremovetrack(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<JSTextTrackList*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "TextTrackList", "onremovetrack");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().removetrackEvent));
}


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

bool setJSTextTrackListConstructor(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    JSValue value = JSValue::decode(encodedValue);
    JSTextTrackListPrototype* domObject = jsDynamicCast<JSTextTrackListPrototype*>(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);
}

bool setJSTextTrackListOnaddtrack(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue value = JSValue::decode(encodedValue);
    UNUSED_PARAM(thisValue);
    JSTextTrackList* castedThis = jsDynamicCast<JSTextTrackList*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "TextTrackList", "onaddtrack");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().addtrackEvent, value);
    return true;
}


bool setJSTextTrackListOnchange(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue value = JSValue::decode(encodedValue);
    UNUSED_PARAM(thisValue);
    JSTextTrackList* castedThis = jsDynamicCast<JSTextTrackList*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "TextTrackList", "onchange");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().changeEvent, value);
    return true;
}


bool setJSTextTrackListOnremovetrack(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue value = JSValue::decode(encodedValue);
    UNUSED_PARAM(thisValue);
    JSTextTrackList* castedThis = jsDynamicCast<JSTextTrackList*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "TextTrackList", "onremovetrack");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().removetrackEvent, value);
    return true;
}


void JSTextTrackList::getOwnPropertyNames(JSObject* object, ExecState* state, PropertyNameArray& propertyNames, EnumerationMode mode)
{
    auto* thisObject = jsCast<JSTextTrackList*>(object);
    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
    for (unsigned i = 0, count = thisObject->wrapped().length(); i < count; ++i)
        propertyNames.add(Identifier::from(state, i));
    Base::getOwnPropertyNames(thisObject, state, propertyNames, mode);
}

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

EncodedJSValue JSC_HOST_CALL jsTextTrackListPrototypeFunctionItem(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSTextTrackList*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "TextTrackList", "item");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSTextTrackList::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    auto index = convert<uint32_t>(*state, state->uncheckedArgument(0), NormalConversion);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    JSValue result = toJS(state, castedThis->globalObject(), impl.item(WTFMove(index)));
    return JSValue::encode(result);
}

EncodedJSValue JSC_HOST_CALL jsTextTrackListPrototypeFunctionGetTrackById(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSTextTrackList*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "TextTrackList", "getTrackById");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSTextTrackList::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    auto id = state->uncheckedArgument(0).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    JSValue result = toJS(state, castedThis->globalObject(), impl.getTrackById(WTFMove(id)));
    return JSValue::encode(result);
}

void JSTextTrackList::visitChildren(JSCell* cell, SlotVisitor& visitor)
{
    auto* thisObject = jsCast<JSTextTrackList*>(cell);
    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
    Base::visitChildren(thisObject, visitor);
    thisObject->wrapped().visitJSEventListeners(visitor);
    thisObject->visitAdditionalChildren(visitor);
}

bool JSTextTrackListOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
{
    auto* jsTextTrackList = jsCast<JSTextTrackList*>(handle.slot()->asCell());
    if (jsTextTrackList->wrapped().isFiringEventListeners())
        return true;
    Element* element = WTF::getPtr(jsTextTrackList->wrapped().element());
    if (!element)
        return false;
    void* root = WebCore::root(element);
    return visitor.containsOpaqueRoot(root);
}

void JSTextTrackListOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context)
{
    auto* jsTextTrackList = jsCast<JSTextTrackList*>(handle.slot()->asCell());
    auto& world = *static_cast<DOMWrapperWorld*>(context);
    uncacheWrapper(world, &jsTextTrackList->wrapped(), jsTextTrackList);
}

#if ENABLE(BINDING_INTEGRITY)
#if PLATFORM(WIN)
#pragma warning(disable: 4483)
extern "C" { extern void (*const __identifier("??_7TextTrackList@WebCore@@6B@")[])(); }
#else
extern "C" { extern void* _ZTVN7WebCore13TextTrackListE[]; }
#endif
#endif

JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject* globalObject, Ref<TextTrackList>&& impl)
{

#if ENABLE(BINDING_INTEGRITY)
    void* actualVTablePointer = *(reinterpret_cast<void**>(impl.ptr()));
#if PLATFORM(WIN)
    void* expectedVTablePointer = reinterpret_cast<void*>(__identifier("??_7TextTrackList@WebCore@@6B@"));
#else
    void* expectedVTablePointer = &_ZTVN7WebCore13TextTrackListE[2];
#if COMPILER(CLANG)
    // If this fails TextTrackList does not have a vtable, so you need to add the
    // ImplementationLacksVTable attribute to the interface definition
    static_assert(__is_polymorphic(TextTrackList), "TextTrackList is not polymorphic");
#endif
#endif
    // If you hit this assertion you either have a use after free bug, or
    // TextTrackList has subclasses. If TextTrackList has subclasses that get passed
    // to toJS() we currently require TextTrackList you to opt out of binding hardening
    // by adding the SkipVTableValidation attribute to the interface IDL definition
    RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer);
#endif
    return createWrapper<TextTrackList>(globalObject, WTFMove(impl));
}

JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, TextTrackList& impl)
{
    return wrap(state, globalObject, impl);
}

TextTrackList* JSTextTrackList::toWrapped(JSC::JSValue value)
{
    if (auto* wrapper = jsDynamicCast<JSTextTrackList*>(value))
        return &wrapper->wrapped();
    return nullptr;
}

}

#endif // ENABLE(VIDEO_TRACK)
