/*
    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 "JSVTTRegionList.h"

#include "ExceptionCode.h"
#include "JSDOMBinding.h"
#include "JSDOMConvert.h"
#include "JSVTTRegion.h"
#include "VTTRegion.h"
#include <runtime/Error.h>
#include <runtime/PropertyNameArray.h>
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

// Functions

JSC::EncodedJSValue JSC_HOST_CALL jsVTTRegionListPrototypeFunctionItem(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsVTTRegionListPrototypeFunctionGetRegionById(JSC::ExecState*);

// Attributes

JSC::EncodedJSValue jsVTTRegionListLength(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSVTTRegionListConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);

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

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

/* Hash table for prototype */

static const HashTableValue JSVTTRegionListPrototypeTableValues[] =
{
    { "length", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsVTTRegionListLength), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "item", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsVTTRegionListPrototypeFunctionItem), (intptr_t) (1) } },
    { "getRegionById", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsVTTRegionListPrototypeFunctionGetRegionById), (intptr_t) (1) } },
};

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

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

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

JSVTTRegionList::JSVTTRegionList(Structure* structure, JSDOMGlobalObject& globalObject, Ref<VTTRegionList>&& impl)
    : JSDOMWrapper<VTTRegionList>(structure, globalObject, WTFMove(impl))
{
}

JSObject* JSVTTRegionList::createPrototype(VM& vm, JSGlobalObject* globalObject)
{
    return JSVTTRegionListPrototype::create(vm, globalObject, JSVTTRegionListPrototype::createStructure(vm, globalObject, globalObject->objectPrototype()));
}

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

void JSVTTRegionList::destroy(JSC::JSCell* cell)
{
    JSVTTRegionList* thisObject = static_cast<JSVTTRegionList*>(cell);
    thisObject->JSVTTRegionList::~JSVTTRegionList();
}

bool JSVTTRegionList::getOwnPropertySlot(JSObject* object, ExecState* state, PropertyName propertyName, PropertySlot& slot)
{
    auto* thisObject = jsCast<JSVTTRegionList*>(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 JSVTTRegionList::getOwnPropertySlotByIndex(JSObject* object, ExecState* state, unsigned index, PropertySlot& slot)
{
    auto* thisObject = jsCast<JSVTTRegionList*>(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 jsVTTRegionListLength(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<JSVTTRegionList*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "VTTRegionList", "length");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsNumber(impl.length());
    return JSValue::encode(result);
}


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

void JSVTTRegionList::getOwnPropertyNames(JSObject* object, ExecState* state, PropertyNameArray& propertyNames, EnumerationMode mode)
{
    auto* thisObject = jsCast<JSVTTRegionList*>(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);
}

EncodedJSValue JSC_HOST_CALL jsVTTRegionListPrototypeFunctionItem(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSVTTRegionList*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "VTTRegionList", "item");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSVTTRegionList::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 jsVTTRegionListPrototypeFunctionGetRegionById(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSVTTRegionList*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "VTTRegionList", "getRegionById");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSVTTRegionList::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.getRegionById(WTFMove(id)));
    return JSValue::encode(result);
}

bool JSVTTRegionListOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
{
    UNUSED_PARAM(handle);
    UNUSED_PARAM(visitor);
    return false;
}

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

JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject* globalObject, Ref<VTTRegionList>&& impl)
{
#if COMPILER(CLANG)
    // If you hit this failure the interface definition has the ImplementationLacksVTable
    // attribute. You should remove that attribute. If the class has subclasses
    // that may be passed through this toJS() function you should use the SkipVTableValidation
    // attribute to VTTRegionList.
    static_assert(!__is_polymorphic(VTTRegionList), "VTTRegionList is polymorphic but the IDL claims it is not");
#endif
    return createWrapper<VTTRegionList>(globalObject, WTFMove(impl));
}

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

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

}

#endif // ENABLE(VIDEO_TRACK)
