/**
 * Helper functions that make your life easier
 * @namespace INTRIGO
 */

if (INTRIGO == undefined)
	var INTRIGO = {};
/**
 * Dumps and displays the content of a variable. Great for debugging
 * @param {Object} arr
 */
function dump(arr) {
	var div = document.createElement('div');
	div.innerHTML = 'Click me to close<pre>' + INTRIGO.dumpHelper(arr) + '</pre>';
	div.style.position = 'absolute';
	div.style.zIndex = '10000';
	div.style.top = 10;
	div.style.left = 10;
	div.style.padding = '5px';
	div.style.border = '1px dashed #2F6FAB';
	div.style.backgroundColor = '#F9F9F9';
	div.style.color = 'black';
	div.onclick = function(){
		this.parentNode.removeChild(this);
	}
	document.body.appendChild(div);
}
INTRIGO.dumpHelper = function(arr,level) {
	var dumped_text = "";
	if(!level) level = 0;
	
	//The padding given at the beginning of the line.
	var level_padding = "";
	for(var j=0;j<level+1;j++) level_padding += "    ";
	
	if(typeof(arr) == 'object') { //Array/Hashes/Objects
	 for(var item in arr) {
	  var value = arr[item];
	 
	  if(typeof(value) == 'object') { //If it is an array,
	   dumped_text += level_padding + "'" + item + "' ...\n";
	   dumped_text += INTRIGO.dumpHelper(value,level+1);
	  } else {
	   dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
	  }
	 }
	} else { //Stings/Chars/Numbers etc.
	 dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
	}
	return dumped_text;
}

/**
 * UID generator: it'll keep incrementing each time it's called
 * @return {Integer}: id++
 */
INTRIGO.uid = (function(){
	var id = 0;
	return function(){
		return id++;
	};
})();

/**
 * checks to see if param is a function
 * @param {Function} funcName
 * @return {Boolean}: true if function false is not
 */
INTRIGO.isFunction = function(funcName) {
	if (typeof funcName == 'function')
		return true;
	else return false;
}

/**
 * returns ASCII key code based on a key event
 * @param {Event} event
 * @return {Integer}: Key code
 */
INTRIGO.getKeyCode = function(event) {
	var browser = navigator.appName;
	if (browser == "Microsoft Internet Explorer")
	 	return window.event.keyCode;
	else return event.keyCode;
}

/**
 * stops the propagation of an event: useful for clicking on a link who's parent div has an "onclick" event
 * @param {Event} event
 */
INTRIGO.noBubble = function(event) {
	if (!event)
		var event = window.event;
	event.cancelBubble = true;
	if (event.stopPropagation)
		event.stopPropagation();
}

/**
 * goes up the DOM tree to find the "element" (2nd param)
 * Stops after the 7th parent and executes the "onComplete" function if the element wasn't found
 * @param {Event} event: getting the target element (starting point) based on an event trigger
 * @param {Object} element: element we're looking for
 * @param {Function} onComplete: if the element is not found this function is executed
 * @return {Boolean}: true if found, false if not
 */
INTRIGO.bubble = function(event, element, onComplete) {
	var targ = INTRIGO.getTarget(event);
	var relativeTarget = targ;
	var count = 0;
	
	if (targ == element)
		return true;

	while (relativeTarget.nodeName != 'BODY') {
		relativeTarget = relativeTarget.parentNode;
		if (relativeTarget == element)
			return true;
		if (count > 7)
			break;
		count++;
	}
	if (typeof(onComplete) == 'function')
		onComplete();
	else return false;
}

/**
 * gets the element the event triggered
 * @param {Event} event
 * @return {Object}: the element found based on the event
 */
INTRIGO.getTarget = function(event) {
	if (!event)
		event = window.event;
	if (event.target)
		return event.target;
	else if (event.srcElement)
		return event.srcElement;
	if (event.nodeType == 3) // defeat Safari bug
		return event.parentNode;
}

/**
 * searchs for the "searchValue" in the "haystack"
 * @param {String} searchValue
 * @param {String} haystack
 * @return {Boolean}: true if found, false if not
 */
INTRIGO.search = function(searchValue, haystack) {
	if (searchValue == null || searchValue == "")
		return false;

	var str = String(searchValue).toLowerCase(); //cast to string incase javascript has 'cleverly' cast our name to a number
	var haystack = String(haystack).toLowerCase();
	var searchValue_array = str.split(" ");

	for (var i = 0; i < searchValue_array.length; i++)
		if (haystack.indexOf(searchValue_array[i]) == -1)
			return false; //Our work is done here.
	return true; //Only if it contained all of the filter words.
}

/**
 * adds "className" to "elt"
 * @param {Object} elt
 * @param {String} className
 */
INTRIGO.addClassName = function(elt, className) {
	if (typeof elt == 'string')
		var elt = document.getElementById(elt);
	if (this.hasClassName(elt, className))
		return;
	else elt.className += ' ' + className;
}

/**
 * removes "className" to "elt"
 * @param {Object} elt
 * @param {String} className
 */
INTRIGO.removeClassName = function (elt, className) {
	if (typeof elt == 'string')
		var elt = document.getElementById(elt);
	if (this.hasClassName(elt, className)) {
		var classes = elt.className.split(' ');
		var tmp = '';
		for (var i = 0; i < classes.length; i++) {
			if (classes[i] != className) {
				tmp += classes[i];
				if (i + 1 < classes.length)
					tmp += ' ';
			}
		}
		elt.className = tmp;
	}
},

/**
 * checks to see if "elt" has "className"
 * @param {Object} elt
 * @param {String} className
 */
INTRIGO.hasClassName = function(elt, className){
	if (elt.className.indexOf(className) > -1)
		return true;
	else return false;
}

/**
 * adds attributes to an element
 * @param {Object} elt: elt to add the attributes to
 * @param {Hash} attribs: key value pair where key is the attribute name and the value is the attribute value
 */
INTRIGO.setAttributes = function(elt, attribs) {
	if (typeof(attribs) == 'object') {
		for(var i in attribs) {
			if (i == 'class') {
				elt.setAttribute('className', attribs[i]);
			}
			elt.setAttribute(i, attribs[i]);
		}
	}
}