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

#include "CSSMutableStyleDeclaration.h"
#include "CSSStyleDeclaration.h"
#include "CSSValue.h"
#include "JSCSSStyleDeclaration.h"
#include "JSCSSValue.h"
#include "JSSVGAnimatedBoolean.h"
#include "JSSVGAnimatedString.h"
#include "JSSVGAnimatedTransformList.h"
#include "JSSVGElement.h"
#include "JSSVGMatrix.h"
#include "JSSVGPointList.h"
#include "JSSVGRect.h"
#include "JSSVGStringList.h"
#include "KURL.h"
#include "SVGElement.h"
#include "SVGPointList.h"
#include "SVGPolylineElement.h"
#include "SVGStringList.h"
#include <runtime/Error.h>
#include <runtime/JSString.h>
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

ASSERT_CLASS_FITS_IN_CELL(JSSVGPolylineElement);

/* Hash table */

static const HashTableValue JSSVGPolylineElementTableValues[15] =
{
    { "requiredFeatures", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPolylineElementRequiredFeatures), (intptr_t)0 },
    { "requiredExtensions", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPolylineElementRequiredExtensions), (intptr_t)0 },
    { "systemLanguage", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPolylineElementSystemLanguage), (intptr_t)0 },
    { "xmllang", DontDelete, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPolylineElementXmllang), (intptr_t)setJSSVGPolylineElementXmllang },
    { "xmlspace", DontDelete, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPolylineElementXmlspace), (intptr_t)setJSSVGPolylineElementXmlspace },
    { "externalResourcesRequired", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPolylineElementExternalResourcesRequired), (intptr_t)0 },
    { "className", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPolylineElementClassName), (intptr_t)0 },
    { "style", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPolylineElementStyle), (intptr_t)0 },
    { "transform", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPolylineElementTransform), (intptr_t)0 },
    { "nearestViewportElement", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPolylineElementNearestViewportElement), (intptr_t)0 },
    { "farthestViewportElement", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPolylineElementFarthestViewportElement), (intptr_t)0 },
    { "points", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPolylineElementPoints), (intptr_t)0 },
    { "animatedPoints", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPolylineElementAnimatedPoints), (intptr_t)0 },
    { "constructor", DontEnum|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPolylineElementConstructor), (intptr_t)0 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSSVGPolylineElementTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 127, JSSVGPolylineElementTableValues, 0 };
#else
    { 34, 31, JSSVGPolylineElementTableValues, 0 };
#endif

/* Hash table for constructor */

static const HashTableValue JSSVGPolylineElementConstructorTableValues[1] =
{
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSSVGPolylineElementConstructorTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 0, JSSVGPolylineElementConstructorTableValues, 0 };
#else
    { 1, 0, JSSVGPolylineElementConstructorTableValues, 0 };
#endif

class JSSVGPolylineElementConstructor : public DOMConstructorObject {
public:
    JSSVGPolylineElementConstructor(ExecState* exec, JSDOMGlobalObject* globalObject)
        : DOMConstructorObject(JSSVGPolylineElementConstructor::createStructure(globalObject->objectPrototype()), globalObject)
    {
        putDirect(exec->propertyNames().prototype, JSSVGPolylineElementPrototype::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 JSSVGPolylineElementConstructor::s_info = { "SVGPolylineElementConstructor", 0, &JSSVGPolylineElementConstructorTable, 0 };

bool JSSVGPolylineElementConstructor::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticValueSlot<JSSVGPolylineElementConstructor, DOMObject>(exec, &JSSVGPolylineElementConstructorTable, this, propertyName, slot);
}

bool JSSVGPolylineElementConstructor::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    return getStaticValueDescriptor<JSSVGPolylineElementConstructor, DOMObject>(exec, &JSSVGPolylineElementConstructorTable, this, propertyName, descriptor);
}

/* Hash table for prototype */

static const HashTableValue JSSVGPolylineElementPrototypeTableValues[7] =
{
    { "hasExtension", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsSVGPolylineElementPrototypeFunctionHasExtension), (intptr_t)1 },
    { "getPresentationAttribute", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsSVGPolylineElementPrototypeFunctionGetPresentationAttribute), (intptr_t)1 },
    { "getBBox", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsSVGPolylineElementPrototypeFunctionGetBBox), (intptr_t)0 },
    { "getCTM", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsSVGPolylineElementPrototypeFunctionGetCTM), (intptr_t)0 },
    { "getScreenCTM", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsSVGPolylineElementPrototypeFunctionGetScreenCTM), (intptr_t)0 },
    { "getTransformToElement", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsSVGPolylineElementPrototypeFunctionGetTransformToElement), (intptr_t)1 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSSVGPolylineElementPrototypeTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 2047, JSSVGPolylineElementPrototypeTableValues, 0 };
