// JavaScript Core Library
var Core = {};

// W3C DOM 2 Events model (For non-IE browsers)
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.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 (target.className == '') {
		return false;
	}

	if (pattern.test (target.className)) {
		return true;
	}

	return false;
};

Core.addClass = function (target, theClass) {
	if (!Core.hasClass (target, theClass)) {
		if (target.className == "") {
			target.className = theClass;
		} else {
			target.className += " " + theClass;
		}
	}
};

Core.removeClass = function (target, theClass) {
	var pattern = new RegExp ("(^| )" + theClass + "( |$)");

	//Using empty string the erase
	target.className = target.className.replace (pattern, "$1");
	//removing extra spaces
	target.className = target.className.replace (/ $/, "");
};

Core.start = function (runnable) {
  	Core.addEventListener (window, "load", runnable.init);
};

Core.startDOMCL = function (runnable) {
	var initOnce = function () {
	    if (arguments.callee.done) {
		  	return;
		}
		arguments.callee.done = true;
		runnable.init ();
	};
	
	Core.addEventListener (document, "DOMContentLoaded", initOnce);
	Core.addEventListener (window, "load", initOnce);
};