/*
	Copyright (c) 2009, Scott & White Hospital All Rights Reserved.
	TODO: Try to get all this parsed into separated libraries of like functionality.
 */

dojo.provide("sw._base.utility");

dojo.require("sw._base.Array.extension");
dojo.require("sw._base.HTMLElement.extension");
dojo.require("sw._base.String.extension");

var EventCache = function(){
	var listEvents = [];
	return {
		listEvents : listEvents,
		add : function(node, sEventName, fHandler){
			listEvents.push(arguments);
		},
		flush : function(){
			var i, item;
			for(i = listEvents.length - 1; i >= 0; i = i - 1){
				item = listEvents[i];
				if(item[0].removeEventListener){
					item[0].removeEventListener(item[1], item[2], item[3]);
				};
				if(item[1].substring(0, 2) != "on"){
					item[1] = "on" + item[1];
				};
				if(item[0].detachEvent){
					item[0].detachEvent(item[1], item[2]);
				};
				item[0][item[1]] = null;
			};
		}
	};
}();
/**
 * addEvent()
 * Assigns an event listener to an event.
 */
addEvent = function( obj, type, fn ) {
	if (obj.addEventListener != undefined){
		obj.addEventListener( type, fn, false );
		EventCache.add(obj, type, fn);
	}else if (obj.attachEvent != undefined){
		obj["e"+type+fn] = fn;
		obj[type+fn] = function() { obj["e"+type+fn]( window.event ); };
		obj.attachEvent( "on"+type, obj[type+fn] );
		EventCache.add(obj, type, fn);
	}else{
		obj["on"+type] = obj["e"+type+fn];
	}
};
/**
 * addLoadEvent()
 * Assigns an event listener to the window load by using addEvent().
 */
addLoadEvent = function(func) {
	dojo.addOnLoad(func);
//	addEvent(window,'load',func);
};

/**
 * addUnloadEvent()
 * Assigns an event listener to the window unload by using addEvent().
 */
addUnloadEvent = function(func) {
	dojo.addOnUnload(func);
//	addEvent(window,'unload',func);
};
/**
 * addEventByID()
 * A wrapper for addEvent() that prevents 
 * the creation of events on non-existent objects.
 */
addEventByID = function( objId, event, fn ){
	var obj = dojo.byId(objId);
	if(obj!=undefined)
		dojo.connect(obj, event.toLowerCase(), fn);
};
/**
 * getElementsByClass()
 * Return Elements from the DOM by className.
 */
getElementsByClass = function(searchClass, node, tag) {
	searchClass = searchClass.trim();
	if ( searchClass.indexOf(".")!=0) 		searchClass = "."+searchClass;
	if ( node==undefined || node==null )	node = document;
	if ( tag==undefined || tag==null )		tag = "";
	return dojo.query(tag+searchClass, node);
};
/**
 * Read the JavaScript cookies tutorial at:
 *   http://www.netspade.com/articles/2005/11/16/javascript-cookies/
 */

/**
 * Sets a Cookie with the given name and value.
 *
 * name       Name of the cookie
 * value      Value of the cookie
 * [expires]  Expiration date of the cookie (default: end of current session)
 * [path]     Path where the cookie is valid (default: path of calling document)
 * [domain]   Domain where the cookie is valid
 *              (default: domain of calling document)
 * [secure]   Boolean value indicating if the cookie transmission requires a
 *              secure transmission
 */
setCookie = function(name, value, expires, path, domain, secure){
    document.cookie= name + "=" + escape(value) +
        ((expires) ? "; expires=" + expires.toGMTString() : "") +
        ((path) ? "; path=" + path : "") +
        ((domain) ? "; domain=" + domain : "") +
        ((secure) ? "; secure" : "");
};

/**
 * Gets the value of the specified cookie.
 *
 * name  Name of the desired cookie.
 *
 * Returns a string containing value of specified cookie,
 *   or null if cookie does not exist.
 */
