/*
    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 "JSMouseEvent.h"

#include "Clipboard.h"
#include "EventTarget.h"
#include "JSClipboard.h"
#include "JSDOMWindow.h"
#include "JSEventTarget.h"
#include "JSNode.h"
#include "MouseEvent.h"
#include "Node.h"
#include <runtime/Error.h>
#include <runtime/JSNumberCell.h>
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

ASSERT_CLASS_FITS_IN_CELL(JSMouseEvent);

/* Hash table */

static const HashTableValue JSMouseEventTableValues[19] =
{
    { "screenX", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMouseEventScreenX), (intptr_t)0 },
    { "screenY", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMouseEventScreenY), (intptr_t)0 },
    { "clientX", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMouseEventClientX), (intptr_t)0 },
    { "clientY", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMouseEventClientY), (intptr_t)0 },
    { "ctrlKey", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMouseEventCtrlKey), (intptr_t)0 },
    { "shiftKey", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMouseEventShiftKey), (intptr_t)0 },
    { "altKey", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMouseEventAltKey), (intptr_t)0 },
    { "metaKey", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMouseEventMetaKey), (intptr_t)0 },
    { "button", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMouseEventButton), (intptr_t)0 },
    { "relatedTarget", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMouseEventRelatedTarget), (intptr_t)0 },
    { "offsetX", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMouseEventOffsetX), (intptr_t)0 },
    { "offsetY", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMouseEventOffsetY), (intptr_t)0 },
    { "x", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMouseEventX), (intptr_t)0 },
    { "y", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMouseEventY), (intptr_t)0 },
    { "fromElement", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMouseEventFromElement), (intptr_t)0 },
    { "toElement", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMouseEventToElement), (intptr_t)0 },
    { "dataTransfer", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMouseEventDataTransfer), (intptr_t)0 },
    { "constructor", DontEnum|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMouseEventConstructor), (intptr_t)0 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSMouseEventTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 127, JSMouseEventTableValues, 0 };
#else
    { 65, 63, JSMouseEventTableValues, 0 };
#endif

/* Hash table for constructor */

static const HashTableValue JSMouseEventConstructorTableValues[1] =
{
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSMouseEventConstructorTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 0, JSMouseEventConstructorTableValues, 0 };
#else
    { 1, 0, JSMouseEventConstructorTableValues, 0 };
#endif

class JSMouseEventConstructor : public DOMConstructorObject {
public:
    JSMouseEventConstructor(ExecState* exec, JSDOMGlobalObject* globalObject)
        : DOMConstructorObject(JSMouseEventConstructor::createStructure(globalObject->objectPrototype()), globalObject)
    {
        putDirect(exec->propertyNames().prototype, JSMouseEventPrototype::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 JSMouseEventConstructor::s_info = { "MouseEventConstructor", 0, &JSMouseEventConstructorTable, 0 };

bool JSMouseEventConstructor::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticValueSlot<JSMouseEventConstructor, DOMObject>(exec, &JSMouseEventConstructorTable, this, propertyName, slot);
}

bool JSMouseEventConstructor::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    return getStaticValueDescriptor<JSMouseEventConstructor, DOMObject>(exec, &JSMouseEventConstructorTable, this, propertyName, descriptor);
}

/* Hash table for prototype */

static const HashTableValue JSMouseEventPrototypeTableValues[2] =
{
    { "initMouseEvent", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsMouseEventPrototypeFunctionInitMouseEvent), (intptr_t)15 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSMouseEventPrototypeTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 0, JSMouseEventPrototypeTableValues, 0 };
#else
    { 2, 1, JSMouseEventPrototypeTableValues, 0 };
#endif

const ClassInfo JSMouseEventPrototype::s_info = { "MouseEventPrototype", 0, &JSMouseEventPrototypeTable, 0 };

JSObject* JSMouseEventPrototype::self(ExecState* exec, JSGlobalObject* globalObject)
{
    return getDOMPrototype<JSMouseEvent>(exec, globalObject);
}

bool JSMouseEventPrototype::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticFunctionSlot<JSObject>(exec, &JSMouseEventPrototypeTable, this, propertyName, slot);
}