#else
    { 17, 15, JSSVGPolylineElementPrototypeTableValues, 0 };
#endif

const ClassInfo JSSVGPolylineElementPrototype::s_info = { "SVGPolylineElementPrototype", 0, &JSSVGPolylineElementPrototypeTable, 0 };

JSObject* JSSVGPolylineElementPrototype::self(ExecState* exec, JSGlobalObject* globalObject)
{
    return getDOMPrototype<JSSVGPolylineElement>(exec, globalObject);
}

bool JSSVGPolylineElementPrototype::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticFunctionSlot<JSObject>(exec, &JSSVGPolylineElementPrototypeTable, this, propertyName, slot);
}

bool JSSVGPolylineElementPrototype::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    return getStaticFunctionDescriptor<JSObject>(exec, &JSSVGPolylineElementPrototypeTable, this, propertyName, descriptor);
}

const ClassInfo JSSVGPolylineElement::s_info = { "SVGPolylineElement", &JSSVGElement::s_info, &JSSVGPolylineElementTable, 0 };

JSSVGPolylineElement::JSSVGPolylineElement(NonNullPassRefPtr<Structure> structure, JSDOMGlobalObject* globalObject, PassRefPtr<SVGPolylineElement> impl)
    : JSSVGElement(structure, globalObject, impl)
{
}

JSObject* JSSVGPolylineElement::createPrototype(ExecState* exec, JSGlobalObject* globalObject)
{
    return new (exec) JSSVGPolylineElementPrototype(JSSVGPolylineElementPrototype::createStructure(JSSVGElementPrototype::self(exec, globalObject)));
}

bool JSSVGPolylineElement::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticValueSlot<JSSVGPolylineElement, Base>(exec, &JSSVGPolylineElementTable, this, propertyName, slot);
}

bool JSSVGPolylineElement::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    return getStaticValueDescriptor<JSSVGPolylineElement, Base>(exec, &JSSVGPolylineElementTable, this, propertyName, descriptor);
}

JSValue jsSVGPolylineElementRequiredFeatures(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSSVGPolylineElement* castedThis = static_cast<JSSVGPolylineElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    SVGPolylineElement* imp = static_cast<SVGPolylineElement*>(castedThis->impl());
    JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->requiredFeatures()), imp);
    return result;
}

JSValue jsSVGPolylineElementRequiredExtensions(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSSVGPolylineElement* castedThis = static_cast<JSSVGPolylineElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    SVGPolylineElement* imp = static_cast<SVGPolylineElement*>(castedThis->impl());
    JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->requiredExtensions()), imp);
    return result;
}

JSValue jsSVGPolylineElementSystemLanguage(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSSVGPolylineElement* castedThis = static_cast<JSSVGPolylineElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    SVGPolylineElement* imp = static_cast<SVGPolylineElement*>(castedThis->impl());
    JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->systemLanguage()), imp);
    return result;
}

JSValue jsSVGPolylineElementXmllang(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSSVGPolylineElement* castedThis = static_cast<JSSVGPolylineElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    SVGPolylineElement* imp = static_cast<SVGPolylineElement*>(castedThis->impl());
    JSValue result = jsString(exec, imp->xmllang());
    return result;
}

JSValue jsSVGPolylineElementXmlspace(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSSVGPolylineElement* castedThis = static_cast<JSSVGPolylineElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    SVGPolylineElement* imp = static_cast<SVGPolylineElement*>(castedThis->impl());
    JSValue result = jsString(exec, imp->xmlspace());
    return result;
}

