(function() {

  // 2008-10-05
  function MEvent(attr) {
    for (var x in attr) {
      this[x] = attr[x];
    }
  }

  document.MEvent = MEvent;

  // 2008-09-23
  function MEventQueue() {
    this.preCycle = [];
    this.queue = [];
    this.handler = [];
    this.mouseX = 0;
    this.mouseY = 0;
  }

  function mouseX(evt) {
    if (!evt)
      evt = window.event;
    if (evt.pageX)
      return evt.pageX;
    else if (evt.clientX)
      return evt.clientX + (document.documentElement.scrollLeft ? 
                            document.documentElement.scrollLeft :
                            document.body.scrollLeft);
    else
      return 0;
  }

  function mouseY(evt) {
    if (!evt)
      evt = window.event;
    if (evt.pageY)
      return evt.pageY;
    else if (evt.clientY)
      return evt.clientY + (document.documentElement.scrollTop ?
                            document.documentElement.scrollTop :
                            document.body.scrollTop);
    else 
      return 0;
  }

  function mouseMoved(e) {

    if (!e)
      e = window.event;
    
    document.mevent.mouseX = parseInt(mouseX(e));
    document.mevent.mouseY = parseInt(mouseY(e));
  }

  MEventQueue.prototype.init =
  function meventqueue_init() {

    document.onmousemove = mouseMoved;

    this.interval = setInterval('document.mevent.cycle()', 50);
  }


  MEventQueue.prototype.append =
  function meventqueue_append(e) {

    this.queue.push(e);
  }

  MEventQueue.prototype.process =
    function meventqueue_process(e) {

    //dd("Processing: " + xb.dumpObject(e));
    for (var i = 0 ; i < this.handler.length ; i++) {
      var handler = this.handler[i];

      if (("on" + e.name) in handler) {
        try {
          handler["on" + e.name].apply(handler, [e]);
        } catch (exception) {
          alert("Event Handler failed: " + exception);
        }
      }
    }
  }

  MEventQueue.prototype.cycle =
    function meventqueue_cycle() {

    if (this.TRACE)
        dd("MEvent Precycle");

    // Before we cycle, if anyone registered we call their pre.
    for (var i = 0 ; i < this.preCycle.length ; i++) {
      this.preCycle[i]();
    }

    if (this.TRACE)
        dd("MEvent Cycle, Pending Events: " + this.queue.length);

    var start = parseInt(Date.getTime/1000);

    while (this.queue.length) {
      var e = this.queue.shift();

      this.process(e);
    }
  }

  document.mevent = new MEventQueue();

})();

MEvent = document.MEvent;

$(document).ready(function() { document.mevent.init(); });
