/*
    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(SVG)

#include "JSSVGPointList.h"

#include "JSSVGPODListCustom.h"
#include "JSSVGPoint.h"
#include "SVGPointList.h"
#include <runtime/Error.h>
#include <runtime/JSNumberCell.h>
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

ASSERT_CLASS_FITS_IN_CELL(JSSVGPointList);

/* Hash table */

static const HashTableValue JSSVGPointListTableValues[3] =
{
    { "numberOfItems", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPointListNumberOfItems), (intptr_t)0 },
    { "constructor", DontEnum|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPointListConstructor), (intptr_t)0 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSSVGPointListTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 3, JSSVGPointListTableValues, 0 };
#else
    { 4, 3, JSSVGPointListTableValues, 0 };
#endif

/* Hash table for constructor */

static const HashTableValue JSSVGPointListConstructorTableValues[1] =
{
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSSVGPointListConstructorTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 0, JSSVGPointListConstructorTableValues, 0 };
#else
    { 1, 0, JSSVGPointListConstructorTableValues, 0 };
#endif

class JSSVGPointListConstructor : public DOMConstructorObject {
public:
    JSSVGPointListConstructor(ExecState* exec, JSDOMGlobalObject* globalObject)
        : DOMConstructorObject(JSSVGPointListConstructor::createStructure(globalObject->objectPrototype()), globalObject)
    {
        putDirect(exec->propertyNames().prototype, JSSVGPointListPrototype::self(exec, globalObject), None);
    }
    virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
    virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
    virtual const ClassInfo* classInfo() const { return &s_info; }
    static const ClassInfo s_info;

    static PassRefPtr<Structure> createStructure(JSValue proto) 
    { 
        return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); 
    }
    
protected:
    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | DOMConstructorObject::StructureFlags;
};

const ClassInfo JSSVGPointListConstructor::s_info = { "SVGPointListConstructor", 0, &JSSVGPointListConstructorTable, 0 };

bool JSSVGPointListConstructor::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticValueSlot<JSSVGPointListConstructor, DOMObject>(exec, &JSSVGPointListConstructorTable, this, propertyName, slot);
}

bool JSSVGPointListConstructor::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    return getStaticValueDescriptor<JSSVGPointListConstructor, DOMObject>(exec, &JSSVGPointListConstructorTable, this, propertyName, descriptor);
}

/* Hash table for prototype */

static const HashTableValue JSSVGPointListPrototypeTableValues[8] =
{
    { "clear", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsSVGPointListPrototypeFunctionClear), (intptr_t)0 },
    { "initialize", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsSVGPointListPrototypeFunctionInitialize), (intptr_t)1 },
    { "getItem", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsSVGPointListPrototypeFunctionGetItem), (intptr_t)1 },
    { "insertItemBefore", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsSVGPointListPrototypeFunctionInsertItemBefore), (intptr_t)2 },
    { "replaceItem", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsSVGPointListPrototypeFunctionReplaceItem), (intptr_t)2 },
    { "removeItem", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsSVGPointListPrototypeFunctionRemoveItem), (intptr_t)1 },
    { "appendItem", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsSVGPointListPrototypeFunctionAppendItem), (intptr_t)1 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSSVGPointListPrototypeTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 63, JSSVGPointListPrototypeTableValues, 0 };
#else
    { 18, 15, JSSVGPointListPrototypeTableValues, 0 };
#endif

const ClassInfo JSSVGPointListPrototype::s_info = { "SVGPointListPrototype", 0, &JSSVGPointListPrototypeTable, 0 };

JSObject* JSSVGPointListPrototype::self(ExecState* exec, JSGlobalObject* globalObject)
{
    return getDOMPrototype<JSSVGPointList>(exec, globalObject);
}

bool JSSVGPointListPrototype::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticFunctionSlot<JSObject>(exec, &JSSVGPointListPrototypeTable, this, propertyName, slot);
}

bool JSSVGPointListPrototype::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    return getStaticFunctionDescriptor<JSObject>(exec, &JSSVGPointListPrototypeTable, this, propertyName, descriptor);
}

const ClassInfo JSSVGPointList::s_info = { "SVGPointList", 0, &JSSVGPointListTable, 0 };

JSSVGPointList::JSSVGPointList(NonNullPassRefPtr<Structure> structure, JSDOMGlobalObject* globalObject, PassRefPtr<SVGPointList> impl)
    : DOMObjectWithGlobalPointer(structure, globalObject)
    , m_impl(impl)
{
}

JSSVGPointList::~JSSVGPointList()
{
    forgetDOMObject(this, impl());
    JSSVGContextCache::forgetWrapper(this);
}

