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.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 = [];
 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.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();func();}}
}

// Shortcut for getElementByID()
function $(){
 var elements = [];
 for (var i = 0; i < arguments.length; i++) {
 var element = arguments[i];
 if (typeof element == "string") {
 element = document.getElementById(element);
 if (arguments.length == 1 && element) return element;
 if(element) elements.push(element);
 }
 }
 if(elements.length) return elements;
 else return false;
}
