/*
    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 "JSRect.h"

#include "CSSPrimitiveValue.h"
#include "JSCSSPrimitiveValue.h"
#include "Rect.h"
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

ASSERT_CLASS_FITS_IN_CELL(JSRect);

/* Hash table */

static const HashTableValue JSRectTableValues[6] =
{
    { "top", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsRectTop), (intptr_t)0 },
    { "right", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsRectRight), (intptr_t)0 },
    { "bottom", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsRectBottom), (intptr_t)0 },
    { "left", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsRectLeft), (intptr_t)0 },
    { "constructor", DontEnum|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsRectConstructor), (intptr_t)0 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSRectTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 7, JSRectTableValues, 0 };
#else
    { 16, 15, JSRectTableValues, 0 };
#endif

/* Hash table for constructor */

static const HashTableValue JSRectConstructorTableValues[1] =
{
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSRectConstructorTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 0, JSRectConstructorTableValues, 0 };
#else
    { 1, 0, JSRectConstructorTableValues, 0 };
#endif

class JSRectConstructor : public DOMConstructorObject {
public:
    JSRectConstructor(ExecState* exec, JSDOMGlobalObject* globalObject)
        : DOMConstructorObject(JSRectConstructor::createStructure(globalObject->objectPrototype()), globalObject)
    {
        putDirect(exec->propertyNames().prototype, JSRectPrototype::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 JSRectConstructor::s_info = { "RectConstructor", 0, &JSRectConstructorTable, 0 };

bool JSRectConstructor::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticValueSlot<JSRectConstructor, DOMObject>(exec, &JSRectConstructorTable, this, propertyName, slot);
}

bool JSRectConstructor::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    return getStaticValueDescriptor<JSRectConstructor, DOMObject>(exec, &JSRectConstructorTable, this, propertyName, descriptor);
}

/* Hash table for prototype */

static const HashTableValue JSRectPrototypeTableValues[1] =
{
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSRectPrototypeTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 0, JSRectPrototypeTableValues, 0 };
#else
    { 1, 0, JSRectPrototypeTableValues, 0 };
#endif

const ClassInfo JSRectPrototype::s_info = { "RectPrototype", 0, &JSRectPrototypeTable, 0 };

JSObject* JSRectPrototype::self(ExecState* exec, JSGlobalObject* globalObject)
{
    return getDOMPrototype<JSRect>(exec, globalObject);
}

const ClassInfo JSRect::s_info = { "Rect", 0, &JSRectTable, 0 };

JSRect::JSRect(NonNullPassRefPtr<Structure> structure, JSDOMGlobalObject* globalObject, PassRefPtr<Rect> impl)
    : DOMObjectWithGlobalPointer(structure, globalObject)
    , m_impl(impl)
{
}

JSRect::~JSRect()
{
    forgetDOMObject(this, impl());
}

JSObject* JSRect::createPrototype(ExecState* exec, JSGlobalObject* globalObject)
{
    return new (exec) JSRectPrototype(JSRectPrototype::createStructure(globalObject->objectPrototype()));
}

bool JSRect::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticValueSlot<JSRect, Base>(exec, &JSRectTable, this, propertyName, slot);
}

bool JSRect::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    return getStaticValueDescriptor<JSRect, Base>(exec, &JSRectTable, this, propertyName, descriptor);
}

JSValue jsRectTop(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSRect* castedThis = static_cast<JSRect*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    Rect* imp = static_cast<Rect*>(castedThis->impl());
    JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->top()));
    return result;
}

JSValue jsRectRight(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSRect* castedThis = static_cast<JSRect*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    Rect* imp = static_cast<Rect*>(castedThis->impl());
    JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->right()));
    return result;
}

JSValue jsRectBottom(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSRect* castedThis = static_cast<JSRect*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    Rect* imp = static_cast<Rect*>(castedThis->impl());
    JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->bottom()));
    return result;
}

JSValue jsRectLeft(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSRect* castedThis = static_cast<JSRect*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    Rect* imp = static_cast<Rect*>(castedThis->impl());
    JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->left()));
    return result;
}

JSValue jsRectConstructor(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSRect* domObject = static_cast<JSRect*>(asObject(slotBase));
    return JSRect::getConstructor(exec, domObject->globalObject());
}
JSValue JSRect::getConstructor(ExecState* exec, JSGlobalObject* globalObject)
{
    return getDOMConstructor<JSRectConstructor>(exec, static_cast<JSDOMGlobalObject*>(globalObject));
}

JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, Rect* object)
{
    return getDOMObjectWrapper<JSRect>(exec, globalObject, object);
}
Rect* toRect(JSC::JSValue value)
{
    return value.inherits(&JSRect::s_info) ? static_cast<JSRect*>(asObject(value))->impl() : 0;
}

}
