/*
    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 "JSCSSVariablesDeclaration.h"

#include "CSSRule.h"
#include "CSSVariablesDeclaration.h"
#include "JSCSSRule.h"
#include "KURL.h"
#include <runtime/Error.h>
#include <runtime/JSNumberCell.h>
#include <runtime/JSString.h>
#include <runtime/PropertyNameArray.h>
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

ASSERT_CLASS_FITS_IN_CELL(JSCSSVariablesDeclaration);

/* Hash table */

static const HashTableValue JSCSSVariablesDeclarationTableValues[5] =
{
    { "cssText", DontDelete, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsCSSVariablesDeclarationCssText), (intptr_t)setJSCSSVariablesDeclarationCssText },
    { "length", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsCSSVariablesDeclarationLength), (intptr_t)0 },
    { "parentRule", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsCSSVariablesDeclarationParentRule), (intptr_t)0 },
    { "constructor", DontEnum|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsCSSVariablesDeclarationConstructor), (intptr_t)0 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSCSSVariablesDeclarationTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 63, JSCSSVariablesDeclarationTableValues, 0 };
#else
    { 10, 7, JSCSSVariablesDeclarationTableValues, 0 };
#endif

/* Hash table for constructor */

static const HashTableValue JSCSSVariablesDeclarationConstructorTableValues[1] =
{
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSCSSVariablesDeclarationConstructorTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 0, JSCSSVariablesDeclarationConstructorTableValues, 0 };
#else
    { 1, 0, JSCSSVariablesDeclarationConstructorTableValues, 0 };
#endif

class JSCSSVariablesDeclarationConstructor : public DOMConstructorObject {
public:
    JSCSSVariablesDeclarationConstructor(ExecState* exec, JSDOMGlobalObject* globalObject)
        : DOMConstructorObject(JSCSSVariablesDeclarationConstructor::createStructure(globalObject->objectPrototype()), globalObject)
    {
        putDirect(exec->propertyNames().prototype, JSCSSVariablesDeclarationPrototype::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 JSCSSVariablesDeclarationConstructor::s_info = { "CSSVariablesDeclarationConstructor", 0, &JSCSSVariablesDeclarationConstructorTable, 0 };

bool JSCSSVariablesDeclarationConstructor::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticValueSlot<JSCSSVariablesDeclarationConstructor, DOMObject>(exec, &JSCSSVariablesDeclarationConstructorTable, this, propertyName, slot);
}

bool JSCSSVariablesDeclarationConstructor::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    return getStaticValueDescriptor<JSCSSVariablesDeclarationConstructor, DOMObject>(exec, &JSCSSVariablesDeclarationConstructorTable, this, propertyName, descriptor);
}

/* Hash table for prototype */

static const HashTableValue JSCSSVariablesDeclarationPrototypeTableValues[5] =
{
    { "getVariableValue", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsCSSVariablesDeclarationPrototypeFunctionGetVariableValue), (intptr_t)1 },
    { "removeVariable", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsCSSVariablesDeclarationPrototypeFunctionRemoveVariable), (intptr_t)1 },
    { "setVariable", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsCSSVariablesDeclarationPrototypeFunctionSetVariable), (intptr_t)2 },
    { "item", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsCSSVariablesDeclarationPrototypeFunctionItem), (intptr_t)1 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSCSSVariablesDeclarationPrototypeTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 15, JSCSSVariablesDeclarationPrototypeTableValues, 0 };
#else
    { 9, 7, JSCSSVariablesDeclarationPrototypeTableValues, 0 };
#endif

const ClassInfo JSCSSVariablesDeclarationPrototype::s_info = { "CSSVariablesDeclarationPrototype", 0, &JSCSSVariablesDeclarationPrototypeTable, 0 };

JSObject* JSCSSVariablesDeclarationPrototype::self(ExecState* exec, JSGlobalObject* globalObject)
{
    return getDOMPrototype<JSCSSVariablesDeclaration>(exec, globalObject);
}

bool JSCSSVariablesDeclarationPrototype::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticFunctionSlot<JSObject>(exec, &JSCSSVariablesDeclarationPrototypeTable, this, propertyName, slot);
}

bool JSCSSVariablesDeclarationPrototype::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    return getStaticFunctionDescriptor<JSObject>(exec, &JSCSSVariablesDeclarationPrototypeTable, this, propertyName, descriptor);
}

