/*
    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 "JSNodeFilter.h"

#include "NodeFilter.h"
#include <runtime/Error.h>
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

ASSERT_CLASS_FITS_IN_CELL(JSNodeFilter);

/* Hash table */

static const HashTableValue JSNodeFilterTableValues[2] =
{
    { "constructor", DontEnum|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterConstructor), (intptr_t)0 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSNodeFilterTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 0, JSNodeFilterTableValues, 0 };
#else
    { 2, 1, JSNodeFilterTableValues, 0 };
#endif

/* Hash table for constructor */

static const HashTableValue JSNodeFilterConstructorTableValues[17] =
{
    { "FILTER_ACCEPT", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterFILTER_ACCEPT), (intptr_t)0 },
    { "FILTER_REJECT", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterFILTER_REJECT), (intptr_t)0 },
    { "FILTER_SKIP", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterFILTER_SKIP), (intptr_t)0 },
    { "SHOW_ALL", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterSHOW_ALL), (intptr_t)0 },
    { "SHOW_ELEMENT", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterSHOW_ELEMENT), (intptr_t)0 },
    { "SHOW_ATTRIBUTE", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterSHOW_ATTRIBUTE), (intptr_t)0 },
    { "SHOW_TEXT", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterSHOW_TEXT), (intptr_t)0 },
    { "SHOW_CDATA_SECTION", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterSHOW_CDATA_SECTION), (intptr_t)0 },
    { "SHOW_ENTITY_REFERENCE", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterSHOW_ENTITY_REFERENCE), (intptr_t)0 },
    { "SHOW_ENTITY", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterSHOW_ENTITY), (intptr_t)0 },
    { "SHOW_PROCESSING_INSTRUCTION", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterSHOW_PROCESSING_INSTRUCTION), (intptr_t)0 },
    { "SHOW_COMMENT", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterSHOW_COMMENT), (intptr_t)0 },
    { "SHOW_DOCUMENT", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterSHOW_DOCUMENT), (intptr_t)0 },
    { "SHOW_DOCUMENT_TYPE", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterSHOW_DOCUMENT_TYPE), (intptr_t)0 },
    { "SHOW_DOCUMENT_FRAGMENT", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterSHOW_DOCUMENT_FRAGMENT), (intptr_t)0 },
    { "SHOW_NOTATION", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterSHOW_NOTATION), (intptr_t)0 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSNodeFilterConstructorTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 127, JSNodeFilterConstructorTableValues, 0 };
#else
    { 34, 31, JSNodeFilterConstructorTableValues, 0 };
#endif

class JSNodeFilterConstructor : public DOMConstructorObject {
public:
    JSNodeFilterConstructor(ExecState* exec, JSDOMGlobalObject* globalObject)
        : DOMConstructorObject(JSNodeFilterConstructor::createStructure(globalObject->objectPrototype()), globalObject)
    {
        putDirect(exec->propertyNames().prototype, JSNodeFilterPrototype::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 JSNodeFilterConstructor::s_info = { "NodeFilterConstructor", 0, &JSNodeFilterConstructorTable, 0 };

bool JSNodeFilterConstructor::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticValueSlot<JSNodeFilterConstructor, DOMObject>(exec, &JSNodeFilterConstructorTable, this, propertyName, slot);
}

bool JSNodeFilterConstructor::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    return getStaticValueDescriptor<JSNodeFilterConstructor, DOMObject>(exec, &JSNodeFilterConstructorTable, this, propertyName, descriptor);
}

/* Hash table for prototype */

static const HashTableValue JSNodeFilterPrototypeTableValues[18] =
{
    { "FILTER_ACCEPT", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterFILTER_ACCEPT), (intptr_t)0 },
    { "FILTER_REJECT", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterFILTER_REJECT), (intptr_t)0 },
    { "FILTER_SKIP", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterFILTER_SKIP), (intptr_t)0 },
    { "SHOW_ALL", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterSHOW_ALL), (intptr_t)0 },
    { "SHOW_ELEMENT", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterSHOW_ELEMENT), (intptr_t)0 },
    { "SHOW_ATTRIBUTE", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterSHOW_ATTRIBUTE), (intptr_t)0 },
    { "SHOW_TEXT", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterSHOW_TEXT), (intptr_t)0 },
    { "SHOW_CDATA_SECTION", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterSHOW_CDATA_SECTION), (intptr_t)0 },
    { "SHOW_ENTITY_REFERENCE", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterSHOW_ENTITY_REFERENCE), (intptr_t)0 },
    { "SHOW_ENTITY", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterSHOW_ENTITY), (intptr_t)0 },
    { "SHOW_PROCESSING_INSTRUCTION", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterSHOW_PROCESSING_INSTRUCTION), (intptr_t)0 },
    { "SHOW_COMMENT", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterSHOW_COMMENT), (intptr_t)0 },
    { "SHOW_DOCUMENT", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterSHOW_DOCUMENT), (intptr_t)0 },
    { "SHOW_DOCUMENT_TYPE", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterSHOW_DOCUMENT_TYPE), (intptr_t)0 },
    { "SHOW_DOCUMENT_FRAGMENT", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterSHOW_DOCUMENT_FRAGMENT), (intptr_t)0 },
    { "SHOW_NOTATION", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNodeFilterSHOW_NOTATION), (intptr_t)0 },
    { "acceptNode", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsNodeFilterPrototypeFunctionAcceptNode), (intptr_t)1 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSNodeFilterPrototypeTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 255, JSNodeFilterPrototypeTableValues, 0 };
#else
    { 66, 63, JSNodeFilterPrototypeTableValues, 0 };
#endif

const ClassInfo JSNodeFilterPrototype::s_info = { "NodeFilterPrototype", 0, &JSNodeFilterPrototypeTable, 0 };

