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 i = 0;
      // get a reference to the window object containing target
      var targetDocument = target.document || target;
      var targetWindow = targetDocument.parentWindow;
      var listeners = target._listeners;
      if (!listeners) {
          return -1;
      }

      // searching backward (to speed up onunload processing), find the listener
      for (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.getEventTarget = function(event){
    var targetElement = null;
    if (typeof event.target != "undefined"){
        targetElement = event.target;
    }else{
        targetElement = event.srcElement;
    }
    while (targetElement.nodeType == 3 && targetElement.parentNode != null){
        targetElement = targetElement.parentNode;
    }
    return targetElement;
};

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.getScrollingPosition = function(){
  //array for X and Y scroll position
  var position = [0, 0];
  //if the window.pageYOffset property is supported
  if(typeof window.pageYOffset != 'undefined'){
    //store position values
    position = [window.pageXOffset,window.pageYOffset];
  }

  //if the documentElement.scrollTop property is supported
  //and the value is greater than zero
  if(typeof document.documentElement.scrollTop != 'undefined'
    && document.documentElement.scrollTop > 0){
    //store position values
    position = [document.documentElement.scrollLeft,document.documentElement.scrollTop];
  }

  //if the body.scrollTop property is supported
  else if(typeof document.body.scrollTop != 'undefined'){
    //store position values
    position = [document.body.scrollLeft,document.body.scrollTop];
  }
  //return the array
  return position;
};

Core.getCursorPosition = function (event) {
    if (typeof event == "undefined") {
        event = window.event;
    }

    var scrollingPosition = Core.getScrollingPosition();
    var cursorPosition = [0, 0];

    if (typeof event.pageX != "undefined" && typeof event.x != "undefined") {
        cursorPosition[0] = event.pageX;
        cursorPosition[1] = event.pageY;
    } else {
        cursorPosition[0] = event.clientX + scrollingPosition[0];
        cursorPosition[1] = event.clientY + scrollingPosition[1];
    }
    return cursorPosition;
};

Core.removeClass = function(target, theClass){
  var pattern = new RegExp("(^| )" + theClass + "( |$)");
  target.className = target.className.replace(pattern, "$1");
  target.className = target.className.replace(/ $/, "");
};

Core.addClass = function(target, theClass){
  if (!Core.hasClass(target, theClass)){
    if (target.className == ""){
      target.className = theClass;
    }else{
      target.className += " " + theClass;
    }
  }
};

Core.hasClass = function(target, theClass){
  var pattern = new RegExp("(^| )" + theClass + "( |$)");
  if (pattern.test(target.className)){
    return true;
  }
  return false;
};

Core.getElementsByClass = function (theClass) {
    var elementArray = [];
    var i = 0;
    if (document.all) {
        elementArray = document.all;
    } else {
        elementArray = document.getElementsByTagName("*");
    }
    var matchedArray = [];
    var pattern = new RegExp("(^| )" + theClass + "( |$)");
    for (i = 0; i < elementArray.length; i++) {
        if (pattern.test(elementArray[i].className)) {
            matchedArray[matchedArray.length] = elementArray[i];
        }
    }
    return matchedArray;
};

Core.start = function(runnable){
  Core.addEventListener(window, "load", runnable.init);
};

function addLoadEvent(func) {
    var oldonload = window.onload;
    if (typeof window.onload != 'function') {
        window.onload = func;
    }
    else {
        window.onload = function () {
            oldonload();
            if (typeof func == 'function') {
                func();
            }
        };
    }
}