getCookie = function(name) {
    var dc = document.cookie;
    var prefix = name + "=";
    var begin = dc.indexOf("; " + prefix);
    if (begin == -1)
    {
        begin = dc.indexOf(prefix);
        if (begin != 0) return null;
    }
    else
    {
        begin += 2;
    }
    var end = document.cookie.indexOf(";", begin);
    if (end == -1)
    {
        end = dc.length;
    }
    return unescape(dc.substring(begin + prefix.length, end));
};

/**
 * Deletes the specified cookie.
 *
 * name      name of the cookie
 * [path]    path of the cookie (must be same as path used to create cookie)
 * [domain]  domain of the cookie (must be same as domain used to create cookie)
 */
deleteCookie = function( name, path, domain ) {
	if ( getCookie( name ) ) { 
		document.cookie =	name + '=' +
							( ( path ) ? ';path=' + path : '') +
							( ( domain ) ? ';domain=' + domain : '' ) +
							';expires=Thu, 01-Jan-1970 00:00:01 GMT';
	}
};
/**
 * toggle()
 * Toggles the display attribute of an object.
 */
toggle = function(obj) {
	var el = document.getElementById(obj);
	if ( el.style.display != 'none' ) {
		el.style.display = 'none';
	}
	else {
		el.style.display = '';
	}
};

/**
 * Starts a dojox.widget.Standby curtain over the specified node.
 * It returns the curtain and the hide() method must be called on it to remove the curtain.<br>
 * <code>
 * var standby = busy("possiblyADivID");<br>
 * //do stuff<br>
 * standby.hide();<br>
 * </code>
 * 
 * A good place to put the hide call is in a callback.<br>
 * 
 * <code>
 * var standby = busy("possiblyADivID");<br>
 * var get = getDefered(url);<br>
 * get.addCallback(function(data){<br>
 * standby.hide();<br>
 * })<br>
 * 
 * </code>
 * this would wait for the task then hide the curtain on completion.
 * @param {Object} nodeID the id of the html Element to but behind the curtain
 */
busy = function(nodeID){
	dojo.require("dojox.widget.Standby");
	var standby = new dojox.widget.Standby({
		target: nodeID
	});
	document.body.appendChild(standby.domNode);
	standby.startup();
	standby.show();		
	return standby;
};

/**
 * createBookmark()
 * Creates a bookmark/favorite.
 * Pass the url to bookmark and the name for the bookmark
 */
createBookmark = function(url, bmName) { 
	if (!url) {
		url = location.href;
	}
	if (!bmName) {
		bmName = document.title;
	}
	
	if (window.sidebar) { //Mozilla Firefox Bookmark
		window.sidebar.addPanel(bmName, url,"");
	} 
	else if (window.external) { //IE Favorite
		window.external.AddFavorite(url, bmName);
	}
	else {
		return true;
	}
};

/**
 * putStringInClass()
 * Inserts special character strings into objects by class.
 * Pass the character string and the target class name
 */
putStringInClass = function(pString, pClass) {
	var browserName=navigator.appName; 
	var classes = getElementsByClass(pClass);
	for (i=0; i < classes.length; i++) {
		classes[i].innerText = pString;
	}
};

/**
 * setCheckedValue()
 * Set the radio button with the given value as being checked
 * do nothing if there are no radio buttons
 * if the given value does not exist, all the radio buttons
 * are reset to unchecked
 */
setCheckedValue = function(radioObj, newValue) {
	if(!radioObj)
		return;
	var radioLength = radioObj.length;
	if(radioLength == undefined) {
		radioObj.checked = (radioObj.value == newValue.toString());
		return;
	}
	for(var i = 0; i < radioLength; i++) {
		radioObj[i].checked = false;
		if(radioObj[i].value == newValue.toString()) {
			radioObj[i].checked = true;
		}
	}
};
/**
 * pushCharacters()
 * A package function that performs several putStringInClass actions.
 * Pass the character string and the target class name
 */