JSValue jsSVGPolylineElementExternalResourcesRequired(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSSVGPolylineElement* castedThis = static_cast<JSSVGPolylineElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    SVGPolylineElement* imp = static_cast<SVGPolylineElement*>(castedThis->impl());
    RefPtr<SVGAnimatedBoolean> obj = imp->externalResourcesRequiredAnimated();
    JSValue result =  toJS(exec, castedThis->globalObject(), obj.get(), imp);
    return result;
}

JSValue jsSVGPolylineElementClassName(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSSVGPolylineElement* castedThis = static_cast<JSSVGPolylineElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    SVGPolylineElement* imp = static_cast<SVGPolylineElement*>(castedThis->impl());
    RefPtr<SVGAnimatedString> obj = imp->classNameAnimated();
    JSValue result =  toJS(exec, castedThis->globalObject(), obj.get(), imp);
    return result;
}

JSValue jsSVGPolylineElementStyle(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSSVGPolylineElement* castedThis = static_cast<JSSVGPolylineElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    SVGPolylineElement* imp = static_cast<SVGPolylineElement*>(castedThis->impl());
    JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->style()));
    return result;
}

JSValue jsSVGPolylineElementTransform(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSSVGPolylineElement* castedThis = static_cast<JSSVGPolylineElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    SVGPolylineElement* imp = static_cast<SVGPolylineElement*>(castedThis->impl());
    RefPtr<SVGAnimatedTransformList> obj = imp->transformAnimated();
    JSValue result =  toJS(exec, castedThis->globalObject(), obj.get(), imp);
    return result;
}

JSValue jsSVGPolylineElementNearestViewportElement(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSSVGPolylineElement* castedThis = static_cast<JSSVGPolylineElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    SVGPolylineElement* imp = static_cast<SVGPolylineElement*>(castedThis->impl());
    JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->nearestViewportElement()));
    return result;
}

JSValue jsSVGPolylineElementFarthestViewportElement(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSSVGPolylineElement* castedThis = static_cast<JSSVGPolylineElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    SVGPolylineElement* imp = static_cast<SVGPolylineElement*>(castedThis->impl());
    JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->farthestViewportElement()));
    return result;
}

JSValue jsSVGPolylineElementPoints(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSSVGPolylineElement* castedThis = static_cast<JSSVGPolylineElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    SVGPolylineElement* imp = static_cast<SVGPolylineElement*>(castedThis->impl());
    JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->points()), imp);
    return result;
}

JSValue jsSVGPolylineElementAnimatedPoints(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSSVGPolylineElement* castedThis = static_cast<JSSVGPolylineElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    SVGPolylineElement* imp = static_cast<SVGPolylineElement*>(castedThis->impl());
    JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->animatedPoints()), imp);
    return result;
}

JSValue jsSVGPolylineElementConstructor(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSSVGPolylineElement* domObject = static_cast<JSSVGPolylineElement*>(asObject(slotBase));
    return JSSVGPolylineElement::getConstructor(exec, domObject->globalObject());
}
void JSSVGPolylineElement::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
    lookupPut<JSSVGPolylineElement, Base>(exec, propertyName, value, &JSSVGPolylineElementTable, this, slot);
}

void setJSSVGPolylineElementXmllang(ExecState* exec, JSObject* thisObject, JSValue value)
{
    JSSVGPolylineElement* castedThisObj = static_cast<JSSVGPolylineElement*>(thisObject);
    SVGPolylineElement* imp = static_cast<SVGPolylineElement*>(castedThisObj->impl());
    imp->setXmllang(value.toString(exec));
}

void setJSSVGPolylineElementXmlspace(ExecState* exec, JSObject* thisObject, JSValue value)
{
    JSSVGPolylineElement* castedThisObj = static_cast<JSSVGPolylineElement*>(thisObject);
    SVGPolylineElement* imp = static_cast<SVGPolylineElement*>(castedThisObj->impl());
    imp->setXmlspace(value.toString(exec));
}

