var Core = {};



// W3C DOM 2 Events model

if (document.addEventListener)

{

  Core.addEventListener = function(target, type, listener)

  {

    target.addEventListener(type, listener, false);

  };



  Core.removeEventListener = function(target, type, listener)

  {

    target.removeEventListener(type, listener, false);

  };



  Core.preventDefault = function(event)

  {

    event.preventDefault();

  };



  Core.stopPropagation = function(event)

  {

    event.stopPropagation();

  };

}

// Internet Explorer Events model

else if (document.attachEvent)

{

  Core.addEventListener = function(target, type, listener)

  {

    // prevent adding the same listener twice, since DOM 2 Events ignores

    // duplicates like this

    if (Core._findListener(target, type, listener) != -1) return;



    // listener2 calls listener as a method of target in one of two ways,

    // depending on what this version of IE supports, and passes it the global

    // event object as an argument

    var listener2 = function()

    {

      var event = window.event;



      if (Function.prototype.call)

      {

        listener.call(target, event);

      }

      else

      {

        target._currentListener = listener;

        target._currentListener(event)

        target._currentListener = null;

      }

    };



    // add listener2 using IE's attachEvent method

    target.attachEvent("on" + type, listener2);



    // create an object describing this listener so we can clean it up later

    var listenerRecord =

    {

      target: target,

      type: type,

      listener: listener,

      listener2: listener2

    };



    // get a reference to the window object containing target

    var targetDocument = target.document || target;

    var targetWindow = targetDocument.parentWindow;



    // create a unique ID for this listener

    var listenerId = "l" + Core._listenerCounter++;



    // store a record of this listener in the window object

    if (!targetWindow._allListeners) targetWindow._allListeners = {};

    targetWindow._allListeners[listenerId] = listenerRecord;



    // store this listener's ID in target

    if (!target._listeners) target._listeners = [];

    target._listeners[target._listeners.length] = listenerId;



    // set up Core._removeAllListeners to clean up all listeners on unload

    if (!targetWindow._unloadListenerAdded)

    {

      targetWindow._unloadListenerAdded = true;

      targetWindow.attachEvent("onunload", Core._removeAllListeners);

    }

  };



  Core.removeEventListener = function(target, type, listener)

  {

    // find out if the listener was actually added to target

    var listenerIndex = Core._findListener(target, type, listener);

    if (listenerIndex == -1) return;



    // get a reference to the window object containing target

    var targetDocument = target.document || target;

    var targetWindow = targetDocument.parentWindow;



    // obtain the record of the listener from the window object

    var listenerId = target._listeners[listenerIndex];

    var listenerRecord = targetWindow._allListeners[listenerId];



    // remove the listener, and remove its ID from target

    target.detachEvent("on" + type, listenerRecord.listener2);

    target._listeners.splice(listenerIndex, 1);



    // remove the record of the listener from the window object

    delete targetWindow._allListeners[listenerId];

  };



  Core.preventDefault = function(event)

  {

    event.returnValue = false;

  };



  Core.stopPropagation = function(event)

  {

    event.cancelBubble = true;

  };



  Core._findListener = function(target, type, listener)

  {

    // get the array of listener IDs added to target

    var listeners = target._listeners;

    if (!listeners) return -1;



    // get a reference to the window object containing target

    var targetDocument = target.document || target;

    var targetWindow = targetDocument.parentWindow;



    // searching backward (to speed up onunload processing), find the listener

    for (var i = listeners.length - 1; i >= 0; i--)

    {

      // get the listener's ID from target

      var listenerId = listeners[i];



      // get the record of the listener from the window object

      var listenerRecord = targetWindow._allListeners[listenerId];



      // compare type and listener with the retrieved record

      if (listenerRecord.type == type && listenerRecord.listener == listener)

      {

        return i;

      }

    }

    return -1;

  };



  Core._removeAllListeners = function()

  {

    var targetWindow = this;



    for (id in targetWindow._allListeners)

    {

      var listenerRecord = targetWindow._allListeners[id];

      listenerRecord.target.detachEvent(

          "on" + listenerRecord.type, listenerRecord.listener2);

      delete targetWindow._allListeners[id];

    }

  };



  Core._listenerCounter = 0;

}



Core.addClass = function(target, theClass)

{

  if (!Core.hasClass(target, theClass))

  {

    if (target.className == "")

    {

      target.className = theClass;

    }

    else

    {

      target.className += " " + theClass;

    }

  }

};



Core.getElementsByClass = function(theClass)

{

  var elementArray = [];



  if (document.all)

  {

    elementArray = document.all;

  }

  else

  {

    elementArray = document.getElementsByTagName("*");

  }



  var matchedArray = [];

  var pattern = new RegExp("(^| )" + theClass + "( |$)");



  for (var i = 0; i < elementArray.length; i++)

  {

    if (pattern.test(elementArray[i].className))

    {

      matchedArray[matchedArray.length] = elementArray[i];

    }

  }



  return matchedArray;

};



Core.hasClass = function(target, theClass)

{

  var pattern = new RegExp("(^| )" + theClass + "( |$)");



  if (pattern.test(target.className))

  {

    return true;

  }



  return false;

};



Core.removeClass = function(target, theClass)

{

  var pattern = new RegExp("(^| )" + theClass + "( |$)");



  target.className = target.className.replace(pattern, "$1");

  target.className = target.className.replace(/ $/, "");

};



Core.getComputedStyle = function(element, styleProperty)

{

  var computedStyle = null;



  if (typeof element.currentStyle != "undefined")

  {

    computedStyle = element.currentStyle;

  }

  else

  {

    computedStyle = document.defaultView.getComputedStyle(element, null);

  }



  return computedStyle[styleProperty];

};



Core.start = function(runnable)

{

  Core.addEventListener(window, "load", runnable.init);

};