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

#include "JSSVGAnimatedBoolean.h"
#include "JSSVGAnimatedPreserveAspectRatio.h"
#include "JSSVGAnimatedRect.h"
#include "JSSVGStringList.h"
#include "SVGStringList.h"
#include "SVGViewElement.h"
#include <runtime/JSNumberCell.h>
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

ASSERT_CLASS_FITS_IN_CELL(JSSVGViewElement);

/* Hash table */

static const HashTableValue JSSVGViewElementTableValues[7] =
{
    { "viewTarget", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGViewElementViewTarget), (intptr_t)0 },
    { "externalResourcesRequired", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGViewElementExternalResourcesRequired), (intptr_t)0 },
    { "viewBox", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGViewElementViewBox), (intptr_t)0 },
    { "preserveAspectRatio", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGViewElementPreserveAspectRatio), (intptr_t)0 },
    { "zoomAndPan", DontDelete, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGViewElementZoomAndPan), (intptr_t)setJSSVGViewElementZoomAndPan },
    { "constructor", DontEnum|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGViewElementConstructor), (intptr_t)0 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSSVGViewElementTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 15, JSSVGViewElementTableValues, 0 };
#else
    { 16, 15, JSSVGViewElementTableValues, 0 };
#endif

/* Hash table for constructor */

static const HashTableValue JSSVGViewElementConstructorTableValues[4] =
{
    { "SVG_ZOOMANDPAN_UNKNOWN", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGViewElementSVG_ZOOMANDPAN_UNKNOWN), (intptr_t)0 },
    { "SVG_ZOOMANDPAN_DISABLE", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGViewElementSVG_ZOOMANDPAN_DISABLE), (intptr_t)0 },
    { "SVG_ZOOMANDPAN_MAGNIFY", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGViewElementSVG_ZOOMANDPAN_MAGNIFY), (intptr_t)0 },
    { 0, 0, 0, 0 }
};

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

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

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

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

/* Hash table for prototype */

static const HashTableValue JSSVGViewElementPrototypeTableValues[4] =
{
    { "SVG_ZOOMANDPAN_UNKNOWN", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGViewElementSVG_ZOOMANDPAN_UNKNOWN), (intptr_t)0 },
    { "SVG_ZOOMANDPAN_DISABLE", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGViewElementSVG_ZOOMANDPAN_DISABLE), (intptr_t)0 },
    { "SVG_ZOOMANDPAN_MAGNIFY", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSVGViewElementSVG_ZOOMANDPAN_MAGNIFY), (intptr_t)0 },
    { 0, 0, 0, 0 }
};

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

const ClassInfo JSSVGViewElementPrototype::s_info = { "SVGViewElementPrototype", 0, &JSSVGViewElementPrototypeTable, 0 };

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

bool JSSVGViewElementPrototype::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticValueSlot<JSSVGViewElementPrototype, JSObject>(exec, &JSSVGViewElementPrototypeTable, this, propertyName, slot);
}

bool JSSVGViewElementPrototype::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    return getStaticValueDescriptor<JSSVGViewElementPrototype, JSObject>(exec, &JSSVGViewElementPrototypeTable, this, propertyName, descriptor);
}

const ClassInfo JSSVGViewElement::s_info = { "SVGViewElement", &JSSVGElement::s_info, &JSSVGViewElementTable, 0 };

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

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

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

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

JSValue jsSVGViewElementViewTarget(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSSVGViewElement* castedThis = static_cast<JSSVGViewElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    SVGViewElement* imp = static_cast<SVGViewElement*>(castedThis->impl());
    JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->viewTarget()), imp);
    return result;
}

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

JSValue jsSVGViewElementViewBox(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSSVGViewElement* castedThis = static_cast<JSSVGViewElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    SVGViewElement* imp = static_cast<SVGViewElement*>(castedThis->impl());
    RefPtr<SVGAnimatedRect> obj = imp->viewBoxAnimated();
    JSValue result =  toJS(exec, castedThis->globalObject(), obj.get(), imp);
    return result;
}

JSValue jsSVGViewElementPreserveAspectRatio(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSSVGViewElement* castedThis = static_cast<JSSVGViewElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    SVGViewElement* imp = static_cast<SVGViewElement*>(castedThis->impl());
    RefPtr<SVGAnimatedPreserveAspectRatio> obj = imp->preserveAspectRatioAnimated();
    JSValue result =  toJS(exec, castedThis->globalObject(), obj.get(), imp);
    return result;
}

JSValue jsSVGViewElementZoomAndPan(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSSVGViewElement* castedThis = static_cast<JSSVGViewElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    SVGViewElement* imp = static_cast<SVGViewElement*>(castedThis->impl());
    JSValue result = jsNumber(exec, imp->zoomAndPan());
    return result;
}

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

void setJSSVGViewElementZoomAndPan(ExecState* exec, JSObject* thisObject, JSValue value)
{
    JSSVGViewElement* castedThisObj = static_cast<JSSVGViewElement*>(thisObject);
    SVGViewElement* imp = static_cast<SVGViewElement*>(castedThisObj->impl());
    imp->setZoomAndPan(value.toInt32(exec));
}

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

// Constant getters

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

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

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


}

#endif // ENABLE(SVG)