JSObject* JSSVGPointList::createPrototype(ExecState* exec, JSGlobalObject* globalObject)
{
    return new (exec) JSSVGPointListPrototype(JSSVGPointListPrototype::createStructure(globalObject->objectPrototype()));
}

bool JSSVGPointList::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticValueSlot<JSSVGPointList, Base>(exec, &JSSVGPointListTable, this, propertyName, slot);
}

bool JSSVGPointList::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    return getStaticValueDescriptor<JSSVGPointList, Base>(exec, &JSSVGPointListTable, this, propertyName, descriptor);
}

JSValue jsSVGPointListNumberOfItems(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSSVGPointList* castedThis = static_cast<JSSVGPointList*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    SVGPointList* imp = static_cast<SVGPointList*>(castedThis->impl());
    JSValue result = jsNumber(exec, imp->numberOfItems());
    return result;
}

JSValue jsSVGPointListConstructor(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSSVGPointList* domObject = static_cast<JSSVGPointList*>(asObject(slotBase));
    return JSSVGPointList::getConstructor(exec, domObject->globalObject());
}
JSValue JSSVGPointList::getConstructor(ExecState* exec, JSGlobalObject* globalObject)
{
    return getDOMConstructor<JSSVGPointListConstructor>(exec, static_cast<JSDOMGlobalObject*>(globalObject));
}

JSValue JSC_HOST_CALL jsSVGPointListPrototypeFunctionClear(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSSVGPointList::s_info))
        return throwError(exec, TypeError);
    JSSVGPointList* castedThisObj = static_cast<JSSVGPointList*>(asObject(thisValue));
    return JSSVGPODListCustom::clear<JSSVGPointList, FloatPoint>(castedThisObj, exec, args, toSVGPoint);
}

JSValue JSC_HOST_CALL jsSVGPointListPrototypeFunctionInitialize(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSSVGPointList::s_info))
        return throwError(exec, TypeError);
    JSSVGPointList* castedThisObj = static_cast<JSSVGPointList*>(asObject(thisValue));
    return JSSVGPODListCustom::initialize<JSSVGPointList, FloatPoint>(castedThisObj, exec, args, toSVGPoint);
}

JSValue JSC_HOST_CALL jsSVGPointListPrototypeFunctionGetItem(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSSVGPointList::s_info))
        return throwError(exec, TypeError);
    JSSVGPointList* castedThisObj = static_cast<JSSVGPointList*>(asObject(thisValue));
    return JSSVGPODListCustom::getItem<JSSVGPointList, FloatPoint>(castedThisObj, exec, args, toSVGPoint);
}

JSValue JSC_HOST_CALL jsSVGPointListPrototypeFunctionInsertItemBefore(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSSVGPointList::s_info))
        return throwError(exec, TypeError);
    JSSVGPointList* castedThisObj = static_cast<JSSVGPointList*>(asObject(thisValue));
    return JSSVGPODListCustom::insertItemBefore<JSSVGPointList, FloatPoint>(castedThisObj, exec, args, toSVGPoint);
}

JSValue JSC_HOST_CALL jsSVGPointListPrototypeFunctionReplaceItem(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSSVGPointList::s_info))
        return throwError(exec, TypeError);
    JSSVGPointList* castedThisObj = static_cast<JSSVGPointList*>(asObject(thisValue));
    return JSSVGPODListCustom::replaceItem<JSSVGPointList, FloatPoint>(castedThisObj, exec, args, toSVGPoint);
}

JSValue JSC_HOST_CALL jsSVGPointListPrototypeFunctionRemoveItem(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSSVGPointList::s_info))
        return throwError(exec, TypeError);
    JSSVGPointList* castedThisObj = static_cast<JSSVGPointList*>(asObject(thisValue));
    return JSSVGPODListCustom::removeItem<JSSVGPointList, FloatPoint>(castedThisObj, exec, args, toSVGPoint);
}

JSValue JSC_HOST_CALL jsSVGPointListPrototypeFunctionAppendItem(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSSVGPointList::s_info))
        return throwError(exec, TypeError);
    JSSVGPointList* castedThisObj = static_cast<JSSVGPointList*>(asObject(thisValue));
    return JSSVGPODListCustom::appendItem<JSSVGPointList, FloatPoint>(castedThisObj, exec, args, toSVGPoint);
}

JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, SVGPointList* object, SVGElement* context)
{
    return getDOMObjectWrapper<JSSVGPointList>(exec, globalObject, object, context);
}
SVGPointList* toSVGPointList(JSC::JSValue value)
{
    return value.inherits(&JSSVGPointList::s_info) ? static_cast<JSSVGPointList*>(asObject(value))->impl() : 0;
}

}

#endif // ENABLE(SVG)
