/* EventUtil object
*****************************************************************************/
var EventUtil = new Object();

EventUtil.oListeners = new Array();
EventUtil.EVENT_TYPE = 0;
EventUtil.EVENT_LISTENER_IMPL = 1;

/* addEventHandler method */
EventUtil.addEventHandler = function (oTarget, sEventType, fnHandler)
{
  if (oTarget.addEventListener) {
    /* DOM-compliant browsers */
    oTarget.addEventListener(sEventType, fnHandler, false);
  } else if (oTarget.attachEvent) {
    /* IE */
    oTarget.attachEvent("on" + sEventType, fnHandler);
  } else {
    /* Others */
    oTarget["on" + sEventType] = fnHandler;
  }
};

EventUtil.addObjEventListener = function (oTarget, sEventType, oObj, fnObjMethod)
{
  var oObjImpl = oObj;
  var fnObjMethodImpl = fnObjMethod;
  var oAdditionalArgs = null;
  if (arguments.length > 4) {
      var iAdditionalArgsLength = arguments.length - 4;
      oAdditionalArgs = new Array(iAdditionalArgsLength);
      for(var i=0; i<iAdditionalArgsLength; i++) {
          oAdditionalArgs[i] = arguments[i+4];
      }
  }
  function EventListenerImpl()
  {
    var oEvent = EventUtil.getEvent();
    var sExprToEval = 'fnObjMethodImpl.call(oObjImpl, oEvent';
    if (oAdditionalArgs!=null) {
        for(var i=0; i<oAdditionalArgs.length; i++) {
            sExprToEval += ', oAdditionalArgs[' + i + ']';
        }
    }
    sExprToEval += ');';    
    eval(sExprToEval);    
    //eval('fnObjMethodImpl.call(oObjImpl, oEvent, oAdditionalArgs);');
  };
  
  if (oTarget.id==undefined) {
    oTarget.id = "id" + new Date().getTime().toString(34) + Math.floor(1000000*Math.random()).toString(34);
  }
  if (EventUtil.oListeners[oTarget.id]==undefined) {
    EventUtil.oListeners[oTarget.id] = new Array();
  }
  var oCurTargetLis = EventUtil.oListeners[oTarget.id];
  var iCurTargetLisLength = oCurTargetLis.length;
  oCurTargetLis[iCurTargetLisLength] = [sEventType, EventListenerImpl];
  
  EventUtil.addEventHandler(oTarget, sEventType, EventListenerImpl);
};

EventUtil.removeObjEventListener = function (oTarget, sEventType)
{
  var oCurTargetLis = EventUtil.oListeners[oTarget.id];
  if (oCurTargetLis!=undefined) {
    function RecursiveRemove(iIndex) {
      var iCurTargetLisLength = oCurTargetLis.length;
      if (iIndex<iCurTargetLisLength) {
        var oLisData = oCurTargetLis[iIndex];
        if (oLisData[EventUtil.EVENT_TYPE]==sEventType) {
          //alert("An event listener is going tobe removed!");
          EventUtil.removeEventHandler(oTarget, sEventType, oLisData[EventUtil.EVENT_LISTENER_IMPL]);
          oCurTargetLis.splice(iIndex, 1);
          RecursiveRemove(iIndex);
        } else {
          RecursiveRemove(iIndex+1);
        }
      } else {
        //alert("RecursiveRemove ended!");
      }
    };
    RecursiveRemove(0);
  }
};

EventUtil.alertAllObjEventListeners = function (oTarget)
{
  var sOutput = "";
  var oCurTargetLis = EventUtil.oListeners[oTarget.id];
  var iCurTargetLisLength = oCurTargetLis.length;
  for(var i=0; i<iCurTargetLisLength; i++) {
    var oLisData = oCurTargetLis[i];
    sOutput += i + ": " + oLisData[EventUtil.EVENT_TYPE] + "\n" + oLisData[EventUtil.EVENT_LISTENER_IMPL] + "\n";
  }
};

/* removeEventHandler method */
EventUtil.removeEventHandler = function (oTarget, sEventType, fnHandler)
{
  if (oTarget.removeEventListener) {
    /* DOM-compliant browsers */
    oTarget.removeEventListener(sEventType, fnHandler, false);
  } else if (oTarget.detachEvent) {
    /* IE */
    oTarget.detachEvent("on" + sEventType, fnHandler);
  } else {
    oTarget["on" + sEventType] = null;
  }
};

/* formatEvent method */
EventUtil.formatEvent = function(oEvent)
{
  if (isIE && isWin) {
    oEvent.charCode = (oEvent.type == "keypress") ? oEvent.keyCode : 0;
    oEvent.isChar = (oEvent.charCode > 0);
    oEvent.pageX = oEvent.clientX + document.body.scrollLeft;
    oEvent.pageY = oEvent.clientY + document.body.scrollTop;
    oEvent.preventDefault = function ()
    {
      this.returnValue = false;
    };
    if (oEvent.type == "mouseout") {
      oEvent.relatedTarget = oEvent.toElement;
    } else if (oEvent.type == "mouseover") {
      oEvent.relatedTarget = oEvent.fromElement;
    }
    oEvent.stopPropagation = function () {
      this.cancelBubble = true;
    };
    oEvent.target = oEvent.srcElement;
    oEvent.time = new Date().getTime();
  }
  return oEvent;
};

EventUtil.getEvent = function()
{
  if (window.event) {
    return this.formatEvent(window.event);
  } else {
    return EventUtil.getEvent.caller.arguments[0];
  }
};

