/*
    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 "JSMimeTypeArray.h"

#include "AtomicString.h"
#include "JSMimeType.h"
#include "MimeType.h"
#include "MimeTypeArray.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(JSMimeTypeArray);

/* Hash table */

static const HashTableValue JSMimeTypeArrayTableValues[3] =
{
    { "length", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMimeTypeArrayLength), (intptr_t)0 },
    { "constructor", DontEnum|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMimeTypeArrayConstructor), (intptr_t)0 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSMimeTypeArrayTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 15, JSMimeTypeArrayTableValues, 0 };
#else
    { 5, 3, JSMimeTypeArrayTableValues, 0 };
#endif

/* Hash table for constructor */

static const HashTableValue JSMimeTypeArrayConstructorTableValues[1] =
{
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSMimeTypeArrayConstructorTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 0, JSMimeTypeArrayConstructorTableValues, 0 };
#else
    { 1, 0, JSMimeTypeArrayConstructorTableValues, 0 };
#endif

class JSMimeTypeArrayConstructor : public DOMConstructorObject {
public:
    JSMimeTypeArrayConstructor(ExecState* exec, JSDOMGlobalObject* globalObject)
        : DOMConstructorObject(JSMimeTypeArrayConstructor::createStructure(globalObject->objectPrototype()), globalObject)
    {
        putDirect(exec->propertyNames().prototype, JSMimeTypeArrayPrototype::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 JSMimeTypeArrayConstructor::s_info = { "MimeTypeArrayConstructor", 0, &JSMimeTypeArrayConstructorTable, 0 };

bool JSMimeTypeArrayConstructor::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticValueSlot<JSMimeTypeArrayConstructor, DOMObject>(exec, &JSMimeTypeArrayConstructorTable, this, propertyName, slot);
}

bool JSMimeTypeArrayConstructor::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    return getStaticValueDescriptor<JSMimeTypeArrayConstructor, DOMObject>(exec, &JSMimeTypeArrayConstructorTable, this, propertyName, descriptor);
}

/* Hash table for prototype */

static const HashTableValue JSMimeTypeArrayPrototypeTableValues[3] =
{
    { "item", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsMimeTypeArrayPrototypeFunctionItem), (intptr_t)1 },
    { "namedItem", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsMimeTypeArrayPrototypeFunctionNamedItem), (intptr_t)1 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSMimeTypeArrayPrototypeTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 7, JSMimeTypeArrayPrototypeTableValues, 0 };
#else
    { 5, 3, JSMimeTypeArrayPrototypeTableValues, 0 };
#endif

const ClassInfo JSMimeTypeArrayPrototype::s_info = { "MimeTypeArrayPrototype", 0, &JSMimeTypeArrayPrototypeTable, 0 };

JSObject* JSMimeTypeArrayPrototype::self(ExecState* exec, JSGlobalObject* globalObject)
{
    return getDOMPrototype<JSMimeTypeArray>(exec, globalObject);
}

bool JSMimeTypeArrayPrototype::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticFunctionSlot<JSObject>(exec, &JSMimeTypeArrayPrototypeTable, this, propertyName, slot);
}

bool JSMimeTypeArrayPrototype::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    return getStaticFunctionDescriptor<JSObject>(exec, &JSMimeTypeArrayPrototypeTable, this, propertyName, descriptor);
}

const ClassInfo JSMimeTypeArray::s_info = { "MimeTypeArray", 0, &JSMimeTypeArrayTable, 0 };

JSMimeTypeArray::JSMimeTypeArray(NonNullPassRefPtr<Structure> structure, JSDOMGlobalObject* globalObject, PassRefPtr<MimeTypeArray> impl)
    : DOMObjectWithGlobalPointer(structure, globalObject)
    , m_impl(impl)
{
}

JSMimeTypeArray::~JSMimeTypeArray()
{
    forgetDOMObject(this, impl());
}

JSObject* JSMimeTypeArray::createPrototype(ExecState* exec, JSGlobalObject* globalObject)
{
    return new (exec) JSMimeTypeArrayPrototype(JSMimeTypeArrayPrototype::createStructure(globalObject->objectPrototype()));
}

