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

#include "HTMLMenuElement.h"
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

ASSERT_CLASS_FITS_IN_CELL(JSHTMLMenuElement);

/* Hash table */

static const HashTableValue JSHTMLMenuElementTableValues[3] =
{
    { "compact", DontDelete, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLMenuElementCompact), (intptr_t)setJSHTMLMenuElementCompact },
    { "constructor", DontEnum|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLMenuElementConstructor), (intptr_t)0 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSHTMLMenuElementTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 3, JSHTMLMenuElementTableValues, 0 };
#else
    { 4, 3, JSHTMLMenuElementTableValues, 0 };
#endif

/* Hash table for constructor */

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

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

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

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

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

/* Hash table for prototype */

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

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

const ClassInfo JSHTMLMenuElementPrototype::s_info = { "HTMLMenuElementPrototype", 0, &JSHTMLMenuElementPrototypeTable, 0 };

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

const ClassInfo JSHTMLMenuElement::s_info = { "HTMLMenuElement", &JSHTMLElement::s_info, &JSHTMLMenuElementTable, 0 };

JSHTMLMenuElement::JSHTMLMenuElement(NonNullPassRefPtr<Structure> structure, JSDOMGlobalObject* globalObject, PassRefPtr<HTMLMenuElement> impl)
    : JSHTMLElement(structure, globalObject, impl)
{
}

JSObject* JSHTMLMenuElement::createPrototype(ExecState* exec, JSGlobalObject* globalObject)
{
    return new (exec) JSHTMLMenuElementPrototype(JSHTMLMenuElementPrototype::createStructure(JSHTMLElementPrototype::self(exec, globalObject)));
}

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

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

JSValue jsHTMLMenuElementCompact(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSHTMLMenuElement* castedThis = static_cast<JSHTMLMenuElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    HTMLMenuElement* imp = static_cast<HTMLMenuElement*>(castedThis->impl());
    JSValue result = jsBoolean(imp->compact());
    return result;
}

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

void setJSHTMLMenuElementCompact(ExecState* exec, JSObject* thisObject, JSValue value)
{
    JSHTMLMenuElement* castedThisObj = static_cast<JSHTMLMenuElement*>(thisObject);
    HTMLMenuElement* imp = static_cast<HTMLMenuElement*>(castedThisObj->impl());
    imp->setCompact(value.toBoolean(exec));
}

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


}