bool JSMouseEventPrototype::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    return getStaticFunctionDescriptor<JSObject>(exec, &JSMouseEventPrototypeTable, this, propertyName, descriptor);
}

const ClassInfo JSMouseEvent::s_info = { "MouseEvent", &JSUIEvent::s_info, &JSMouseEventTable, 0 };

JSMouseEvent::JSMouseEvent(NonNullPassRefPtr<Structure> structure, JSDOMGlobalObject* globalObject, PassRefPtr<MouseEvent> impl)
    : JSUIEvent(structure, globalObject, impl)
{
}

JSObject* JSMouseEvent::createPrototype(ExecState* exec, JSGlobalObject* globalObject)
{
    return new (exec) JSMouseEventPrototype(JSMouseEventPrototype::createStructure(JSUIEventPrototype::self(exec, globalObject)));
}

bool JSMouseEvent::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticValueSlot<JSMouseEvent, Base>(exec, &JSMouseEventTable, this, propertyName, slot);
}

bool JSMouseEvent::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    return getStaticValueDescriptor<JSMouseEvent, Base>(exec, &JSMouseEventTable, this, propertyName, descriptor);
}

JSValue jsMouseEventScreenX(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSMouseEvent* castedThis = static_cast<JSMouseEvent*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    MouseEvent* imp = static_cast<MouseEvent*>(castedThis->impl());
    JSValue result = jsNumber(exec, imp->screenX());
    return result;
}

JSValue jsMouseEventScreenY(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSMouseEvent* castedThis = static_cast<JSMouseEvent*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    MouseEvent* imp = static_cast<MouseEvent*>(castedThis->impl());
    JSValue result = jsNumber(exec, imp->screenY());
    return result;
}

JSValue jsMouseEventClientX(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSMouseEvent* castedThis = static_cast<JSMouseEvent*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    MouseEvent* imp = static_cast<MouseEvent*>(castedThis->impl());
    JSValue result = jsNumber(exec, imp->clientX());
    return result;
}

JSValue jsMouseEventClientY(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSMouseEvent* castedThis = static_cast<JSMouseEvent*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    MouseEvent* imp = static_cast<MouseEvent*>(castedThis->impl());
    JSValue result = jsNumber(exec, imp->clientY());
    return result;
}

JSValue jsMouseEventCtrlKey(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSMouseEvent* castedThis = static_cast<JSMouseEvent*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    MouseEvent* imp = static_cast<MouseEvent*>(castedThis->impl());
    JSValue result = jsBoolean(imp->ctrlKey());
    return result;
}

JSValue jsMouseEventShiftKey(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSMouseEvent* castedThis = static_cast<JSMouseEvent*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    MouseEvent* imp = static_cast<MouseEvent*>(castedThis->impl());
    JSValue result = jsBoolean(imp->shiftKey());
    return result;
}

JSValue jsMouseEventAltKey(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSMouseEvent* castedThis = static_cast<JSMouseEvent*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    MouseEvent* imp = static_cast<MouseEvent*>(castedThis->impl());
    JSValue result = jsBoolean(imp->altKey());
    return result;
}

JSValue jsMouseEventMetaKey(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSMouseEvent* castedThis = static_cast<JSMouseEvent*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    MouseEvent* imp = static_cast<MouseEvent*>(castedThis->impl());
    JSValue result = jsBoolean(imp->metaKey());
    return result;
}

JSValue jsMouseEventButton(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSMouseEvent* castedThis = static_cast<JSMouseEvent*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    MouseEvent* imp = static_cast<MouseEvent*>(castedThis->impl());
    JSValue result = jsNumber(exec, imp->button());
    return result;
}

