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 using the same listener twice, since DOM 2
// events ignore 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() {
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 = "1" + 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 = targetDocument || 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 it's 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 (typeof document.all != "undefined") {
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 = taregt.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);
};
