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

#include "KURL.h"
#include "SVGPaint.h"
#include <runtime/Error.h>
#include <runtime/JSNumberCell.h>
#include <runtime/JSString.h>
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

ASSERT_CLASS_FITS_IN_CELL(JSSVGPaint);

/* Hash table */

static const HashTableValue JSSVGPaintTableValues[4] =
{
    { "paintType", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPaintPaintType), (intptr_t)0 },
    { "uri", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPaintUri), (intptr_t)0 },
    { "constructor", DontEnum|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPaintConstructor), (intptr_t)0 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSSVGPaintTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 31, JSSVGPaintTableValues, 0 };
#else
    { 9, 7, JSSVGPaintTableValues, 0 };
#endif

/* Hash table for constructor */

static const HashTableValue JSSVGPaintConstructorTableValues[11] =
{
    { "SVG_PAINTTYPE_UNKNOWN", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPaintSVG_PAINTTYPE_UNKNOWN), (intptr_t)0 },
    { "SVG_PAINTTYPE_RGBCOLOR", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPaintSVG_PAINTTYPE_RGBCOLOR), (intptr_t)0 },
    { "SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPaintSVG_PAINTTYPE_RGBCOLOR_ICCCOLOR), (intptr_t)0 },
    { "SVG_PAINTTYPE_NONE", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPaintSVG_PAINTTYPE_NONE), (intptr_t)0 },
    { "SVG_PAINTTYPE_CURRENTCOLOR", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPaintSVG_PAINTTYPE_CURRENTCOLOR), (intptr_t)0 },
    { "SVG_PAINTTYPE_URI_NONE", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPaintSVG_PAINTTYPE_URI_NONE), (intptr_t)0 },
    { "SVG_PAINTTYPE_URI_CURRENTCOLOR", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPaintSVG_PAINTTYPE_URI_CURRENTCOLOR), (intptr_t)0 },
    { "SVG_PAINTTYPE_URI_RGBCOLOR", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPaintSVG_PAINTTYPE_URI_RGBCOLOR), (intptr_t)0 },
    { "SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPaintSVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR), (intptr_t)0 },
    { "SVG_PAINTTYPE_URI", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPaintSVG_PAINTTYPE_URI), (intptr_t)0 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSSVGPaintConstructorTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 4095, JSSVGPaintConstructorTableValues, 0 };
#else
    { 35, 31, JSSVGPaintConstructorTableValues, 0 };
#endif

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

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

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

/* Hash table for prototype */

static const HashTableValue JSSVGPaintPrototypeTableValues[13] =
{
    { "SVG_PAINTTYPE_UNKNOWN", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPaintSVG_PAINTTYPE_UNKNOWN), (intptr_t)0 },
    { "SVG_PAINTTYPE_RGBCOLOR", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPaintSVG_PAINTTYPE_RGBCOLOR), (intptr_t)0 },
    { "SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPaintSVG_PAINTTYPE_RGBCOLOR_ICCCOLOR), (intptr_t)0 },
    { "SVG_PAINTTYPE_NONE", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPaintSVG_PAINTTYPE_NONE), (intptr_t)0 },
    { "SVG_PAINTTYPE_CURRENTCOLOR", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPaintSVG_PAINTTYPE_CURRENTCOLOR), (intptr_t)0 },
    { "SVG_PAINTTYPE_URI_NONE", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPaintSVG_PAINTTYPE_URI_NONE), (intptr_t)0 },
    { "SVG_PAINTTYPE_URI_CURRENTCOLOR", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPaintSVG_PAINTTYPE_URI_CURRENTCOLOR), (intptr_t)0 },
    { "SVG_PAINTTYPE_URI_RGBCOLOR", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPaintSVG_PAINTTYPE_URI_RGBCOLOR), (intptr_t)0 },
    { "SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPaintSVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR), (intptr_t)0 },
    { "SVG_PAINTTYPE_URI", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGPaintSVG_PAINTTYPE_URI), (intptr_t)0 },
    { "setUri", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsSVGPaintPrototypeFunctionSetUri), (intptr_t)1 },
    { "setPaint", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsSVGPaintPrototypeFunctionSetPaint), (intptr_t)4 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSSVGPaintPrototypeTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 4095, JSSVGPaintPrototypeTableValues, 0 };
#else
    { 35, 31, JSSVGPaintPrototypeTableValues, 0 };
#endif

const ClassInfo JSSVGPaintPrototype::s_info = { "SVGPaintPrototype", 0, &JSSVGPaintPrototypeTable, 0 };

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

bool JSSVGPaintPrototype::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticPropertySlot<JSSVGPaintPrototype, JSObject>(exec, &JSSVGPaintPrototypeTable, this, propertyName, slot);
}

