/**
  * Event.simulate(@element, eventName[, options]) -> Element
  *  *
  *   * - @element: element to fire event on
  *    * - eventName: name of event to fire (only MouseEvents and HTMLEvents interfaces are supported)
  *     * - options: optional object to fine-tune event properties - pointerX, pointerY, ctrlKey, etc.
  *      *
  *       *    $('foo').simulate('click'); // => fires "click" event on an element with id=foo
  *        *
  *         **/
(function(){

 var eventMatchers = {
 'HTMLEvents': /^(?:load|unload|abort|error|select|change|submit|reset|focus|blur|resize|scroll)$/,
 'MouseEvents': /^(?:click|mouse(?:down|up|over|move|out))$/
 }
 var defaultOptions = {
pointerX: 0,
pointerY: 0,
button: 0,
ctrlKey: false,
altKey: false,
shiftKey: false,
metaKey: false,
bubbles: true,
cancelable: true
}

Event.simulate = function(element, eventName) {
var options = Object.extend(defaultOptions, arguments[2] || { });
var oEvent, eventType = null;

element = $(element);

for (var name in eventMatchers) {
    if (eventMatchers[name].test(eventName)) { eventType = name; break; }
}

if (!eventType)
    throw new SyntaxError('Only HTMLEvents and MouseEvents interfaces are supported');

    if (document.createEvent) {
        oEvent = document.createEvent(eventType);
        if (eventType == 'HTMLEvents') {
            oEvent.initEvent(eventName, options.bubbles, options.cancelable);
        }
        else {
            oEvent.initMouseEvent(eventName, options.bubbles, options.cancelable, document.defaultView,
                    options.button, options.pointerX, options.pointerY, options.pointerX, options.pointerY,
                    options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.button, element);
        }
        element.dispatchEvent(oEvent);
    }
else {
    options.clientX = options.pointerX;
    options.clientY = options.pointerY;
    oEvent = Object.extend(document.createEventObject(), options);
    element.fireEvent('on' + eventName, oEvent);
}
return element;
}

Element.addMethods({ simulate: Event.simulate });
})()

