/* <documentation about="ABOUT library.js" type="GENERAL">
	<summary>This is the Eden Javascript Library file: it contains general functions used for the entire application. 
		No page initialisation calls are made in this file; there is one exception: Lib.addEvent(window, "unload", Lib.eventCache.flush): This removes all attached events.
		Make your function calls in the specific javascript files, in the [namespace].init()
		
		The documentation of this file is in English because it is a general file used for all projects.
	</summary>
	<namespace>Lib</namespace>
</documentation> */
var Lib = {};

/* <documentation about="Lib.debug/Lib.allowAlert" type="global variables">
	<summary>These variables are used for debugging - do not change</summary>
	<namespace>Lib</namespace>
</documentation> */
Lib.debug = false; 
Lib.allowAlert = true;

/* <documentation about="Lib.safari/Lib.opera..." type="global variables">
	<summary>Browser checks</summary>
	<namespace>Lib</namespace>
</documentation> */
Lib.safari = (navigator.userAgent.toLowerCase().indexOf('safari') != - 1);
Lib.opera = window.opera ? true : false;
Lib.firefox = (navigator.userAgent.toLowerCase().indexOf('firefox') != - 1);
Lib.ie = (document.all && document.getElementById) ? true:false;
Lib.ie6 = navigator.appVersion.indexOf("MSIE 6")!=-1 ? true:false;
Lib.ie7 = navigator.appVersion.indexOf("MSIE 7")!=-1 ? true:false;

/* ========== CORE ============================================================================ */
/* <documentation about="Lib.addEvent" type="CORE FUNCTION">
	<summary>Adds events to elements of the DOM</summary>
	<namespace>Lib</namespace>
	<param type="object" descr="A reference to the node on which the event has been set (HTML element).">obj</param>
	<param type="string" descr="The name of the event ">evt</param>
	<param type="object" descr="A reference to the function which handles the event.">fn</param>
</documentation> */
Lib.addEvent = function (obj,evt,fn) {
	if (obj.addEventListener) { obj.addEventListener(evt,fn,false); }
	else if (obj.attachEvent) {
		obj.attachEvent('on'+evt,fn);
		Lib.eventCache.add(obj, evt, fn, false); 	
	}
}

/* <documentation about="Lib.removeEvent" type="CORE FUNCTION">
	<summary>Removes events to elements of the DOM</summary>
	<namespace>Lib</namespace>
	<param type="object" descr="A reference to the node on which the event has been set (HTML element).">obj</param>
	<param type="string" descr="The name of the event ">evt</param>
	<param type="object" descr="A reference to the function which handles the event.">fn</param>
</documentation> */
Lib.removeEvent = function (obj,evt,fn) {
	if (obj.removeEventListener)
		obj.removeEventListener(evt,fn,false);
	else if (obj.detachEvent)
		obj.detachEvent('on'+evt,fn);
}

Lib.eventCache = function(){
	try {
		var listEvents = [];
		
		/*  Implement array.push for browsers which don't support it natively. (used in EventCache)
		Please remove this if it's already in other code */
		if(Array.prototype.push == null){
			Array.prototype.push = function(){
				for(var i = 0; i < arguments.length; i++){
					this[this.length] = arguments[i];
		       	};
		        return this.length;
			};
		};
	     
	    return {
			listEvents : listEvents,
	     
			/* <documentation about="Lib.eventCache.add" type="CORE FUNCTION">
				<summary>Keeping track of all the attached events</summary>
				<namespace>Lib</namespace>
				<param type="object" descr="A reference to the node on which the event has been set (HTML element).">node</param>
				<param type="string" descr="The name of the event">sEventName</param>
				<param type="object" descr="A reference to the function which handles the event. ">fHandler</param>
				<param type="bool" descr="A boolean which determines whether the event is triggered in capture mode or not. Does not apply to Internet Explorer.">bCapture</param>
			</documentation> */
			add : 	function(node, sEventName, fHandler, bCapture){
						listEvents.push(arguments); 
					},
	     
		 	/* <documentation about="Lib.eventCache.flush" type="CORE FUNCTION">
				<summary>Used to remove (detach) all cached events.</summary>
			</documentation> */
			flush : 	function(){
					var i, item;
					for(i = listEvents.length - 1; i >= 0; i = i - 1){
						item = listEvents[i];
	                 	Lib.removeEvent(item[0], item[1], item[2])
	                    
						item[0][item[1]] = null;
					};
			}
	      };
	} catch (ex){ Lib.errHandler(ex); }	
}();

