/*
    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 "JSStyleSheetList.h"

#include "AtomicString.h"
#include "JSStyleSheet.h"
#include "StyleSheet.h"
#include "StyleSheetList.h"
#include <runtime/Error.h>
#include <runtime/JSNumberCell.h>
#include <runtime/PropertyNameArray.h>
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

ASSERT_CLASS_FITS_IN_CELL(JSStyleSheetList);

/* Hash table */

static const HashTableValue JSStyleSheetListTableValues[3] =
{
    { "length", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsStyleSheetListLength), (intptr_t)0 },
    { "constructor", DontEnum|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsStyleSheetListConstructor), (intptr_t)0 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSStyleSheetListTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 15, JSStyleSheetListTableValues, 0 };
#else
    { 5, 3, JSStyleSheetListTableValues, 0 };
#endif

/* Hash table for constructor */

static const HashTableValue JSStyleSheetListConstructorTableValues[1] =
{
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSStyleSheetListConstructorTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 0, JSStyleSheetListConstructorTableValues, 0 };
#else
    { 1, 0, JSStyleSheetListConstructorTableValues, 0 };
#endif

class JSStyleSheetListConstructor : public DOMConstructorObject {
public:
    JSStyleSheetListConstructor(ExecState* exec, JSDOMGlobalObject* globalObject)
        : DOMConstructorObject(JSStyleSheetListConstructor::createStructure(globalObject->objectPrototype()), globalObject)
    {
        putDirect(exec->propertyNames().prototype, JSStyleSheetListPrototype::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 JSStyleSheetListConstructor::s_info = { "StyleSheetListConstructor", 0, &JSStyleSheetListConstructorTable, 0 };

bool JSStyleSheetListConstructor::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticValueSlot<JSStyleSheetListConstructor, DOMObject>(exec, &JSStyleSheetListConstructorTable, this, propertyName, slot);
}

bool JSStyleSheetListConstructor::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    return getStaticValueDescriptor<JSStyleSheetListConstructor, DOMObject>(exec, &JSStyleSheetListConstructorTable, this, propertyName, descriptor);
}

/* Hash table for prototype */

static const HashTableValue JSStyleSheetListPrototypeTableValues[2] =
{
    { "item", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsStyleSheetListPrototypeFunctionItem), (intptr_t)1 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSStyleSheetListPrototypeTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 0, JSStyleSheetListPrototypeTableValues, 0 };
#else
    { 2, 1, JSStyleSheetListPrototypeTableValues, 0 };
#endif

const ClassInfo JSStyleSheetListPrototype::s_info = { "StyleSheetListPrototype", 0, &JSStyleSheetListPrototypeTable, 0 };

JSObject* JSStyleSheetListPrototype::self(ExecState* exec, JSGlobalObject* globalObject)
{
    return getDOMPrototype<JSStyleSheetList>(exec, globalObject);
}

bool JSStyleSheetListPrototype::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticFunctionSlot<JSObject>(exec, &JSStyleSheetListPrototypeTable, this, propertyName, slot);
}

bool JSStyleSheetListPrototype::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    return getStaticFunctionDescriptor<JSObject>(exec, &JSStyleSheetListPrototypeTable, this, propertyName, descriptor);
}

const ClassInfo JSStyleSheetList::s_info = { "StyleSheetList", 0, &JSStyleSheetListTable, 0 };

JSStyleSheetList::JSStyleSheetList(NonNullPassRefPtr<Structure> structure, JSDOMGlobalObject* globalObject, PassRefPtr<StyleSheetList> impl)
    : DOMObjectWithGlobalPointer(structure, globalObject)
    , m_impl(impl)
{
}

JSStyleSheetList::~JSStyleSheetList()
{
    forgetDOMObject(this, impl());
}

JSObject* JSStyleSheetList::createPrototype(ExecState* exec, JSGlobalObject* globalObject)
{
    return new (exec) JSStyleSheetListPrototype(JSStyleSheetListPrototype::createStructure(globalObject->objectPrototype()));
}