const ClassInfo JSCSSVariablesDeclaration::s_info = { "CSSVariablesDeclaration", 0, &JSCSSVariablesDeclarationTable, 0 };

JSCSSVariablesDeclaration::JSCSSVariablesDeclaration(NonNullPassRefPtr<Structure> structure, JSDOMGlobalObject* globalObject, PassRefPtr<CSSVariablesDeclaration> impl)
    : DOMObjectWithGlobalPointer(structure, globalObject)
    , m_impl(impl)
{
}

JSCSSVariablesDeclaration::~JSCSSVariablesDeclaration()
{
    forgetDOMObject(this, impl());
}

JSObject* JSCSSVariablesDeclaration::createPrototype(ExecState* exec, JSGlobalObject* globalObject)
{
    return new (exec) JSCSSVariablesDeclarationPrototype(JSCSSVariablesDeclarationPrototype::createStructure(globalObject->objectPrototype()));
}

bool JSCSSVariablesDeclaration::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    const HashEntry* entry = JSCSSVariablesDeclarationTable.entry(exec, propertyName);
    if (entry) {
        slot.setCustom(this, entry->propertyGetter());
        return true;
    }
    bool ok;
    unsigned index = propertyName.toUInt32(&ok, false);
    if (ok) {
        slot.setCustomIndex(this, index, indexGetter);
        return true;
    }
    return getStaticValueSlot<JSCSSVariablesDeclaration, Base>(exec, &JSCSSVariablesDeclarationTable, this, propertyName, slot);
}

bool JSCSSVariablesDeclaration::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    const HashEntry* entry = JSCSSVariablesDeclarationTable.entry(exec, propertyName);
    if (entry) {
        PropertySlot slot;
        slot.setCustom(this, entry->propertyGetter());
        descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes());
        return true;
    }
    bool ok;
    unsigned index = propertyName.toUInt32(&ok, false);
    if (ok && index < static_cast<CSSVariablesDeclaration*>(impl())->length()) {
        PropertySlot slot;
        slot.setCustomIndex(this, index, indexGetter);
        descriptor.setDescriptor(slot.getValue(exec, propertyName), DontDelete | ReadOnly);
        return true;
    }
    return getStaticValueDescriptor<JSCSSVariablesDeclaration, Base>(exec, &JSCSSVariablesDeclarationTable, this, propertyName, descriptor);
}

bool JSCSSVariablesDeclaration::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
{
    if (propertyName < static_cast<CSSVariablesDeclaration*>(impl())->length()) {
        slot.setCustomIndex(this, propertyName, indexGetter);
        return true;
    }
    return getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot);
}

JSValue jsCSSVariablesDeclarationCssText(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSCSSVariablesDeclaration* castedThis = static_cast<JSCSSVariablesDeclaration*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    CSSVariablesDeclaration* imp = static_cast<CSSVariablesDeclaration*>(castedThis->impl());
    JSValue result = jsString(exec, imp->cssText());
    return result;
}

JSValue jsCSSVariablesDeclarationLength(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSCSSVariablesDeclaration* castedThis = static_cast<JSCSSVariablesDeclaration*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    CSSVariablesDeclaration* imp = static_cast<CSSVariablesDeclaration*>(castedThis->impl());
    JSValue result = jsNumber(exec, imp->length());
    return result;
}

JSValue jsCSSVariablesDeclarationParentRule(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSCSSVariablesDeclaration* castedThis = static_cast<JSCSSVariablesDeclaration*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    CSSVariablesDeclaration* imp = static_cast<CSSVariablesDeclaration*>(castedThis->impl());
    JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->parentRule()));
    return result;
}

JSValue jsCSSVariablesDeclarationConstructor(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSCSSVariablesDeclaration* domObject = static_cast<JSCSSVariablesDeclaration*>(asObject(slotBase));
    return JSCSSVariablesDeclaration::getConstructor(exec, domObject->globalObject());
}
void JSCSSVariablesDeclaration::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
    lookupPut<JSCSSVariablesDeclaration, Base>(exec, propertyName, value, &JSCSSVariablesDeclarationTable, this, slot);
}