bool JSMimeTypeArray::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    const HashEntry* entry = JSMimeTypeArrayTable.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<MimeTypeArray*>(impl())->length()) {
        slot.setCustomIndex(this, index, indexGetter);
        return true;
    }
    if (canGetItemsForName(exec, static_cast<MimeTypeArray*>(impl()), propertyName)) {
        slot.setCustom(this, nameGetter);
        return true;
    }
    return getStaticValueSlot<JSMimeTypeArray, Base>(exec, &JSMimeTypeArrayTable, this, propertyName, slot);
}

bool JSMimeTypeArray::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    const HashEntry* entry = JSMimeTypeArrayTable.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<MimeTypeArray*>(impl())->length()) {
        PropertySlot slot;
        slot.setCustomIndex(this, index, indexGetter);
        descriptor.setDescriptor(slot.getValue(exec, propertyName), DontDelete | ReadOnly);
        return true;
    }
    if (canGetItemsForName(exec, static_cast<MimeTypeArray*>(impl()), propertyName)) {
        PropertySlot slot;
        slot.setCustom(this, nameGetter);
        descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum);
        return true;
    }
    return getStaticValueDescriptor<JSMimeTypeArray, Base>(exec, &JSMimeTypeArrayTable, this, propertyName, descriptor);
}

bool JSMimeTypeArray::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
{
    if (propertyName < static_cast<MimeTypeArray*>(impl())->length()) {
        slot.setCustomIndex(this, propertyName, indexGetter);
        return true;
    }
    return getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot);
}

JSValue jsMimeTypeArrayLength(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSMimeTypeArray* castedThis = static_cast<JSMimeTypeArray*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    MimeTypeArray* imp = static_cast<MimeTypeArray*>(castedThis->impl());
    JSValue result = jsNumber(exec, imp->length());
    return result;
}

JSValue jsMimeTypeArrayConstructor(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSMimeTypeArray* domObject = static_cast<JSMimeTypeArray*>(asObject(slotBase));
    return JSMimeTypeArray::getConstructor(exec, domObject->globalObject());
}
void JSMimeTypeArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
{
    for (unsigned i = 0; i < static_cast<MimeTypeArray*>(impl())->length(); ++i)
        propertyNames.add(Identifier::from(exec, i));
     Base::getOwnPropertyNames(exec, propertyNames, mode);
}

JSValue JSMimeTypeArray::getConstructor(ExecState* exec, JSGlobalObject* globalObject)
{
    return getDOMConstructor<JSMimeTypeArrayConstructor>(exec, static_cast<JSDOMGlobalObject*>(globalObject));
}

JSValue JSC_HOST_CALL jsMimeTypeArrayPrototypeFunctionItem(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSMimeTypeArray::s_info))
        return throwError(exec, TypeError);
    JSMimeTypeArray* castedThisObj = static_cast<JSMimeTypeArray*>(asObject(thisValue));
    MimeTypeArray* imp = static_cast<MimeTypeArray*>(castedThisObj->impl());
    unsigned index = args.at(0).toInt32(exec);


    JSC::JSValue result = toJS(exec, castedThisObj->globalObject(), WTF::getPtr(imp->item(index)));
    return result;
}

JSValue JSC_HOST_CALL jsMimeTypeArrayPrototypeFunctionNamedItem(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSMimeTypeArray::s_info))
        return throwError(exec, TypeError);
    JSMimeTypeArray* castedThisObj = static_cast<JSMimeTypeArray*>(asObject(thisValue));
    MimeTypeArray* imp = static_cast<MimeTypeArray*>(castedThisObj->impl());
    const UString& name = args.at(0).toString(exec);


    JSC::JSValue result = toJS(exec, castedThisObj->globalObject(), WTF::getPtr(imp->namedItem(name)));
    return result;
}


JSValue JSMimeTypeArray::indexGetter(ExecState* exec, JSValue slotBase, unsigned index)
{
    JSMimeTypeArray* thisObj = static_cast<JSMimeTypeArray*>(asObject(slotBase));
    return toJS(exec, thisObj->globalObject(), static_cast<MimeTypeArray*>(thisObj->impl())->item(index));
}
JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, MimeTypeArray* object)
{
    return getDOMObjectWrapper<JSMimeTypeArray>(exec, globalObject, object);
}
MimeTypeArray* toMimeTypeArray(JSC::JSValue value)
{
    return value.inherits(&JSMimeTypeArray::s_info) ? static_cast<JSMimeTypeArray*>(asObject(value))->impl() : 0;
}

}