bool JSSVGPaintPrototype::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    return getStaticPropertyDescriptor<JSSVGPaintPrototype, JSObject>(exec, &JSSVGPaintPrototypeTable, this, propertyName, descriptor);
}

const ClassInfo JSSVGPaint::s_info = { "SVGPaint", &JSSVGColor::s_info, &JSSVGPaintTable, 0 };

JSSVGPaint::JSSVGPaint(NonNullPassRefPtr<Structure> structure, JSDOMGlobalObject* globalObject, PassRefPtr<SVGPaint> impl)
    : JSSVGColor(structure, globalObject, impl)
{
}

JSObject* JSSVGPaint::createPrototype(ExecState* exec, JSGlobalObject* globalObject)
{
    return new (exec) JSSVGPaintPrototype(JSSVGPaintPrototype::createStructure(JSSVGColorPrototype::self(exec, globalObject)));
}

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

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

JSValue jsSVGPaintPaintType(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSSVGPaint* castedThis = static_cast<JSSVGPaint*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    SVGPaint* imp = static_cast<SVGPaint*>(castedThis->impl());
    JSValue result = jsNumber(exec, imp->paintType());
    return result;
}

JSValue jsSVGPaintUri(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSSVGPaint* castedThis = static_cast<JSSVGPaint*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    SVGPaint* imp = static_cast<SVGPaint*>(castedThis->impl());
    JSValue result = jsString(exec, imp->uri());
    return result;
}

JSValue jsSVGPaintConstructor(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSSVGPaint* domObject = static_cast<JSSVGPaint*>(asObject(slotBase));
    return JSSVGPaint::getConstructor(exec, domObject->globalObject());
}
JSValue JSSVGPaint::getConstructor(ExecState* exec, JSGlobalObject* globalObject)
{
    return getDOMConstructor<JSSVGPaintConstructor>(exec, static_cast<JSDOMGlobalObject*>(globalObject));
}

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

    imp->setUri(uri);
    return jsUndefined();
}

JSValue JSC_HOST_CALL jsSVGPaintPrototypeFunctionSetPaint(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSSVGPaint::s_info))
        return throwError(exec, TypeError);
    JSSVGPaint* castedThisObj = static_cast<JSSVGPaint*>(asObject(thisValue));
    SVGPaint* imp = static_cast<SVGPaint*>(castedThisObj->impl());
    ExceptionCode ec = 0;
    SVGPaint::SVGPaintType paintType = static_cast<SVGPaint::SVGPaintType>(args.at(0).toInt32(exec));
    const UString& uri = args.at(1).toString(exec);
    const UString& rgbColor = args.at(2).toString(exec);
    const UString& iccColor = args.at(3).toString(exec);

    imp->setPaint(paintType, uri, rgbColor, iccColor, ec);
    setDOMException(exec, ec);
    return jsUndefined();
}

// Constant getters

JSValue jsSVGPaintSVG_PAINTTYPE_UNKNOWN(ExecState* exec, JSValue, const Identifier&)
{
    return jsNumber(exec, static_cast<int>(0));
}

JSValue jsSVGPaintSVG_PAINTTYPE_RGBCOLOR(ExecState* exec, JSValue, const Identifier&)
{
    return jsNumber(exec, static_cast<int>(1));
}

JSValue jsSVGPaintSVG_PAINTTYPE_RGBCOLOR_ICCCOLOR(ExecState* exec, JSValue, const Identifier&)
{
    return jsNumber(exec, static_cast<int>(2));
}

JSValue jsSVGPaintSVG_PAINTTYPE_NONE(ExecState* exec, JSValue, const Identifier&)
{
    return jsNumber(exec, static_cast<int>(101));
}

JSValue jsSVGPaintSVG_PAINTTYPE_CURRENTCOLOR(ExecState* exec, JSValue, const Identifier&)
{
    return jsNumber(exec, static_cast<int>(102));
}

JSValue jsSVGPaintSVG_PAINTTYPE_URI_NONE(ExecState* exec, JSValue, const Identifier&)
{
    return jsNumber(exec, static_cast<int>(103));
}

JSValue jsSVGPaintSVG_PAINTTYPE_URI_CURRENTCOLOR(ExecState* exec, JSValue, const Identifier&)
{
    return jsNumber(exec, static_cast<int>(104));
}

JSValue jsSVGPaintSVG_PAINTTYPE_URI_RGBCOLOR(ExecState* exec, JSValue, const Identifier&)
{
    return jsNumber(exec, static_cast<int>(105));
}

JSValue jsSVGPaintSVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR(ExecState* exec, JSValue, const Identifier&)
{
    return jsNumber(exec, static_cast<int>(106));
}

JSValue jsSVGPaintSVG_PAINTTYPE_URI(ExecState* exec, JSValue, const Identifier&)
{
    return jsNumber(exec, static_cast<int>(107));
}


}

#endif // ENABLE(SVG)
