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

#include "JSNode.h"
#include "JSNodeFilter.h"
#include "Node.h"
#include "NodeFilter.h"
#include "TreeWalker.h"
#include <runtime/Error.h>
#include <runtime/JSNumberCell.h>
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

ASSERT_CLASS_FITS_IN_CELL(JSTreeWalker);

/* Hash table */

static const HashTableValue JSTreeWalkerTableValues[7] =
{
    { "root", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTreeWalkerRoot), (intptr_t)0 },
    { "whatToShow", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTreeWalkerWhatToShow), (intptr_t)0 },
    { "filter", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTreeWalkerFilter), (intptr_t)0 },
    { "expandEntityReferences", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTreeWalkerExpandEntityReferences), (intptr_t)0 },
    { "currentNode", DontDelete, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTreeWalkerCurrentNode), (intptr_t)setJSTreeWalkerCurrentNode },
    { "constructor", DontEnum|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTreeWalkerConstructor), (intptr_t)0 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSTreeWalkerTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 255, JSTreeWalkerTableValues, 0 };
#else
    { 18, 15, JSTreeWalkerTableValues, 0 };
#endif

/* Hash table for constructor */

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

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

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

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

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

/* Hash table for prototype */

static const HashTableValue JSTreeWalkerPrototypeTableValues[8] =
{
    { "parentNode", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsTreeWalkerPrototypeFunctionParentNode), (intptr_t)0 },
    { "firstChild", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsTreeWalkerPrototypeFunctionFirstChild), (intptr_t)0 },
    { "lastChild", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsTreeWalkerPrototypeFunctionLastChild), (intptr_t)0 },
    { "previousSibling", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsTreeWalkerPrototypeFunctionPreviousSibling), (intptr_t)0 },
    { "nextSibling", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsTreeWalkerPrototypeFunctionNextSibling), (intptr_t)0 },
    { "previousNode", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsTreeWalkerPrototypeFunctionPreviousNode), (intptr_t)0 },
    { "nextNode", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsTreeWalkerPrototypeFunctionNextNode), (intptr_t)0 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSTreeWalkerPrototypeTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 15, JSTreeWalkerPrototypeTableValues, 0 };
#else
    { 16, 15, JSTreeWalkerPrototypeTableValues, 0 };
#endif

const ClassInfo JSTreeWalkerPrototype::s_info = { "TreeWalkerPrototype", 0, &JSTreeWalkerPrototypeTable, 0 };

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

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

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

const ClassInfo JSTreeWalker::s_info = { "TreeWalker", 0, &JSTreeWalkerTable, 0 };

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

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

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

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

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

JSValue jsTreeWalkerRoot(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSTreeWalker* castedThis = static_cast<JSTreeWalker*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    TreeWalker* imp = static_cast<TreeWalker*>(castedThis->impl());
    JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->root()));
    return result;
}

JSValue jsTreeWalkerWhatToShow(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSTreeWalker* castedThis = static_cast<JSTreeWalker*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    TreeWalker* imp = static_cast<TreeWalker*>(castedThis->impl());
    JSValue result = jsNumber(exec, imp->whatToShow());
    return result;
}

JSValue jsTreeWalkerFilter(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSTreeWalker* castedThis = static_cast<JSTreeWalker*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    TreeWalker* imp = static_cast<TreeWalker*>(castedThis->impl());
    JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->filter()));
    return result;
}

JSValue jsTreeWalkerExpandEntityReferences(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSTreeWalker* castedThis = static_cast<JSTreeWalker*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    TreeWalker* imp = static_cast<TreeWalker*>(castedThis->impl());
    JSValue result = jsBoolean(imp->expandEntityReferences());
    return result;
}

JSValue jsTreeWalkerCurrentNode(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSTreeWalker* castedThis = static_cast<JSTreeWalker*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    TreeWalker* imp = static_cast<TreeWalker*>(castedThis->impl());
    JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->currentNode()));
    return result;
}

JSValue jsTreeWalkerConstructor(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSTreeWalker* domObject = static_cast<JSTreeWalker*>(asObject(slotBase));
    return JSTreeWalker::getConstructor(exec, domObject->globalObject());
}
void JSTreeWalker::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
    lookupPut<JSTreeWalker, Base>(exec, propertyName, value, &JSTreeWalkerTable, this, slot);
}

void setJSTreeWalkerCurrentNode(ExecState* exec, JSObject* thisObject, JSValue value)
{
    JSTreeWalker* castedThisObj = static_cast<JSTreeWalker*>(thisObject);
    TreeWalker* imp = static_cast<TreeWalker*>(castedThisObj->impl());
    ExceptionCode ec = 0;
    imp->setCurrentNode(toNode(value), ec);
    setDOMException(exec, ec);
}

JSValue JSTreeWalker::getConstructor(ExecState* exec, JSGlobalObject* globalObject)
{
    return getDOMConstructor<JSTreeWalkerConstructor>(exec, static_cast<JSDOMGlobalObject*>(globalObject));
}

JSValue JSC_HOST_CALL jsTreeWalkerPrototypeFunctionParentNode(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSTreeWalker::s_info))
        return throwError(exec, TypeError);
    JSTreeWalker* castedThisObj = static_cast<JSTreeWalker*>(asObject(thisValue));
    return castedThisObj->parentNode(exec, args);
}

JSValue JSC_HOST_CALL jsTreeWalkerPrototypeFunctionFirstChild(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSTreeWalker::s_info))
        return throwError(exec, TypeError);
    JSTreeWalker* castedThisObj = static_cast<JSTreeWalker*>(asObject(thisValue));
    return castedThisObj->firstChild(exec, args);
}

JSValue JSC_HOST_CALL jsTreeWalkerPrototypeFunctionLastChild(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSTreeWalker::s_info))
        return throwError(exec, TypeError);
    JSTreeWalker* castedThisObj = static_cast<JSTreeWalker*>(asObject(thisValue));
    return castedThisObj->lastChild(exec, args);
}

JSValue JSC_HOST_CALL jsTreeWalkerPrototypeFunctionPreviousSibling(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSTreeWalker::s_info))
        return throwError(exec, TypeError);
    JSTreeWalker* castedThisObj = static_cast<JSTreeWalker*>(asObject(thisValue));
    return castedThisObj->previousSibling(exec, args);
}

JSValue JSC_HOST_CALL jsTreeWalkerPrototypeFunctionNextSibling(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSTreeWalker::s_info))
        return throwError(exec, TypeError);
    JSTreeWalker* castedThisObj = static_cast<JSTreeWalker*>(asObject(thisValue));
    return castedThisObj->nextSibling(exec, args);
}

JSValue JSC_HOST_CALL jsTreeWalkerPrototypeFunctionPreviousNode(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSTreeWalker::s_info))
        return throwError(exec, TypeError);
    JSTreeWalker* castedThisObj = static_cast<JSTreeWalker*>(asObject(thisValue));
    return castedThisObj->previousNode(exec, args);
}

JSValue JSC_HOST_CALL jsTreeWalkerPrototypeFunctionNextNode(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSTreeWalker::s_info))
        return throwError(exec, TypeError);
    JSTreeWalker* castedThisObj = static_cast<JSTreeWalker*>(asObject(thisValue));
    return castedThisObj->nextNode(exec, args);
}

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

}