void setJSCSSVariablesDeclarationCssText(ExecState* exec, JSObject* thisObject, JSValue value)
{
    JSCSSVariablesDeclaration* castedThisObj = static_cast<JSCSSVariablesDeclaration*>(thisObject);
    CSSVariablesDeclaration* imp = static_cast<CSSVariablesDeclaration*>(castedThisObj->impl());
    imp->setCssText(value.toString(exec));
}

void JSCSSVariablesDeclaration::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
{
    for (unsigned i = 0; i < static_cast<CSSVariablesDeclaration*>(impl())->length(); ++i)
        propertyNames.add(Identifier::from(exec, i));
     Base::getOwnPropertyNames(exec, propertyNames, mode);
}

JSValue JSCSSVariablesDeclaration::getConstructor(ExecState* exec, JSGlobalObject* globalObject)
{
    return getDOMConstructor<JSCSSVariablesDeclarationConstructor>(exec, static_cast<JSDOMGlobalObject*>(globalObject));
}

JSValue JSC_HOST_CALL jsCSSVariablesDeclarationPrototypeFunctionGetVariableValue(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSCSSVariablesDeclaration::s_info))
        return throwError(exec, TypeError);
    JSCSSVariablesDeclaration* castedThisObj = static_cast<JSCSSVariablesDeclaration*>(asObject(thisValue));
    CSSVariablesDeclaration* imp = static_cast<CSSVariablesDeclaration*>(castedThisObj->impl());
    const UString& variableName = args.at(0).toString(exec);


    JSC::JSValue result = jsString(exec, imp->getVariableValue(variableName));
    return result;
}

JSValue JSC_HOST_CALL jsCSSVariablesDeclarationPrototypeFunctionRemoveVariable(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSCSSVariablesDeclaration::s_info))
        return throwError(exec, TypeError);
    JSCSSVariablesDeclaration* castedThisObj = static_cast<JSCSSVariablesDeclaration*>(asObject(thisValue));
    CSSVariablesDeclaration* imp = static_cast<CSSVariablesDeclaration*>(castedThisObj->impl());
    ExceptionCode ec = 0;
    const UString& variableName = args.at(0).toString(exec);


    JSC::JSValue result = jsString(exec, imp->removeVariable(variableName, ec));
    setDOMException(exec, ec);
    return result;
}

JSValue JSC_HOST_CALL jsCSSVariablesDeclarationPrototypeFunctionSetVariable(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSCSSVariablesDeclaration::s_info))
        return throwError(exec, TypeError);
    JSCSSVariablesDeclaration* castedThisObj = static_cast<JSCSSVariablesDeclaration*>(asObject(thisValue));
    CSSVariablesDeclaration* imp = static_cast<CSSVariablesDeclaration*>(castedThisObj->impl());
    ExceptionCode ec = 0;
    const UString& variableName = args.at(0).toString(exec);
    const UString& value = args.at(1).toString(exec);

    imp->setVariable(variableName, value, ec);
    setDOMException(exec, ec);
    return jsUndefined();
}

JSValue JSC_HOST_CALL jsCSSVariablesDeclarationPrototypeFunctionItem(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSCSSVariablesDeclaration::s_info))
        return throwError(exec, TypeError);
    JSCSSVariablesDeclaration* castedThisObj = static_cast<JSCSSVariablesDeclaration*>(asObject(thisValue));
    CSSVariablesDeclaration* imp = static_cast<CSSVariablesDeclaration*>(castedThisObj->impl());
    unsigned index = args.at(0).toInt32(exec);


    JSC::JSValue result = jsString(exec, imp->item(index));
    return result;
}


JSValue JSCSSVariablesDeclaration::indexGetter(ExecState* exec, JSValue slotBase, unsigned index)
{
    JSCSSVariablesDeclaration* thisObj = static_cast<JSCSSVariablesDeclaration*>(asObject(slotBase));
    return jsStringOrNull(exec, thisObj->impl()->item(index));
}
JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, CSSVariablesDeclaration* object)
{
    return getDOMObjectWrapper<JSCSSVariablesDeclaration>(exec, globalObject, object);
}
CSSVariablesDeclaration* toCSSVariablesDeclaration(JSC::JSValue value)
{
    return value.inherits(&JSCSSVariablesDeclaration::s_info) ? static_cast<JSCSSVariablesDeclaration*>(asObject(value))->impl() : 0;
}

}
