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

#include "KURL.h"
#include "StyleMedia.h"
#include <runtime/Error.h>
#include <runtime/JSString.h>
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

ASSERT_CLASS_FITS_IN_CELL(JSStyleMedia);

/* Hash table */

static const HashTableValue JSStyleMediaTableValues[3] =
{
    { "type", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsStyleMediaType), (intptr_t)0 },
    { "constructor", DontEnum|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsStyleMediaConstructor), (intptr_t)0 },
    { 0, 0, 0, 0 }
};

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

/* Hash table for constructor */

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

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

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

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

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

/* Hash table for prototype */

static const HashTableValue JSStyleMediaPrototypeTableValues[2] =
{
    { "matchMedium", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsStyleMediaPrototypeFunctionMatchMedium), (intptr_t)1 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSStyleMediaPrototypeTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 0, JSStyleMediaPrototypeTableValues, 0 };
#else
    { 2, 1, JSStyleMediaPrototypeTableValues, 0 };
#endif

const ClassInfo JSStyleMediaPrototype::s_info = { "StyleMediaPrototype", 0, &JSStyleMediaPrototypeTable, 0 };

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

bool JSStyleMediaPrototype::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticFunctionSlot<JSObject>(exec, &JSStyleMediaPrototypeTable, this, propertyName, slot);
}

bool JSStyleMediaPrototype::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    return getStaticFunctionDescriptor<JSObject>(exec, &JSStyleMediaPrototypeTable, this, propertyName, descriptor);
}

const ClassInfo JSStyleMedia::s_info = { "StyleMedia", 0, &JSStyleMediaTable, 0 };

JSStyleMedia::JSStyleMedia(NonNullPassRefPtr<Structure> structure, JSDOMGlobalObject* globalObject, PassRefPtr<StyleMedia> impl)
    : DOMObjectWithGlobalPointer(structure, globalObject)
    , m_impl(impl)
{
}

JSStyleMedia::~JSStyleMedia()
{
    forgetDOMObject(this, impl());
}

JSObject* JSStyleMedia::createPrototype(ExecState* exec, JSGlobalObject* globalObject)
{
    return new (exec) JSStyleMediaPrototype(JSStyleMediaPrototype::createStructure(globalObject->objectPrototype()));
}

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

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

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

JSValue jsStyleMediaConstructor(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSStyleMedia* domObject = static_cast<JSStyleMedia*>(asObject(slotBase));
    return JSStyleMedia::getConstructor(exec, domObject->globalObject());
}
JSValue JSStyleMedia::getConstructor(ExecState* exec, JSGlobalObject* globalObject)
{
    return getDOMConstructor<JSStyleMediaConstructor>(exec, static_cast<JSDOMGlobalObject*>(globalObject));
}

JSValue JSC_HOST_CALL jsStyleMediaPrototypeFunctionMatchMedium(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSStyleMedia::s_info))
        return throwError(exec, TypeError);
    JSStyleMedia* castedThisObj = static_cast<JSStyleMedia*>(asObject(thisValue));
    StyleMedia* imp = static_cast<StyleMedia*>(castedThisObj->impl());
    const UString& mediaquery = args.at(0).toString(exec);


    JSC::JSValue result = jsBoolean(imp->matchMedium(mediaquery));
    return result;
}

JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, StyleMedia* object)
{
    return getDOMObjectWrapper<JSStyleMedia>(exec, globalObject, object);
}
StyleMedia* toStyleMedia(JSC::JSValue value)
{
    return value.inherits(&JSStyleMedia::s_info) ? static_cast<JSStyleMedia*>(asObject(value))->impl() : 0;
}

}