bool JSStyleSheetList::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    const HashEntry* entry = JSStyleSheetListTable.entry(exec, propertyName);
    if (entry) {
        slot.setCustom(this, entry->propertyGetter());
        return true;
    }
    bool ok;
    unsigned index = propertyName.toUInt32(&ok, false);
    if (ok && index < static_cast<StyleSheetList*>(impl())->length()) {
        slot.setCustomIndex(this, index, indexGetter);
        return true;
    }
    if (canGetItemsForName(exec, static_cast<StyleSheetList*>(impl()), propertyName)) {
        slot.setCustom(this, nameGetter);
        return true;
    }
    return getStaticValueSlot<JSStyleSheetList, Base>(exec, &JSStyleSheetListTable, this, propertyName, slot);
}

bool JSStyleSheetList::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    const HashEntry* entry = JSStyleSheetListTable.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<StyleSheetList*>(impl())->length()) {
        PropertySlot slot;
        slot.setCustomIndex(this, index, indexGetter);
        descriptor.setDescriptor(slot.getValue(exec, propertyName), DontDelete | ReadOnly);
        return true;
    }
    if (canGetItemsForName(exec, static_cast<StyleSheetList*>(impl()), propertyName)) {
        PropertySlot slot;
        slot.setCustom(this, nameGetter);
        descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum);
        return true;
    }
    return getStaticValueDescriptor<JSStyleSheetList, Base>(exec, &JSStyleSheetListTable, this, propertyName, descriptor);
}

bool JSStyleSheetList::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
{
    if (propertyName < static_cast<StyleSheetList*>(impl())->length()) {
        slot.setCustomIndex(this, propertyName, indexGetter);
        return true;
    }
    return getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot);
}

JSValue jsStyleSheetListLength(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSStyleSheetList* castedThis = static_cast<JSStyleSheetList*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    StyleSheetList* imp = static_cast<StyleSheetList*>(castedThis->impl());
    JSValue result = jsNumber(exec, imp->length());
    return result;
}

JSValue jsStyleSheetListConstructor(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSStyleSheetList* domObject = static_cast<JSStyleSheetList*>(asObject(slotBase));
    return JSStyleSheetList::getConstructor(exec, domObject->globalObject());
}
void JSStyleSheetList::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
{
    for (unsigned i = 0; i < static_cast<StyleSheetList*>(impl())->length(); ++i)
        propertyNames.add(Identifier::from(exec, i));
     Base::getOwnPropertyNames(exec, propertyNames, mode);
}

JSValue JSStyleSheetList::getConstructor(ExecState* exec, JSGlobalObject* globalObject)
{
    return getDOMConstructor<JSStyleSheetListConstructor>(exec, static_cast<JSDOMGlobalObject*>(globalObject));
}

JSValue JSC_HOST_CALL jsStyleSheetListPrototypeFunctionItem(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSStyleSheetList::s_info))
        return throwError(exec, TypeError);
    JSStyleSheetList* castedThisObj = static_cast<JSStyleSheetList*>(asObject(thisValue));
    StyleSheetList* imp = static_cast<StyleSheetList*>(castedThisObj->impl());
    unsigned index = args.at(0).toInt32(exec);


    JSC::JSValue result = toJS(exec, castedThisObj->globalObject(), WTF::getPtr(imp->item(index)));
    return result;
}


JSValue JSStyleSheetList::indexGetter(ExecState* exec, JSValue slotBase, unsigned index)
{
    JSStyleSheetList* thisObj = static_cast<JSStyleSheetList*>(asObject(slotBase));
    return toJS(exec, thisObj->globalObject(), static_cast<StyleSheetList*>(thisObj->impl())->item(index));
}
JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, StyleSheetList* object)
{
    return getDOMObjectWrapper<JSStyleSheetList>(exec, globalObject, object);
}
StyleSheetList* toStyleSheetList(JSC::JSValue value)
{
    return value.inherits(&JSStyleSheetList::s_info) ? static_cast<JSStyleSheetList*>(asObject(value))->impl() : 0;
}

}
