
// This is true if we are IE.
ie = (navigator.appName.indexOf("Microsoft Internet Explorer") != -1 ) ? true : false;

// This is true if we are CHROME.
chrome = (navigator.userAgent.indexOf("Chrome") != -1 ) ? true : false;

firefox = (navigator.userAgent.indexOf("Firefox") != -1 ) ? true : false;


// This is true if we are SAFARI.

/**
 * Add array utility function contains which
 * checks to see if an array contains the given
 * obj.
 */
if (!Array.prototype.contains) { 
Array.prototype.contains = function(obj) {   
	var i = this.length;   
	while (i--) {     
		if (this[i] === obj) {       
			return true;     
		}  
	}   
	return false;
} // Array.prototype.contains
} // if( !Array.prototype.contains )

if( !document.getElementsByClass ) {
	//console.log("defining getElementsByClass")
	document.getElementsByClass = function(classname, node) {
		if(!node) node = document.getElementsByTagName("body")[0];
		var a = [];
		var re = new RegExp('\\b' + classname + '\\b');
		var els = node.getElementsByTagName("*");
		for(var i=0,j=els.length; i<j; i++)
			if(re.test(els[i].className)) a.push(els[i]);
		return a;
	}; // getElementsByClassName
}


/**
 * Add array utility to return the index of the
 * given element in the array or -1 if not found.
 */
if (!Array.prototype.indexOf) { 
	Array.prototype.indexOf = function(searchElement /* , fromIndex */) { 
		if (this === void 0 || this === null) { 
			throw new TypeError(); 
		}
		var t = Object(this); 
		var len = t.length >>> 0; 
		if (len === 0) { 
			return -1; 
		}
		var n = 0; 
		if (arguments.length > 0)  { 
			n = Number(arguments[1]); 
			if (n !== n) { 
				n = 0; 
			} else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0))  {
				n = (n > 0 || -1) * Math.floor(Math.abs(n)); 
			}
		} 
		// maybe error here.
		if (n >= len) { 
			return -1; 
		}
		var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0); 
		for (; k < len; k++)  { 
			if (k in t && t[k] === searchElement) { 
				return k; 
			}
		} 
		return -1; 
	}; 
} // if( !Array.prototype.indexOf )

/**
 * Utility function for checking to see if
 * something is defined and not null.
 */
def = function( obj ) {
        var ret = true;
        if( obj === null || obj === undefined ) {
                ret = false;
        }
        return ret;
}; // def

/**
 * Return value or 0 if undefined or null.
 */
zero = function( val ) {
        var ret = 0;
        if( def( val ) && !isNaN(val) && val != "" ) {
                ret = val;
        }
        return ret;
}; // zero

/**
 * Get the body from the document.
 */
getBody = function() {
	var b = document.getElementsByTagName("body");
	return b[0];
};


// Initialize global variables for logging.
debug = false;
logDiv = null;
bd = null;

getEventTarget = function( e ) {
			var targ;
			if (!e) var e = window.event;
			if (e.target) targ = e.target;
			else if (e.srcElement) targ = e.srcElement;
			if (targ.nodeType == 3) // defeat Safari bug
				targ = targ.parentNode;
			return targ;
};


/**
 * Logs to a div.
 */
log = function( str ) {
        if( false ) {//window.debug ) {
                if( !def(logDiv) && def(bd)) {
                        var divStyle = "position: relative; "+
                        "width: 100%; height: 200px; overflow: auto;"+
                        "background-color: yellow;";
                        logDiv = document.createElement("div");
                        logDiv.setAttribute("id", "kali-log");
                        //Kali.logDiv.setAttribute("class", "cent");
                        logDiv.setAttribute("style", divStyle );
                        bd.appendChild( logDiv );
                } 
                if( def( logDiv ) ) {
                        logDiv.innerHTML += str + "<br/>\n";
                }
        }
}; // log


/**
 * Returns an array where [0] = x position and [1] = y position.
 *
 */
getPosition = function ( oobj ) {
      var obj = oobj;
      var topValue= 0,leftValue= 0;
      while(obj){
        leftValue+= obj.offsetLeft;
        topValue+= obj.offsetTop;
        obj= obj.offsetParent;
      }
      // COL.log("getPossition "+oobj.id+" = "+leftValue+", "+topValue);
      return new Array( leftValue, topValue );

};


/**
 * Utillity function to dump an object.
 */
dump = 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 += dump(value,level+1);
                        } else {
                                dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
                        }
                }
        } else { // Stings/Chars/Numbers etc.
                dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
        }
        return dumped_text;
}; // dump(


/**
 * Searches for a child with class 'cl1' in 'el2'.
 * returns an array of found elements.
 */