pushCharacters = function() {
/** 
 * Decimal Unicode characters:
 * &nbsp; = &#160;
 * ? = &#9650;   ? = &#9658;   ? = &#9660;   rtArrow = &#9668;
 * ? = &#8593;   ? = &#8594;   ? = &#8595;   ? = &#8592;   ? = &#8616;   ? = &#8596;
 * � = &#171;    � = &#187;    ? = &#8226;
 */
//	putStringInClass(String.fromCharCode(9660,160),"downArrow");   // ?
//	putStringInClass(String.fromCharCode(9658,160),"rightArrow");  // ?
//	putStringInClass(String.fromCharCode(9668,160),"leftArrow");  // ?
};

/*************************************************************************************************/
getPrefix = function(strClass){
	for (i=0; i<=strClass.length-1; i++){
		var char = strClass.substring(i, i+1);
		if (isUpperCase(char)||isDigit(char)){
			return strClass.substring(0,i);
		}
	}
	return strClass;
};
setBodyCls = function(classStr) {
	if (classStr==null) classStr="";
		dojo.body().className = classStr;	/*document.getElementsByTagName("body")[0].className = value;/**/
};
getBodyCls = function() {
	return dojo.body().className;	/*return document.getElementsByTagName("body")[0].className;/**/
};
getBodyStyle = function(prefix) {
	var classes = getBodyCls().split(' ');
	for (i=0; i<=classes.length-1; i++){
		if(classes[i].startsWith(prefix)) return classes[i];
	}
};
loadStyleSheet = function(url){
	if(dojo.query("link[href$='"+url+"']").length == 0){
		var link = document.createElement("link");
		link.setAttribute("media","screen,projection");
		link.setAttribute("href",url);
		link.setAttribute("type","text/css");
		link.setAttribute("rel","stylesheet");
		dojo.query("head")[0].appendChild(link);
	}else{
		console.warn("Already loaded CSS: " + url);
	}
};
setDjTheme = function(djStyle) {
	var djThemes = [ "nihilo", "soria", "tundra", "none" ];
	if(djThemes.indexOf(djStyle) == -1){
		console.error("Error in sw._utility.setDjTheme: '"+djStyle+"' is not a valid Dojo Theme!");
		return;
	}
	djThemes.forEach(function(djTheme){
		dojo.removeClass(dojo.body(),djTheme);
	});
	if(djStyle!="none"){
		dojo.addClass(dojo.body(),djStyle);
		var djStyleSheet = "/web/scripts/packages/dojo/active/dijit/themes/"+djStyle+"/"+djStyle+".css";
		loadStyleSheet(djStyleSheet);
	}
};

setPageCursor = function(cursor) {
	var curClasses = [ "pointer", "wait", "crosshair", "help", "text", "none" ];
	if(curClasses.indexOf(cursor) == -1){
		console.error("Error in sw._utility.setPageCursor: '"+cursor+"' is not a valid cursor type!");
		return;
	}
	curClasses.forEach(function(curClass){
		dojo.removeClass(dojo.body(),curClass);
	});
	if(cursor!="none") dojo.addClass(dojo.body(),cursor);
};
/*
 * Remove all instances of a given class.
 * param className String Name of class to be removed.
 * param root String|DOM Node A DOMNode (or node id) to scope the search from. *Optional*
 * */
removeClass = function(className, root) {
	if(className.indexOf(".")==0) className = className.substring(1);
	if(root==null){
		dojo.query("."+className).removeClass(className);
	}else{
		dojo.query("."+className, root).removeClass(className);
	}
};
setStyleCookie = function(value){
	var prefix = getPrefix(value);
	var cookieName = prefix + swRequest.context.suite;
	setCookie(cookieName, value, null, "/");
};
setBodyStyle = function(value) {
	alterBodyStyle(value);
	setStyleCookie(value);
};
alterBodyStyle = function(classStr) {
	dojo.removeClass(dojo.body(),getBodyStyle(getPrefix(classStr)));
	dojo.addClass(dojo.body(),classStr);
};
setTheme = function(value) {
	currentTheme = value;
	var cookieName = "theme" + swRequest.context.suite;
	setCookie(cookieName, value, null, "/");
};
alterTheme = function() {
	var sTheme = document.getElementById("selectTheme").value;
	window.alert("Reload page to apply "+ sTheme +" theme.");
	setTheme(sTheme);
};
/*************************************************************************************************/
/**
 * resizeFont()
 * Resize font by toggleing the f_size value. 
 * Uses the alterBodyClass function.
 */