JSValue jsMouseEventRelatedTarget(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSMouseEvent* castedThis = static_cast<JSMouseEvent*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    MouseEvent* imp = static_cast<MouseEvent*>(castedThis->impl());
    JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->relatedTarget()));
    return result;
}

JSValue jsMouseEventOffsetX(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSMouseEvent* castedThis = static_cast<JSMouseEvent*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    MouseEvent* imp = static_cast<MouseEvent*>(castedThis->impl());
    JSValue result = jsNumber(exec, imp->offsetX());
    return result;
}

JSValue jsMouseEventOffsetY(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSMouseEvent* castedThis = static_cast<JSMouseEvent*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    MouseEvent* imp = static_cast<MouseEvent*>(castedThis->impl());
    JSValue result = jsNumber(exec, imp->offsetY());
    return result;
}

JSValue jsMouseEventX(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSMouseEvent* castedThis = static_cast<JSMouseEvent*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    MouseEvent* imp = static_cast<MouseEvent*>(castedThis->impl());
    JSValue result = jsNumber(exec, imp->x());
    return result;
}

JSValue jsMouseEventY(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSMouseEvent* castedThis = static_cast<JSMouseEvent*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    MouseEvent* imp = static_cast<MouseEvent*>(castedThis->impl());
    JSValue result = jsNumber(exec, imp->y());
    return result;
}

JSValue jsMouseEventFromElement(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSMouseEvent* castedThis = static_cast<JSMouseEvent*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    MouseEvent* imp = static_cast<MouseEvent*>(castedThis->impl());
    JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->fromElement()));
    return result;
}

JSValue jsMouseEventToElement(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSMouseEvent* castedThis = static_cast<JSMouseEvent*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    MouseEvent* imp = static_cast<MouseEvent*>(castedThis->impl());
    JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->toElement()));
    return result;
}

JSValue jsMouseEventDataTransfer(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSMouseEvent* castedThis = static_cast<JSMouseEvent*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    MouseEvent* imp = static_cast<MouseEvent*>(castedThis->impl());
    JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->dataTransfer()));
    return result;
}

JSValue jsMouseEventConstructor(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSMouseEvent* domObject = static_cast<JSMouseEvent*>(asObject(slotBase));
    return JSMouseEvent::getConstructor(exec, domObject->globalObject());
}
JSValue JSMouseEvent::getConstructor(ExecState* exec, JSGlobalObject* globalObject)
{
    return getDOMConstructor<JSMouseEventConstructor>(exec, static_cast<JSDOMGlobalObject*>(globalObject));
}

JSValue JSC_HOST_CALL jsMouseEventPrototypeFunctionInitMouseEvent(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSMouseEvent::s_info))
        return throwError(exec, TypeError);
    JSMouseEvent* castedThisObj = static_cast<JSMouseEvent*>(asObject(thisValue));
    MouseEvent* imp = static_cast<MouseEvent*>(castedThisObj->impl());
    const UString& type = args.at(0).toString(exec);
    bool canBubble = args.at(1).toBoolean(exec);
    bool cancelable = args.at(2).toBoolean(exec);
    DOMWindow* view = toDOMWindow(args.at(3));
    int detail = args.at(4).toInt32(exec);
    int screenX = args.at(5).toInt32(exec);
    int screenY = args.at(6).toInt32(exec);
    int clientX = args.at(7).toInt32(exec);
    int clientY = args.at(8).toInt32(exec);
    bool ctrlKey = args.at(9).toBoolean(exec);
    bool altKey = args.at(10).toBoolean(exec);
    bool shiftKey = args.at(11).toBoolean(exec);
    bool metaKey = args.at(12).toBoolean(exec);
    unsigned short button = args.at(13).toInt32(exec);
    EventTarget* relatedTarget = toEventTarget(args.at(14));

    imp->initMouseEvent(type, canBubble, cancelable, view, detail, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget);
    return jsUndefined();
}


}