childClass = function( el2, cl1 ) {

        var retVal = false;
        if( def(el2) && def(el2.children) && def(cl1) ) {
        //console.log("el.id:"+el2.id+" el.class:"+el2.className);
        var children = el2.children;
        for( var i = 0; i < children.length; i++ ) {
                var child = children[i];
                var cl = child.getAttribute("class");
                var type = child.tagName;
                //console.log("type:"+type);
                if(  def(cl) ) {
                        //console.log("def class");
                        if( cl.indexOf( cl1 ) != -1 ) {
                                //console.log("found:"+cl1);
                                if( retVal ) {
                                        if( def(retVal.length) ) {
                                                //console.log("append");
                                                retVal[ retVal.length ] = child;
                                        } else {
                                                //console.log("set");
                                                retVal = [ retVal, child ];
                                        }
                                } else {
                                        //console.log("set 1");
                                        retVal = child;
                                }
                        } else {
                                //console.log("didn't find:"+cl);
                        }
                } else {
                        //console.log("not defined class");
                }
        }
        }
        //log("return:"+retVal);
        return retVal;
};




/**
 * Searches 'el2' for an element with the type 'name'.
 * returns an array of found elements.
 */
childElement = function( el2, name ) {
        var retVal = false;
        var children = el2.children;
        log("children.length:"+children.length);
        for( var i = 0; i < children.length; i++ ) {
                var child = children[i];
                if( child.nodeName == name ) {
                        log("found22:"+child.nodeName);
                        if( retVal ) {
                                if( def(retVal.length) ) {
                                        retVal[ retVal.length ] = child;
                                } else {
                                        retVal = [ retVal, child ];
                                }
                        } else {
                                retVal = child;
                        }
                } else {
                        log("didn't find22:"+child.nodeName);
                }
        }
        return retVal;
};




/**
 * Parses a URI into an array of the parts.
 *
 * @param {String} str the uri to parse. Eg. protocol://host:port/directory/file?query#anchor
 */
parseUri = function (str) {
        var     o   = parseUri.options,
                m   = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
                uri = {},
                i   = 14;

        while (i--) uri[o.key[i]] = m[i] || "";

        uri[o.q.name] = {};
        uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
                if ($1) uri[o.q.name][$1] = $2;
        });

        return uri;
};


/**
 * A helper JSON Object for parsing the URI.
 * Contains the REGULAR EXPRESSIONS for parsing a uri and their name mappings.
 *
 */
parseUri.options = {
        strictMode: false,
        key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
        q:   {
                name:   "queryKey",
                parser: /(?:^|&)([^&=]*)=?([^&]*)/g
        },
        parser: {
                strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
                loose:  /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
        }
};


/**
 * Gets the width of the page.
 */
getWidth = function() {
        var ret = 0;
        if( def(window.innerWidth) ) {
                ret = window.innerWidth;
        } else if( def(document.body.clientWidth) ) {
                ret = document.body.clientWidth;
        }
        return stripPx(ret);
}; // getWidth


/**
 * Get the total document height.
 * BUG: add some to this because it isn't correct.
 */
getHeight = function() {
    var D = document;
    return Math.max(
        zero(D.body.scrollHeight), zero(D.documentElement.scrollHeight),
        zero(D.body.offsetHeight), zero(D.documentElement.offsetHeight),
        zero(D.body.clientHeight), zero(D.documentElement.clientHeight),
        zero(window.innerHeight), zero( window.scrollMaxY ), zero(document.scrollHeight ),
        zero( window.scrollHeight )
    );
};



/**
 * Makes the appropriate XMLHttpRequest to the given url
 * and callss the given callback function for further
 * processing of the response.
 * @param {String} url the url to request.
 * @param {String} params the form variables to pass.
 * @param {Object} scpe the scope of the callback. default is window (i think).
 * @param {Function} callback the function object to call and pass the responst to.
 */