JSObject* JSNodeFilterPrototype::self(ExecState* exec, JSGlobalObject* globalObject)
{
    return getDOMPrototype<JSNodeFilter>(exec, globalObject);
}

bool JSNodeFilterPrototype::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticPropertySlot<JSNodeFilterPrototype, JSObject>(exec, &JSNodeFilterPrototypeTable, this, propertyName, slot);
}

bool JSNodeFilterPrototype::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    return getStaticPropertyDescriptor<JSNodeFilterPrototype, JSObject>(exec, &JSNodeFilterPrototypeTable, this, propertyName, descriptor);
}

const ClassInfo JSNodeFilter::s_info = { "NodeFilter", 0, &JSNodeFilterTable, 0 };

JSNodeFilter::JSNodeFilter(NonNullPassRefPtr<Structure> structure, JSDOMGlobalObject* globalObject, PassRefPtr<NodeFilter> impl)
    : DOMObjectWithGlobalPointer(structure, globalObject)
    , m_impl(impl)
{
}

JSNodeFilter::~JSNodeFilter()
{
    forgetDOMObject(this, impl());
}

JSObject* JSNodeFilter::createPrototype(ExecState* exec, JSGlobalObject* globalObject)
{
    return new (exec) JSNodeFilterPrototype(JSNodeFilterPrototype::createStructure(globalObject->objectPrototype()));
}

bool JSNodeFilter::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticValueSlot<JSNodeFilter, Base>(exec, &JSNodeFilterTable, this, propertyName, slot);
}

bool JSNodeFilter::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    return getStaticValueDescriptor<JSNodeFilter, Base>(exec, &JSNodeFilterTable, this, propertyName, descriptor);
}

JSValue jsNodeFilterConstructor(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSNodeFilter* domObject = static_cast<JSNodeFilter*>(asObject(slotBase));
    return JSNodeFilter::getConstructor(exec, domObject->globalObject());
}
JSValue JSNodeFilter::getConstructor(ExecState* exec, JSGlobalObject* globalObject)
{
    return getDOMConstructor<JSNodeFilterConstructor>(exec, static_cast<JSDOMGlobalObject*>(globalObject));
}

JSValue JSC_HOST_CALL jsNodeFilterPrototypeFunctionAcceptNode(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSNodeFilter::s_info))
        return throwError(exec, TypeError);
    JSNodeFilter* castedThisObj = static_cast<JSNodeFilter*>(asObject(thisValue));
    return castedThisObj->acceptNode(exec, args);
}

// Constant getters

JSValue jsNodeFilterFILTER_ACCEPT(ExecState* exec, JSValue, const Identifier&)
{
    return jsNumber(exec, static_cast<int>(1));
}

JSValue jsNodeFilterFILTER_REJECT(ExecState* exec, JSValue, const Identifier&)
{
    return jsNumber(exec, static_cast<int>(2));
}

JSValue jsNodeFilterFILTER_SKIP(ExecState* exec, JSValue, const Identifier&)
{
    return jsNumber(exec, static_cast<int>(3));
}

JSValue jsNodeFilterSHOW_ALL(ExecState* exec, JSValue, const Identifier&)
{
    return jsNumber(exec, static_cast<int>(0xFFFFFFFF));
}

JSValue jsNodeFilterSHOW_ELEMENT(ExecState* exec, JSValue, const Identifier&)
{
    return jsNumber(exec, static_cast<int>(0x00000001));
}

JSValue jsNodeFilterSHOW_ATTRIBUTE(ExecState* exec, JSValue, const Identifier&)
{
    return jsNumber(exec, static_cast<int>(0x00000002));
}

JSValue jsNodeFilterSHOW_TEXT(ExecState* exec, JSValue, const Identifier&)
{
    return jsNumber(exec, static_cast<int>(0x00000004));
}

JSValue jsNodeFilterSHOW_CDATA_SECTION(ExecState* exec, JSValue, const Identifier&)
{
    return jsNumber(exec, static_cast<int>(0x00000008));
}

JSValue jsNodeFilterSHOW_ENTITY_REFERENCE(ExecState* exec, JSValue, const Identifier&)
{
    return jsNumber(exec, static_cast<int>(0x00000010));
}

JSValue jsNodeFilterSHOW_ENTITY(ExecState* exec, JSValue, const Identifier&)
{
    return jsNumber(exec, static_cast<int>(0x00000020));
}

JSValue jsNodeFilterSHOW_PROCESSING_INSTRUCTION(ExecState* exec, JSValue, const Identifier&)
{
    return jsNumber(exec, static_cast<int>(0x00000040));
}

JSValue jsNodeFilterSHOW_COMMENT(ExecState* exec, JSValue, const Identifier&)
{
    return jsNumber(exec, static_cast<int>(0x00000080));
}

JSValue jsNodeFilterSHOW_DOCUMENT(ExecState* exec, JSValue, const Identifier&)
{
    return jsNumber(exec, static_cast<int>(0x00000100));
}

JSValue jsNodeFilterSHOW_DOCUMENT_TYPE(ExecState* exec, JSValue, const Identifier&)
{
    return jsNumber(exec, static_cast<int>(0x00000200));
}

JSValue jsNodeFilterSHOW_DOCUMENT_FRAGMENT(ExecState* exec, JSValue, const Identifier&)
{
    return jsNumber(exec, static_cast<int>(0x00000400));
}

JSValue jsNodeFilterSHOW_NOTATION(ExecState* exec, JSValue, const Identifier&)
{
    return jsNumber(exec, static_cast<int>(0x00000800));
}

JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, NodeFilter* object)
{
    return getDOMObjectWrapper<JSNodeFilter>(exec, globalObject, object);
}

}
