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

#include <wtf/GetPtr.h>

#include "DocumentFragment.h"
#include "ExceptionCode.h"
#include "JSDocumentFragment.h"
#include "JSNode.h"
#include "JSRange.h"
#include "Node.h"
#include "PlatformString.h"
#include "Range.h"

using namespace KJS;

namespace WebCore {

/* Hash table */

static const HashEntry JSRangeTableEntries[] =
{
    { "endOffset", JSRange::EndOffsetAttrNum, DontDelete|ReadOnly, 0, &JSRangeTableEntries[7] },
    { "startOffset", JSRange::StartOffsetAttrNum, DontDelete|ReadOnly, 0, &JSRangeTableEntries[8] },
    { "endContainer", JSRange::EndContainerAttrNum, DontDelete|ReadOnly, 0, &JSRangeTableEntries[9] },
    { 0, 0, 0, 0, 0 },
    { 0, 0, 0, 0, 0 },
    { "startContainer", JSRange::StartContainerAttrNum, DontDelete|ReadOnly, 0, 0 },
    { 0, 0, 0, 0, 0 },
    { "collapsed", JSRange::CollapsedAttrNum, DontDelete|ReadOnly, 0, 0 },
    { "commonAncestorContainer", JSRange::CommonAncestorContainerAttrNum, DontDelete|ReadOnly, 0, 0 },
    { "constructor", JSRange::ConstructorAttrNum, DontDelete|DontEnum|ReadOnly, 0, 0 }
};

static const HashTable JSRangeTable = 
{
    2, 10, JSRangeTableEntries, 7
};

/* Hash table for constructor */

static const HashEntry JSRangeConstructorTableEntries[] =
{
    { "START_TO_START", Range::START_TO_START, DontDelete|ReadOnly, 0, 0 },
    { "NODE_AFTER", Range::NODE_AFTER, DontDelete|ReadOnly, 0, 0 },
    { 0, 0, 0, 0, 0 },
    { 0, 0, 0, 0, 0 },
    { 0, 0, 0, 0, 0 },
    { "NODE_BEFORE", Range::NODE_BEFORE, DontDelete|ReadOnly, 0, 0 },
    { "START_TO_END", Range::START_TO_END, DontDelete|ReadOnly, 0, &JSRangeConstructorTableEntries[9] },
    { "END_TO_END", Range::END_TO_END, DontDelete|ReadOnly, 0, &JSRangeConstructorTableEntries[8] },
    { "END_TO_START", Range::END_TO_START, DontDelete|ReadOnly, 0, 0 },
    { "NODE_BEFORE_AND_AFTER", Range::NODE_BEFORE_AND_AFTER, DontDelete|ReadOnly, 0, &JSRangeConstructorTableEntries[10] },
    { "NODE_INSIDE", Range::NODE_INSIDE, DontDelete|ReadOnly, 0, 0 }
};

static const HashTable JSRangeConstructorTable = 
{
    2, 11, JSRangeConstructorTableEntries, 8
};

class JSRangeConstructor : public DOMObject {
public:
    JSRangeConstructor(ExecState* exec)
    {
        setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype());
        putDirect(exec->propertyNames().prototype, JSRangePrototype::self(exec), None);
    }
    virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
    JSValue* getValueProperty(ExecState*, int token) const;
    virtual const ClassInfo* classInfo() const { return &info; }
    static const ClassInfo info;

    virtual bool implementsHasInstance() const { return true; }
};

const ClassInfo JSRangeConstructor::info = { "RangeConstructor", 0, &JSRangeConstructorTable, 0 };

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

JSValue* JSRangeConstructor::getValueProperty(ExecState*, int token) const
{
    // The token is the numeric value of its associated constant
    return jsNumber(token);
}

/* Hash table for prototype */