JSValue JSSVGPolylineElement::getConstructor(ExecState* exec, JSGlobalObject* globalObject)
{
    return getDOMConstructor<JSSVGPolylineElementConstructor>(exec, static_cast<JSDOMGlobalObject*>(globalObject));
}

JSValue JSC_HOST_CALL jsSVGPolylineElementPrototypeFunctionHasExtension(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSSVGPolylineElement::s_info))
        return throwError(exec, TypeError);
    JSSVGPolylineElement* castedThisObj = static_cast<JSSVGPolylineElement*>(asObject(thisValue));
    SVGPolylineElement* imp = static_cast<SVGPolylineElement*>(castedThisObj->impl());
    const UString& extension = args.at(0).toString(exec);


    JSC::JSValue result = jsBoolean(imp->hasExtension(extension));
    return result;
}

JSValue JSC_HOST_CALL jsSVGPolylineElementPrototypeFunctionGetPresentationAttribute(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSSVGPolylineElement::s_info))
        return throwError(exec, TypeError);
    JSSVGPolylineElement* castedThisObj = static_cast<JSSVGPolylineElement*>(asObject(thisValue));
    SVGPolylineElement* imp = static_cast<SVGPolylineElement*>(castedThisObj->impl());
    const UString& name = args.at(0).toString(exec);


    JSC::JSValue result = toJS(exec, castedThisObj->globalObject(), WTF::getPtr(imp->getPresentationAttribute(name)));
    return result;
}

JSValue JSC_HOST_CALL jsSVGPolylineElementPrototypeFunctionGetBBox(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSSVGPolylineElement::s_info))
        return throwError(exec, TypeError);
    JSSVGPolylineElement* castedThisObj = static_cast<JSSVGPolylineElement*>(asObject(thisValue));
    SVGPolylineElement* imp = static_cast<SVGPolylineElement*>(castedThisObj->impl());


    JSC::JSValue result = toJS(exec, castedThisObj->globalObject(), JSSVGStaticPODTypeWrapper<FloatRect>::create(imp->getBBox()).get(), 0 /* no context on purpose */);
    return result;
}

JSValue JSC_HOST_CALL jsSVGPolylineElementPrototypeFunctionGetCTM(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSSVGPolylineElement::s_info))
        return throwError(exec, TypeError);
    JSSVGPolylineElement* castedThisObj = static_cast<JSSVGPolylineElement*>(asObject(thisValue));
    SVGPolylineElement* imp = static_cast<SVGPolylineElement*>(castedThisObj->impl());


    JSC::JSValue result = toJS(exec, castedThisObj->globalObject(), JSSVGStaticPODTypeWrapper<AffineTransform>::create(imp->getCTM()).get(), 0 /* no context on purpose */);
    return result;
}

JSValue JSC_HOST_CALL jsSVGPolylineElementPrototypeFunctionGetScreenCTM(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSSVGPolylineElement::s_info))
        return throwError(exec, TypeError);
    JSSVGPolylineElement* castedThisObj = static_cast<JSSVGPolylineElement*>(asObject(thisValue));
    SVGPolylineElement* imp = static_cast<SVGPolylineElement*>(castedThisObj->impl());


    JSC::JSValue result = toJS(exec, castedThisObj->globalObject(), JSSVGStaticPODTypeWrapper<AffineTransform>::create(imp->getScreenCTM()).get(), 0 /* no context on purpose */);
    return result;
}

JSValue JSC_HOST_CALL jsSVGPolylineElementPrototypeFunctionGetTransformToElement(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSSVGPolylineElement::s_info))
        return throwError(exec, TypeError);
    JSSVGPolylineElement* castedThisObj = static_cast<JSSVGPolylineElement*>(asObject(thisValue));
    SVGPolylineElement* imp = static_cast<SVGPolylineElement*>(castedThisObj->impl());
    ExceptionCode ec = 0;
    SVGElement* element = toSVGElement(args.at(0));


    JSC::JSValue result = toJS(exec, castedThisObj->globalObject(), JSSVGStaticPODTypeWrapper<AffineTransform>::create(imp->getTransformToElement(element, ec)).get(), 0 /* no context on purpose */);
    setDOMException(exec, ec);
    return result;
}


}

#endif // ENABLE(SVG)