/* <documentation about="Lib.debugAlert" type="CORE FUNCTION">
	<summary>Displays alert with error message, if alert is allowed (not cancelled in confirm) and Lib.debug = true</summary>
	<namespace>Lib</namespace>
	<param type="string" descr="Message to display in alert">message</param>
</documentation> */
Lib.debugAlert = function (message) {
		if(Lib.allowAlert && Lib.debug) { Lib.allowAlert = confirm(message); }
	}


/* <documentation about="Lib.errHandler" type="CORE FUNCTION">
	<summary>Handles errors in javascript application</summary>
	<namespace>Lib</namespace>
	<param type="object" descr="Error object">err</param>
</documentation> */
Lib.errHandler = function (err) {
		var errorText = "";
		for (var i in err) { errorText += i + "=" + err[i] + "\n"; }
		Lib.debugAlert("An error has occured: \n\n" + errorText + "\nSee Firefox browser for correct linenumbers."); 			
		return true;	
	}	
/* ========== END CORE ====================================================================== */
	
/* ========== GENERAL FUNCTIONS ============================================================= */


/* <documentation about="Lib.getElementsByClassName" type="general function">
	<summary>Used to find HTML elements with certain classname</summary>
	<namespace>Lib</namespace>
	<param type="string" descr="Classname you are looking for">searchClass</param>
	<param type="string" descr="An optional tag name to narrow the search to specific tags e.g. 'a' for links (optional, defaults to  '*').">tagName</param>
	<param type="string" descr="An optional object container to search inside. This narrows the scope of the search (optional, defaults to document).">elem</param>
	<returns>Array of HTML elements</returns>
</documentation> */
Lib.getElementsByClassName = function (searchClass, tagName, containerElement) {
	tagName = tagName || "*";
	containerElement = containerElement || document;
	
	var allElements = containerElement.getElementsByTagName(tagName);
	if (!allElements.length &&  tagName == "*" &&  containerElement.all) allElements = containerElement.all;
	
	var elementsFound = new Array();
	var delim = searchClass.indexOf("|") != -1  ? '|' : " ";
	
	var arrClass = searchClass.split(delim);
	for (var i = 0, j = allElements.length; i < j; i++) {
		var arrObjClass = allElements[i].className.split(" ");
		if (delim == " " && arrClass.length > arrObjClass.length) { continue; }
		var c = 0;
		comparisonLoop:
			for (var k = 0, l = arrObjClass.length; k < l; k++) {
				for (var m = 0, n = arrClass.length; m < n; m++) {
					if (arrClass[m] == arrObjClass[k]) c++;
					if (( delim == "|" && c == 1) || (delim == " " && c == arrClass.length)) {
						elementsFound.push(allElements[i]);
					break comparisonLoop;
				}
			}
		}
	}
	return elementsFound;
}


/* ========== END GENERAL FUNCTIONS ========================================================= */

/* <documentation about="Add eventhandler Lib.eventCache.flush on window unload" type="FUNCTION CALL">
	<summary>Calling Lib.addEvent: Add Lib.eventCache.flush as eventhandler on window onunload: Detach all attached events (solves memory leak in ie)</summary>
</documentation> */
Lib.addEvent(window, "unload", Lib.eventCache.flush);