/*
    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(DATAGRID)

#include "JSHTMLDataGridColElement.h"

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

using namespace JSC;

namespace WebCore {

ASSERT_CLASS_FITS_IN_CELL(JSHTMLDataGridColElement);

/* Hash table */

static const HashTableValue JSHTMLDataGridColElementTableValues[7] =
{
    { "label", DontDelete, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLDataGridColElementLabel), (intptr_t)setJSHTMLDataGridColElementLabel },
    { "type", DontDelete, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLDataGridColElementType), (intptr_t)setJSHTMLDataGridColElementType },
    { "sortable", DontDelete, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLDataGridColElementSortable), (intptr_t)setJSHTMLDataGridColElementSortable },
    { "sortDirection", DontDelete, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLDataGridColElementSortDirection), (intptr_t)setJSHTMLDataGridColElementSortDirection },
    { "primary", DontDelete, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLDataGridColElementPrimary), (intptr_t)setJSHTMLDataGridColElementPrimary },
    { "constructor", DontEnum|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsHTMLDataGridColElementConstructor), (intptr_t)0 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSHTMLDataGridColElementTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 63, JSHTMLDataGridColElementTableValues, 0 };
#else
    { 17, 15, JSHTMLDataGridColElementTableValues, 0 };
#endif

/* Hash table for constructor */

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

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

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

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

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

/* Hash table for prototype */

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

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

const ClassInfo JSHTMLDataGridColElementPrototype::s_info = { "HTMLDataGridColElementPrototype", 0, &JSHTMLDataGridColElementPrototypeTable, 0 };

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

const ClassInfo JSHTMLDataGridColElement::s_info = { "HTMLDataGridColElement", &JSHTMLElement::s_info, &JSHTMLDataGridColElementTable, 0 };

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

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

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

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

JSValue jsHTMLDataGridColElementLabel(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSHTMLDataGridColElement* castedThis = static_cast<JSHTMLDataGridColElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    HTMLDataGridColElement* imp = static_cast<HTMLDataGridColElement*>(castedThis->impl());
    JSValue result = jsString(exec, imp->label());
    return result;
}

JSValue jsHTMLDataGridColElementType(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSHTMLDataGridColElement* castedThis = static_cast<JSHTMLDataGridColElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    HTMLDataGridColElement* imp = static_cast<HTMLDataGridColElement*>(castedThis->impl());
    JSValue result = jsString(exec, imp->type());
    return result;
}

JSValue jsHTMLDataGridColElementSortable(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSHTMLDataGridColElement* castedThis = static_cast<JSHTMLDataGridColElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    HTMLDataGridColElement* imp = static_cast<HTMLDataGridColElement*>(castedThis->impl());
    JSValue result = jsNumber(exec, imp->sortable());
    return result;
}

JSValue jsHTMLDataGridColElementSortDirection(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSHTMLDataGridColElement* castedThis = static_cast<JSHTMLDataGridColElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    HTMLDataGridColElement* imp = static_cast<HTMLDataGridColElement*>(castedThis->impl());
    JSValue result = jsNumber(exec, imp->sortDirection());
    return result;
}

JSValue jsHTMLDataGridColElementPrimary(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSHTMLDataGridColElement* castedThis = static_cast<JSHTMLDataGridColElement*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    HTMLDataGridColElement* imp = static_cast<HTMLDataGridColElement*>(castedThis->impl());
    JSValue result = jsBoolean(imp->primary());
    return result;
}

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

void setJSHTMLDataGridColElementLabel(ExecState* exec, JSObject* thisObject, JSValue value)
{
    JSHTMLDataGridColElement* castedThisObj = static_cast<JSHTMLDataGridColElement*>(thisObject);
    HTMLDataGridColElement* imp = static_cast<HTMLDataGridColElement*>(castedThisObj->impl());
    imp->setLabel(value.toString(exec));
}

void setJSHTMLDataGridColElementType(ExecState* exec, JSObject* thisObject, JSValue value)
{
    JSHTMLDataGridColElement* castedThisObj = static_cast<JSHTMLDataGridColElement*>(thisObject);
    HTMLDataGridColElement* imp = static_cast<HTMLDataGridColElement*>(castedThisObj->impl());
    imp->setType(value.toString(exec));
}

void setJSHTMLDataGridColElementSortable(ExecState* exec, JSObject* thisObject, JSValue value)
{
    JSHTMLDataGridColElement* castedThisObj = static_cast<JSHTMLDataGridColElement*>(thisObject);
    HTMLDataGridColElement* imp = static_cast<HTMLDataGridColElement*>(castedThisObj->impl());
    imp->setSortable(value.toInt32(exec));
}

void setJSHTMLDataGridColElementSortDirection(ExecState* exec, JSObject* thisObject, JSValue value)
{
    JSHTMLDataGridColElement* castedThisObj = static_cast<JSHTMLDataGridColElement*>(thisObject);
    HTMLDataGridColElement* imp = static_cast<HTMLDataGridColElement*>(castedThisObj->impl());
    imp->setSortDirection(value.toInt32(exec));
}

void setJSHTMLDataGridColElementPrimary(ExecState* exec, JSObject* thisObject, JSValue value)
{
    JSHTMLDataGridColElement* castedThisObj = static_cast<JSHTMLDataGridColElement*>(thisObject);
    HTMLDataGridColElement* imp = static_cast<HTMLDataGridColElement*>(castedThisObj->impl());
    imp->setPrimary(value.toBoolean(exec));
}

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


}

#endif // ENABLE(DATAGRID)