resizeFont = function() {
	var size = getBodyStyle("size");
	if (size=="size100"){
		setBodyStyle("size110");
	}else if(size=="size110"){
		setBodyStyle("size120");
	}else{
		setBodyStyle("size100");
	}
};
/**
 * autoExec()
 * hook function that runs when the window loads.
 */
autoExec = function() {
//  Move "noBannerMargin" classed headers out of div.iwContent.
//	moveBanner(); 
//	Content Footer Panel Events.
	addEventByID("bookMarkMe","onclick",function(){createBookmark(location.href,document.title);});
	addEventByID("printMe","onclick",function(){print();});
	addEventByID("resizeMe","onclick",resizeFont);
};
/**
 * Event section:
 * This section is for assigning functions to events.
 * Use the addLoadEvent to assign an event listener to the window load.
 * Use the addUnloadEvent to assign an event listener to the window unload.
 */
 
// A load event to push special characters not recognised by the xsl processor.
//addLoadEvent(pushCharacters);
//addLoadEvent(ctlLoad);
addLoadEvent(autoExec);

// An unload event is added to the window to run the EventCache ?flush? method.
addUnloadEvent(EventCache.flush);

/************** CONTROL PANEL ***************************************************************/
/**
 * TODO: get this working again! --with a Dojo popup.
 * */
ctlPanelShow = function()  {
	var oControlPanel= dojo.byId("ctlPanel");
	if (oControlPanel!=null) {
		oControlPanel.className= "jspTools screenOnly";
	}else{ 
		var url = "/web/AJAX/jsp/tools/ControlPanel.jsp?pageSiteSuite=" + swRequest.context.suite;
		var objId = "ctlFrame";
		//var scriptSrc = "/web/scripts/tools/ctlPanel.js";
		var callback = function() {
			console.info("ctlPanelShow callback start.");
			dojo.require("sw.tool.ControlPanel");
			console.log("ctlPanelShow callback done.");
		};
		// make ajax call.
		loadAjax(url,objId,callback);
	}
};
/** END CONTROL PANEL SECTION. **************************************************************/

swNavTo = function(uri) {
	var base = "";
	var loc = trim(uri);
	if(loc=="") return;
	if(loc.toLowerCase().indexOf("http") == 0) {
		window.open(loc);							/* spawn a new window if path is fully qualified /**/
		return;
	}
	if (loc.charAt(0) != '/' && loc.charAt(0) != "#") { 
		loc = "/"+loc;								// add leading '/' if not already there and not a jump
	}
	var b = dojo.query("base");	/* var b = document.getElementsByTagName('base');/*old code*/
	if(b && b[0] && b[0].href) {
		base = b[0].href;							// get base if available
		if(base.substring(base.length-1) == '/') {
			base = base.substring(0,base.length-1); // if base ends with '/' strip off last character	
		}
		loc = base + loc;							// add base to uri if it's available
	}
	if((loc.indexOf(".htm")+loc.indexOf(".jsp")) == -2) {
		window.open(loc);							// spawn new window if not an html or jsp file
	} else {
		location.href = loc;
	}
};

var key = new Array(); 	// Define QuickKey pages here
key['s'] = function(){ctlPanelShow();};

keyHandler = function(e) {
	if (!e) e = event;
	var ch = String.fromCharCode(e.keyCode).toLowerCase();
	if(e.altKey && typeof key[ch] == "function") {
		key[ch]();
		return false;
	}
};
document.onkeydown = keyHandler;