makeRequest = function ( url, params, scpe, callback ) {
        log("url: "+url+" params: "+params);
        // Set up XMLHttpRequest Object.
        if (typeof XMLHttpRequest != "undefined") {
                req = new XMLHttpRequest();
        } else if (window.ActiveXObject) {
                req = new ActiveXObject("Microsoft.XMLHTTP");
        }
        // Depending on whether params is set, do POST or GET.
        if( params !== null ) {
                log("post");
                req.open("POST", url, true);
        } else {
                log("get");
                req.open("GET", url, true );
        }
        // Intermediary handler, called after the response is recieved.
        // Called various times with different states.
        var ourHandler = function( ) {
                try { // Catch any errors to prevent any messages being desplayed to end-user.
                        if (req.readyState == 4 && req.status == 200 ) {
                                log("request received");
                                obj = req.responseText;

                                //log( obj );
                                // The response was successful, call the user
                                // supplied callback.
                                callback.apply( scpe, new Array( obj ) );
                        }
                        if( req.status != 200 ) {
                                // The response was unsuccessful, call the user
                                // Supplied callback but indicate that there
                                // Was a problem.
                                obj = "Server error: "+req.responseText;
                                callback.apply( scpe, new Array( obj ) );
                        }
                } catch ( e ) {
                        //alert( e );
                }
        };
        // Set the intermediary handler.
        req.onreadystatechange = ourHandler;
        if( params !== null ) {
                // If post, set a header to indicate form-urlencoded.
                req.setRequestHeader("Content-Type",
                   "application/x-www-form-urlencoded");
                // If post, put params.
                req.send(params);
        } else {
                // Get doesn't take parmas, they are passed in url.
                req.send( null );
        }
};// function makeRequest







/**
 * Strips 'px' from a string and returns the integer.
 */
stripPx = function( str ) {
        var ret = str;
        if( def(str) ) {
                if( def(str.indexOf) ) {
                        var pos = str.indexOf("px");
                        if( pos != -1 ) {
                                ret = parseInt(str.substring( 0, pos ));
                        } else {
                                ret = parseInt(str);
                        }
                }
        }
        return ret;
};




/**
 * Get the top of the scroll location.
 */
scrollTop = function() {
        var top = 0;
        if( ie && def(document.documentElement.scrollTop) ) {
                top = document.documentElement.scrollTop;
        } else if( ie && def(document.body.scrollTop) ) {
                top = document.body.scrollTop;
        } else {
                top = window.pageYOffset;
        }
        return top;
};


/**
 * Positions the given div to x and y.
 *
 */
posDiv = function( div, x, y ) {
        if( def( div ) ) {
                div.style.left = x+"px";
                div.style.top = y+"px";
        } else {
                alert("div undefined");
        }
};



// ########### functions having to do with a window resize.
repos = [];
reposAll = function() {
	for( var i = 0; i < repos.length; i++ ) {
		repos[i].apply( window, new Array() );
	}
};
addRepos = function( func ) {
        repos[ repos.length ] = func;
};
window.onresize = reposAll;
// ###############################





// ####### functions having to do with the window loading.
loaded = false;
load = [];
loadAll = function() {
	log("loadAll");
        for( var i = 0; i < load.length; i++ ) {
			log("load["+i+"]");
			if( def( load[i]) ) {
                load[i].apply( window, new Array() );
            }
        }
	loaded = true;
};
addLoad = function( func ) {
	log("addLoad("+func+")");
	if( !loaded ) {
		load[ load.length ] = func;
	} else {
		log("call load function becuz already loaded");
		func.apply( window, new Array() );
	}
};
initUtils = function() {
	bd = getBody();
};
addLoad( initUtils );
window.onload = loadAll;


// Load iScroll when DOM content is ready.
//document.addEventListener('DOMContentLoaded', loadAll, false);


// ###########################




// ###### functions having to do with the window scrolling.
window.scrollz = [];
scrollAll = function() {
        for( var i = 0; i < window.scrollz.length; i++ ) {
                window.scrollz[i].apply( window, new Array() );
        }
};
addScroll = function( func ) {
	window.scrollz[ window.scrollz.length ] = func;
};
window.onscroll = scrollAll;
// ##############################

// #### functions looking for hash change
window.ourHash = [];
hashAll = function() {
        for( var i = 0; i < ourHash.length; i++ ) {
                ourHash[i].apply( window, new Array() );
        }
};
addHash = function( func ) {
        ourHash[ourHash.length] = func;
};
if( 'onhashchange' in window ) {
        window.onhashchange = hashAll;
}

// capture key down.
keypress = [];
function keypressAll( e ) {
	for( var i = 0; i < keypress.length; i++ ) {
		keypress[i].apply( window, new Array( e ) );
	}
}
function addKeypress( func ) {
	keypress[keypress.length] = func;
}
window.onkeypress = keypressAll;

// capture key up.
keyup = [];
function keyupAll( e ) {
	for( var i = 0; i < keyup.length; i++ ) {
		keyup[i].apply( window, new Array( e ) );
	}
}
function addKeyup( func ) {
	keyup[keyup.length] = func;
}
window.onkeyup = keyupAll;


//capture orientation change.
orientation = [];
function orientationAll( e ) {
	for( var i = 0; i < orientation.length; i++ ) {
		orientation[i].apply( window, new Array( e ) );
	}
}
function addOrientation( func ) {
	orientation[orientation.length] = func;
}
window.onorientationchange = keyupAll;