static const HashEntry JSRangePrototypeTableEntries[] =
{
    { "START_TO_START", Range::START_TO_START, DontDelete|ReadOnly, 0, 0 },
    { "setEnd", JSRange::SetEndFuncNum, DontDelete|Function, 2, &JSRangePrototypeTableEntries[38] },
    { "selectNode", JSRange::SelectNodeFuncNum, DontDelete|Function, 1, 0 },
    { "setStartAfter", JSRange::SetStartAfterFuncNum, DontDelete|Function, 1, 0 },
    { "START_TO_END", Range::START_TO_END, DontDelete|ReadOnly, 0, 0 },
    { "cloneContents", JSRange::CloneContentsFuncNum, DontDelete|Function, 0, &JSRangePrototypeTableEntries[39] },
    { "NODE_BEFORE", Range::NODE_BEFORE, DontDelete|ReadOnly, 0, &JSRangePrototypeTableEntries[31] },
    { "setEndAfter", JSRange::SetEndAfterFuncNum, DontDelete|Function, 1, 0 },
    { "NODE_INSIDE", Range::NODE_INSIDE, DontDelete|ReadOnly, 0, 0 },
    { 0, 0, 0, 0, 0 },
    { 0, 0, 0, 0, 0 },
    { "surroundContents", JSRange::SurroundContentsFuncNum, DontDelete|Function, 1, 0 },
    { "insertNode", JSRange::InsertNodeFuncNum, DontDelete|Function, 1, &JSRangePrototypeTableEntries[35] },
    { "END_TO_END", Range::END_TO_END, DontDelete|ReadOnly, 0, 0 },
    { "setStartBefore", JSRange::SetStartBeforeFuncNum, DontDelete|Function, 1, &JSRangePrototypeTableEntries[40] },
    { 0, 0, 0, 0, 0 },
    { 0, 0, 0, 0, 0 },
    { "cloneRange", JSRange::CloneRangeFuncNum, DontDelete|Function, 0, 0 },
    { 0, 0, 0, 0, 0 },
    { "NODE_BEFORE_AND_AFTER", Range::NODE_BEFORE_AND_AFTER, DontDelete|ReadOnly, 0, 0 },
    { "selectNodeContents", JSRange::SelectNodeContentsFuncNum, DontDelete|Function, 1, &JSRangePrototypeTableEntries[33] },
    { 0, 0, 0, 0, 0 },
    { "detach", JSRange::DetachFuncNum, DontDelete|Function, 0, 0 },
    { "setStart", JSRange::SetStartFuncNum, DontDelete|Function, 2, &JSRangePrototypeTableEntries[36] },
    { "NODE_AFTER", Range::NODE_AFTER, DontDelete|ReadOnly, 0, &JSRangePrototypeTableEntries[34] },
    { "compareBoundaryPoints", JSRange::CompareBoundaryPointsFuncNum, DontDelete|Function, 2, 0 },
    { "END_TO_START", Range::END_TO_START, DontDelete|ReadOnly, 0, &JSRangePrototypeTableEntries[32] },
    { 0, 0, 0, 0, 0 },
    { 0, 0, 0, 0, 0 },
    { 0, 0, 0, 0, 0 },
    { 0, 0, 0, 0, 0 },
    { "setEndBefore", JSRange::SetEndBeforeFuncNum, DontDelete|Function, 1, 0 },
    { "collapse", JSRange::CollapseFuncNum, DontDelete|Function, 1, 0 },
    { "deleteContents", JSRange::DeleteContentsFuncNum, DontDelete|Function, 0, &JSRangePrototypeTableEntries[37] },
    { "extractContents", JSRange::ExtractContentsFuncNum, DontDelete|Function, 0, 0 },
    { "toString", JSRange::ToStringFuncNum, DontDelete|Function, 0, 0 },
    { "createContextualFragment", JSRange::CreateContextualFragmentFuncNum, DontDelete|Function, 1, 0 },
    { "intersectsNode", JSRange::IntersectsNodeFuncNum, DontDelete|Function, 1, 0 },
    { "compareNode", JSRange::CompareNodeFuncNum, DontDelete|Function, 1, 0 },
    { "comparePoint", JSRange::ComparePointFuncNum, DontDelete|Function, 2, 0 },
    { "isPointInRange", JSRange::IsPointInRangeFuncNum, DontDelete|Function, 2, 0 }
};

static const HashTable JSRangePrototypeTable = 
{
    2, 41, JSRangePrototypeTableEntries, 31
};

const ClassInfo JSRangePrototype::info = { "RangePrototype", 0, &JSRangePrototypeTable, 0 };

JSObject* JSRangePrototype::self(ExecState* exec)
{
    return KJS::cacheGlobalObject<JSRangePrototype>(exec, "[[JSRange.prototype]]");
}

bool JSRangePrototype::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticPropertySlot<JSRangePrototypeFunction, JSRangePrototype, JSObject>(exec, &JSRangePrototypeTable, this, propertyName, slot);
}

JSValue* JSRangePrototype::getValueProperty(ExecState*, int token) const
{
    // The token is the numeric value of its associated constant
    return jsNumber(token);
}

const ClassInfo JSRange::info = { "Range", 0, &JSRangeTable, 0 };

JSRange::JSRange(ExecState* exec, Range* impl)
    : m_impl(impl)
{
    setPrototype(JSRangePrototype::self(exec));
}

JSRange::~JSRange()
{
    ScriptInterpreter::forgetDOMObject(m_impl.get());
}

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

