/*
    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"
#include "JSSVGLengthList.h"

#include "ExceptionCode.h"
#include "JSDOMBinding.h"
#include "JSDOMConstructor.h"
#include "JSDOMConvert.h"
#include "JSSVGLength.h"
#include "SVGLength.h"
#include <runtime/Error.h>
#include <runtime/FunctionPrototype.h>
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

// Functions

JSC::EncodedJSValue JSC_HOST_CALL jsSVGLengthListPrototypeFunctionClear(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsSVGLengthListPrototypeFunctionInitialize(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsSVGLengthListPrototypeFunctionGetItem(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsSVGLengthListPrototypeFunctionInsertItemBefore(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsSVGLengthListPrototypeFunctionReplaceItem(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsSVGLengthListPrototypeFunctionRemoveItem(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsSVGLengthListPrototypeFunctionAppendItem(JSC::ExecState*);

// Attributes

JSC::EncodedJSValue jsSVGLengthListNumberOfItems(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsSVGLengthListConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSSVGLengthListConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);

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

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

typedef JSDOMConstructorNotConstructable<JSSVGLengthList> JSSVGLengthListConstructor;

template<> JSValue JSSVGLengthListConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
{
    UNUSED_PARAM(vm);
    return globalObject.functionPrototype();
}

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

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

/* Hash table for prototype */

static const HashTableValue JSSVGLengthListPrototypeTableValues[] =
{
    { "constructor", DontEnum, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGLengthListConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSSVGLengthListConstructor) } },
    { "numberOfItems", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGLengthListNumberOfItems), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "clear", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsSVGLengthListPrototypeFunctionClear), (intptr_t) (0) } },
    { "initialize", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsSVGLengthListPrototypeFunctionInitialize), (intptr_t) (1) } },
    { "getItem", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsSVGLengthListPrototypeFunctionGetItem), (intptr_t) (1) } },
    { "insertItemBefore", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsSVGLengthListPrototypeFunctionInsertItemBefore), (intptr_t) (2) } },
    { "replaceItem", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsSVGLengthListPrototypeFunctionReplaceItem), (intptr_t) (2) } },
    { "removeItem", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsSVGLengthListPrototypeFunctionRemoveItem), (intptr_t) (1) } },
    { "appendItem", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsSVGLengthListPrototypeFunctionAppendItem), (intptr_t) (1) } },
};

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

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

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

JSSVGLengthList::JSSVGLengthList(Structure* structure, JSDOMGlobalObject& globalObject, Ref<SVGListPropertyTearOff<SVGLengthList>>&& impl)
    : JSDOMWrapper<SVGListPropertyTearOff<SVGLengthList>>(structure, globalObject, WTFMove(impl))
{
}

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

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

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

EncodedJSValue jsSVGLengthListNumberOfItems(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<JSSVGLengthList*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "SVGLengthList", "numberOfItems");
    }
    JSValue result =  jsNumber(castedThis->wrapped().numberOfItems());
    return JSValue::encode(result);
}


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

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

EncodedJSValue JSC_HOST_CALL jsSVGLengthListPrototypeFunctionClear(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSSVGLengthList*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "SVGLengthList", "clear");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSSVGLengthList::info());
    auto& impl = castedThis->wrapped();
    ExceptionCode ec = 0;
    impl.clear(ec);
    setDOMException(state, throwScope, ec);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsSVGLengthListPrototypeFunctionInitialize(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSSVGLengthList*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "SVGLengthList", "initialize");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSSVGLengthList::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    SVGPropertyTearOff<SVGLength>* item = nullptr;
    if (!state->uncheckedArgument(0).isUndefinedOrNull()) {
        item = JSSVGLength::toWrapped(state->uncheckedArgument(0));
        if (UNLIKELY(!item))
            return throwArgumentTypeError(*state, throwScope, 0, "item", "SVGLengthList", "initialize", "SVGLength");
    }
    JSValue result = toJS(state, castedThis->globalObject(), impl.initialize(WTFMove(item), ec));

    setDOMException(state, throwScope, ec);
    return JSValue::encode(result);
}

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

    setDOMException(state, throwScope, ec);
    return JSValue::encode(result);
}

EncodedJSValue JSC_HOST_CALL jsSVGLengthListPrototypeFunctionInsertItemBefore(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSSVGLengthList*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "SVGLengthList", "insertItemBefore");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSSVGLengthList::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 2))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    SVGPropertyTearOff<SVGLength>* item = nullptr;
    if (!state->uncheckedArgument(0).isUndefinedOrNull()) {
        item = JSSVGLength::toWrapped(state->uncheckedArgument(0));
        if (UNLIKELY(!item))
            return throwArgumentTypeError(*state, throwScope, 0, "item", "SVGLengthList", "insertItemBefore", "SVGLength");
    }
    auto index = convert<uint32_t>(*state, state->uncheckedArgument(1), NormalConversion);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    JSValue result = toJS(state, castedThis->globalObject(), impl.insertItemBefore(WTFMove(item), WTFMove(index), ec));

    setDOMException(state, throwScope, ec);
    return JSValue::encode(result);
}

EncodedJSValue JSC_HOST_CALL jsSVGLengthListPrototypeFunctionReplaceItem(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSSVGLengthList*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "SVGLengthList", "replaceItem");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSSVGLengthList::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 2))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    SVGPropertyTearOff<SVGLength>* item = nullptr;
    if (!state->uncheckedArgument(0).isUndefinedOrNull()) {
        item = JSSVGLength::toWrapped(state->uncheckedArgument(0));
        if (UNLIKELY(!item))
            return throwArgumentTypeError(*state, throwScope, 0, "item", "SVGLengthList", "replaceItem", "SVGLength");
    }
    auto index = convert<uint32_t>(*state, state->uncheckedArgument(1), NormalConversion);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    JSValue result = toJS(state, castedThis->globalObject(), impl.replaceItem(WTFMove(item), WTFMove(index), ec));

    setDOMException(state, throwScope, ec);
    return JSValue::encode(result);
}

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

    setDOMException(state, throwScope, ec);
    return JSValue::encode(result);
}

EncodedJSValue JSC_HOST_CALL jsSVGLengthListPrototypeFunctionAppendItem(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSSVGLengthList*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "SVGLengthList", "appendItem");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSSVGLengthList::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    ExceptionCode ec = 0;
    SVGPropertyTearOff<SVGLength>* item = nullptr;
    if (!state->uncheckedArgument(0).isUndefinedOrNull()) {
        item = JSSVGLength::toWrapped(state->uncheckedArgument(0));
        if (UNLIKELY(!item))
            return throwArgumentTypeError(*state, throwScope, 0, "item", "SVGLengthList", "appendItem", "SVGLength");
    }
    JSValue result = toJS(state, castedThis->globalObject(), impl.appendItem(WTFMove(item), ec));

    setDOMException(state, throwScope, ec);
    return JSValue::encode(result);
}

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

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

JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject* globalObject, Ref<SVGListPropertyTearOff<SVGLengthList>>&& impl)
{
    return createWrapper<SVGListPropertyTearOff<SVGLengthList>>(globalObject, WTFMove(impl));
}

JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, SVGListPropertyTearOff<SVGLengthList>& impl)
{
    return wrap(state, globalObject, impl);
}

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

}
