// addEvent() taken from
// http://www.dustindiaz.com/rock-solid-addevent/
function addEvent( obj, type, fn ) {
  //alert('adding ' + type + ' to ' + obj.id );
  if (obj.addEventListener) {
    obj.addEventListener( type, fn, false );
    EventCache.add(obj, type, fn);
  }
  else if (obj.attachEvent) {
    obj["e"+type+fn] = fn;
    obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
    obj.attachEvent( "on"+type, obj[type+fn] );
    EventCache.add(obj, type, fn);
  }
  else {
    obj["on"+type] = obj["e"+type+fn];
  }
}

function rmEvent( obj, type, fn ) {
  if(obj.removeEventListener) {
    obj.removeEventListener(type, fn, null);
  }
  if(obj.detachEvent) {
    obj.detachEvent(type, fn);
  }
}

var EventCache = function() {
  var listEvents = [];
  return {
    listEvents : listEvents, 
    add : function(node, sEventName, fHandler) {
            listEvents.push(arguments);
          },
    flush : function() {
              var i, item;
              for(i = listEvents.length - 1; i >= 0; i = i - 1) {
                item = listEvents[i];
                if(item[0].removeEventListener) {
                  item[0].removeEventListener(item[1], item[2], item[3]);
                };
                if(item[1].substring(0, 2) != "on") {
                  item[1] = "on" + item[1];
                };
                if(item[0].detachEvent) {
                  item[0].detachEvent(item[1], item[2]);
                };
                item[0][item[1]] = null;
              };
	    }
    };
  }();
addEvent(window,'unload',EventCache.flush);

// return the object that was just targeted by the event
function getTarget(evt)
{
  if (evt && evt.target)   //Moz
    return evt.target;
  else if(window.event)    //IE
    return window.event.srcElement;
  else                     //no event
    return;
}

// return the first parent object with the id prefix
function findObjParentById(el, id)
{
  if(el.id && el.id.indexOf(id) == 0) {
    return el;
  } else {
    return findObjParentById(el.parentNode, id);
  }
}

// get the kode of the key that was just pressed
// This is from http://www.howtocreate.co.uk/tutorials/index.php?tut=0&part=17  
function getKeyCode(e)
{
  if( !e ) {    //if the browser did not pass the event information to the    //function, we will have to obtain it from the event register    if( window.event ) {        //DOM      e = window.event;    } else {      //TOTAL FAILURE, WE HAVE NO WAY OF REFERENCING THE EVENT      return;    }  }  if( typeof( e.which ) == 'number' ) {     //NS 4, NS 6+, Mozilla 0.9+, Opera     e = e.which;  } else if( typeof( e.keyCode ) == 'number'  ) {     //IE, NS 6+, Mozilla 0.9+     e = e.keyCode;  } else if( typeof( e.charCode ) == 'number'  ) {     //also NS 6+, Mozilla 0.9+     e = e.charCode;  } else {     //TOTAL FAILURE, WE HAVE NO WAY OF OBTAINING THE KEY CODE     return;  }  //window.alert('The key pressed has keycode ' + e + ' and is key ' + String.fromCharCode( e ) );
  return e;
}

// this cruft is an example I grabbed where the author distinguishes between single and double clicks
// might be useful someday

//var dcTime=250;    // doubleclick time//var dcDelay=100;   // no clicks after doubleclick//var dcAt=0;        // time of doubleclick//var savEvent=null; // save Event for handling doClick().//var savEvtTime=0;  // save time of click event.//var savTO=null;    // handle of click setTimeOut// //function showMe(form, txt) {//  document.forms[form].elements[0].value += txt;//}// //function hadDoubleClick() {//  var d = new Date();//  var now = d.getTime();//  showMe(1, "Checking DC (" + now + " - " + dcAt);//  if ((now - dcAt) < dcDelay) {//    showMe(1, "*hadDC*");//    return true;//  }//  showMe(1, " OK ");//  return false;//}// //function handleWisely(which) {//  showMe(1, which + " fired...");//  switch (which) {//    case "click": //      // If we've just had a doubleclick then ignore it//      if (hadDoubleClick()) return false;//       //      // Otherwise set timer to act.  It may be preempted by a doubleclick.//      savEvent = which;//      d = new Date();//      savEvtTime = d.getTime();//      savTO = setTimeout("doClick(savEvent)", dcTime);//      break;//    case "dblclick"://      doDoubleClick(which);//      break;//    default://  }//}// //function doClick(which) {//  // preempt if DC occurred after original click.//  if (savEvtTime - dcAt <= 0) {//    showMe(1, "ignore Click");//    return false;//  }//  showMe(1, "Handle Click.  ");//}// //function doDoubleClick(which) {//  var d = new Date();//  dcAt = d.getTime();//  if (savTO != null) {//    clearTimeout( savTO );          // Clear pending Click  //    savTO = null;//  }//  showMe(1, "Handle DoubleClick at " + dcAt);//}