JSValue* JSRange::getValueProperty(ExecState* exec, int token) const
{
    switch (token) {
    case StartContainerAttrNum: {
        ExceptionCode ec = 0;
        Range* imp = static_cast<Range*>(impl());

        KJS::JSValue* result = toJS(exec, WTF::getPtr(imp->startContainer(ec)));
        setDOMException(exec, ec);
        return result;
    }
    case StartOffsetAttrNum: {
        ExceptionCode ec = 0;
        Range* imp = static_cast<Range*>(impl());

        KJS::JSValue* result = jsNumber(imp->startOffset(ec));
        setDOMException(exec, ec);
        return result;
    }
    case EndContainerAttrNum: {
        ExceptionCode ec = 0;
        Range* imp = static_cast<Range*>(impl());

        KJS::JSValue* result = toJS(exec, WTF::getPtr(imp->endContainer(ec)));
        setDOMException(exec, ec);
        return result;
    }
    case EndOffsetAttrNum: {
        ExceptionCode ec = 0;
        Range* imp = static_cast<Range*>(impl());

        KJS::JSValue* result = jsNumber(imp->endOffset(ec));
        setDOMException(exec, ec);
        return result;
    }
    case CollapsedAttrNum: {
        ExceptionCode ec = 0;
        Range* imp = static_cast<Range*>(impl());

        KJS::JSValue* result = jsBoolean(imp->collapsed(ec));
        setDOMException(exec, ec);
        return result;
    }
    case CommonAncestorContainerAttrNum: {
        ExceptionCode ec = 0;
        Range* imp = static_cast<Range*>(impl());

        KJS::JSValue* result = toJS(exec, WTF::getPtr(imp->commonAncestorContainer(ec)));
        setDOMException(exec, ec);
        return result;
    }
    case ConstructorAttrNum:
        return getConstructor(exec);
    }
    return 0;
}

JSValue* JSRange::getConstructor(ExecState* exec)
{
    return KJS::cacheGlobalObject<JSRangeConstructor>(exec, "[[Range.constructor]]");
}
JSValue* JSRangePrototypeFunction::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
{
    if (!thisObj->inherits(&JSRange::info))
      return throwError(exec, TypeError);

    Range* imp = static_cast<Range*>(static_cast<JSRange*>(thisObj)->impl());

    switch (id) {
    case JSRange::SetStartFuncNum: {
        ExceptionCode ec = 0;
        Node* refNode = toNode(args[0]);
        bool offsetOk;
        int offset = args[1]->toInt32(exec, offsetOk);
        if (!offsetOk) {
            setDOMException(exec, TYPE_MISMATCH_ERR);
            return jsUndefined();
        }

        imp->setStart(refNode, offset, ec);
        setDOMException(exec, ec);
        return jsUndefined();
    }
    case JSRange::SetEndFuncNum: {
        ExceptionCode ec = 0;
        Node* refNode = toNode(args[0]);
        bool offsetOk;
        int offset = args[1]->toInt32(exec, offsetOk);
        if (!offsetOk) {
            setDOMException(exec, TYPE_MISMATCH_ERR);
            return jsUndefined();
        }

        imp->setEnd(refNode, offset, ec);
        setDOMException(exec, ec);
        return jsUndefined();
    }
    case JSRange::SetStartBeforeFuncNum: {
        ExceptionCode ec = 0;
        Node* refNode = toNode(args[0]);

        imp->setStartBefore(refNode, ec);
        setDOMException(exec, ec);
        return jsUndefined();
    }
    case JSRange::SetStartAfterFuncNum: {
        ExceptionCode ec = 0;
        Node* refNode = toNode(args[0]);

        imp->setStartAfter(refNode, ec);
        setDOMException(exec, ec);
        return jsUndefined();
    }
    case JSRange::SetEndBeforeFuncNum: {
        ExceptionCode ec = 0;
        Node* refNode = toNode(args[0]);

        imp->setEndBefore(refNode, ec);
        setDOMException(exec, ec);
        return jsUndefined();
    }
    case JSRange::SetEndAfterFuncNum: {
        ExceptionCode ec = 0;
        Node* refNode = toNode(args[0]);

        imp->setEndAfter(refNode, ec);
        setDOMException(exec, ec);
        return jsUndefined();
    }
    case JSRange::CollapseFuncNum: {
        ExceptionCode ec = 0;
        bool toStart = args[0]->toBoolean(exec);

        imp->collapse(toStart, ec);
        setDOMException(exec, ec);
        return jsUndefined();
    }
    case JSRange::SelectNodeFuncNum: {
        ExceptionCode ec = 0;
        Node* refNode = toNode(args[0]);

        imp->selectNode(refNode, ec);
        setDOMException(exec, ec);
        return jsUndefined();
    }
    case JSRange::SelectNodeContentsFuncNum: {
        ExceptionCode ec = 0;
        Node* refNode = toNode(args[0]);

        imp->selectNodeContents(refNode, ec);
        setDOMException(exec, ec);
        return jsUndefined();
    }
    case JSRange::CompareBoundaryPointsFuncNum: {
        ExceptionCode ec = 0;
        Range::CompareHow how = static_cast<Range::CompareHow>(args[0]->toInt32(exec));
        Range* sourceRange = toRange(args[1]);


        KJS::JSValue* result = jsNumber(imp->compareBoundaryPoints(how, sourceRange, ec));
        setDOMException(exec, ec);
        return result;
    }
    case JSRange::DeleteContentsFuncNum: {
        ExceptionCode ec = 0;

        imp->deleteContents(ec);
        setDOMException(exec, ec);
        return jsUndefined();
    }
    case JSRange::ExtractContentsFuncNum: {
        ExceptionCode ec = 0;


        KJS::JSValue* result = toJS(exec, WTF::getPtr(imp->extractContents(ec)));
        setDOMException(exec, ec);
        return result;
    }
    case JSRange::CloneContentsFuncNum: {
        ExceptionCode ec = 0;


        KJS::JSValue* result = toJS(exec, WTF::getPtr(imp->cloneContents(ec)));
        setDOMException(exec, ec);
        return result;
    }
    case JSRange::InsertNodeFuncNum: {
        ExceptionCode ec = 0;
        Node* newNode = toNode(args[0]);

        imp->insertNode(newNode, ec);
        setDOMException(exec, ec);
        return jsUndefined();
    }
    case JSRange::SurroundContentsFuncNum: {
        ExceptionCode ec = 0;
        Node* newParent = toNode(args[0]);

        imp->surroundContents(newParent, ec);
        setDOMException(exec, ec);
        return jsUndefined();
    }
    case JSRange::CloneRangeFuncNum: {
        ExceptionCode ec = 0;


        KJS::JSValue* result = toJS(exec, WTF::getPtr(imp->cloneRange(ec)));
        setDOMException(exec, ec);
        return result;
    }
    case JSRange::ToStringFuncNum: {
        ExceptionCode ec = 0;


        KJS::JSValue* result = jsString(imp->toString(ec));
        setDOMException(exec, ec);
        return result;
    }
    case JSRange::DetachFuncNum: {
        ExceptionCode ec = 0;

        imp->detach(ec);
        setDOMException(exec, ec);
        return jsUndefined();
    }
    case JSRange::CreateContextualFragmentFuncNum: {
        ExceptionCode ec = 0;
        String html = args[0]->toString(exec);


        KJS::JSValue* result = toJS(exec, WTF::getPtr(imp->createContextualFragment(html, ec)));
        setDOMException(exec, ec);
        return result;
    }
    case JSRange::IntersectsNodeFuncNum: {
        ExceptionCode ec = 0;
        Node* refNode = toNode(args[0]);


        KJS::JSValue* result = jsBoolean(imp->intersectsNode(refNode, ec));
        setDOMException(exec, ec);
        return result;
    }
    case JSRange::CompareNodeFuncNum: {
        ExceptionCode ec = 0;
        Node* refNode = toNode(args[0]);


        KJS::JSValue* result = jsNumber(imp->compareNode(refNode, ec));
        setDOMException(exec, ec);
        return result;
    }
    case JSRange::ComparePointFuncNum: {
        ExceptionCode ec = 0;
        Node* refNode = toNode(args[0]);
        bool offsetOk;
        int offset = args[1]->toInt32(exec, offsetOk);
        if (!offsetOk) {
            setDOMException(exec, TYPE_MISMATCH_ERR);
            return jsUndefined();
        }


        KJS::JSValue* result = jsNumber(imp->comparePoint(refNode, offset, ec));
        setDOMException(exec, ec);
        return result;
    }
    case JSRange::IsPointInRangeFuncNum: {
        ExceptionCode ec = 0;
        Node* refNode = toNode(args[0]);
        bool offsetOk;
        int offset = args[1]->toInt32(exec, offsetOk);
        if (!offsetOk) {
            setDOMException(exec, TYPE_MISMATCH_ERR);
            return jsUndefined();
        }


        KJS::JSValue* result = jsBoolean(imp->isPointInRange(refNode, offset, ec));
        setDOMException(exec, ec);
        return result;
    }
    }
    return 0;
}
KJS::JSValue* toJS(KJS::ExecState* exec, Range* obj)
{
    return KJS::cacheDOMObject<Range, JSRange>(exec, obj);
}
Range* toRange(KJS::JSValue* val)
{
    return val->isObject(&JSRange::info) ? static_cast<JSRange*>(val)->impl() : 0;
}

}
