/*
	Copyright (c) 2009, Scott & White Hospital All Rights Reserved.
 */

dojo.provide("sw._base.ajax");
var menuList = [];
/**
 * Ajax utility that puts response text into the object who's ID is specified by the objId param.
 * Depends on Dojo script library.
 * @author kcorley
 * TODO: factor out menu functions into separate js module
 */
loadAjax  = function(loadURL, objId, callBackFunc, errBackFunc) {
	dojo.xhrGet({
		url: loadURL,
		handleAs: "text",
		handle: function(data,args){
			//if(typeof data == "error"){
			if(typeof data != "string"){
				console.error("loadAjax() error!");
				console.log(args);
				if (errBackFunc != null) {
					if(dojo.isFunction(errBackFunc)){
						errBackFunc();
					}
				} else {
					console.error("loadAjax() error!");
					console.log(args);
				}
			}else{
				data = trim(data);
				if(data.length > 0) { 
					var contentViewer = dojo.byId(objId);
					if(contentViewer) contentViewer.outerHTML = data;
					if (callBackFunc != null) {
						if(dojo.isFunction(callBackFunc)){
							callBackFunc();
						}else{
							var scriptId = objId + "Script";
							loadJavaScript(scriptSrc, scriptId);
						}
					}
				}
			}
		}
	});
}
/**
 * lazyLoadContent
 * Loads content using Dojox's ContentPane.
 * downloads content from a URL and outputs it where ever the function is called from.
 * It creates a target div tag with the given id parameter.
 * Then it downloads the content from the given URL. 
 * Unlike loadAjax() this evaluates any scripts or CSS 
 * included with the downloaded content. 
 * If used during page load, the id parameter is used to create the host div.
 * If used after page load, the id parameter should be an existing div object or id.
 * Returns a deferred object
 * Publishes "Load" and "DownloadError" events under the topic of objId param.
 */
lazyLoadContent = function(loadURL, objId, callBackFunc, errBackFunc) {
	var d = new dojo.Deferred();
	var contentPane = null;
	var loadContentPane = function(){
		dojo.require("dojox.layout.ContentPane");
		var divTempLoad = document.createElement("div");
		var divTempLoadId = objId + "TempLoadDiv";
		divTempLoad.setAttribute("id", objId + "TempLoadDiv");
		document.body.appendChild(divTempLoad);
		contentPane = new dojox.layout.ContentPane( {
	        href: loadURL
	        ,renderStyles: true
	        ,executeScripts: true
	        ,style: "display:inline;"
            ,onDownloadError: function() {
				if (errBackFunc != null){
					errBackFunc();
				}else{
					console.error(this.errorMessage);
					dojo.byId(objId).innerHTML = this.errorMessage;
				}
            	contentPane.destroyRecursive(false);
            	dojo.publish(objId,["DownloadError"]);
            }
            ,onLoad: function() {
				dojo.byId(objId).innerHTML = contentPane.domNode.innerHTML;				
				contentPane.destroyRecursive(false);
				if (callBackFunc != null) callBackFunc();
				dojo.publish(objId,["Load"]);
            }
	    }, divTempLoad );
		contentPane.startup();
	}
	if(swRequest.pageLoaded){
		loadContentPane();
	}else{
		document.writeln("<div id='"+objId+"'>Loading...</div>");
		dojo.addOnLoad(loadContentPane());
	}
	return d;
}
/********** Multi-request AJAX ***************************************************************/
/**
 * @deprecated
 */
loadAjaxOld = function(url, objId, scriptSrc) {
	var mycallback = function(responseText){
		var contentViewer = document.getElementById(objId);
		if(contentViewer) contentViewer.outerHTML = responseText.trim();
		// load optional javascript file.
		if (scriptSrc != null) {
			var scriptId = objId + "Script";
			loadJavaScript(scriptSrc, scriptId);
		}					
	}
	var ac = new AJAXCall(url, mycallback);
	ac.doGet();
}
/**
 * @param url
 * @param callback
 * @return
 * @deprecated
 */
AJAXCall = function(url, callback) {

    var req = init();
    req.onreadystatechange = processRequest;
        
    function init() {
      if (window.XMLHttpRequest) {
        return new XMLHttpRequest();
      } else if (window.ActiveXObject) {
        return new ActiveXObject("Microsoft.XMLHTTP");
      }
    }
    
    function processRequest () {
      if (req.readyState == 4) {
        if (req.status == 200) {
          if (callback) callback(req.responseText);
        }
      }
    }

    this.doGet = function() {
      req.open("GET", url, true);
      req.send(null);
    }
    
    this.doPost = function(body) {
      req.open("POST", url, true);
      req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
      req.send(body);
    }
}
/*
 ************************** LAZY MENU LOADING SCRIPTS ******************************
 */

/**
 * Used by setSWMenus to do a lazy load using AJAX.
 * Inserts a container tag into the DOM then defines 
 * an AJAX call-back function to insert the requested 
 * menu into that container tag.
 * param loadURL like "jsp/tools/menu/page.jsp"
 */
loadMenu = function(loadURL){
	if(loadURL.length==0)return;
	loadURL = formatForAjax(loadURL);
	addMenuContainer(getMenuContainerId(loadURL));
	dojo.addOnLoad(function(){
		dojo.xhrGet({
			url: loadURL,
			handleAs: "text",
			handle: function(data,args){
				if(typeof data == "error"){
					console.warn("error!");
					console.log(args);
				}else{
					data = trim(data);
					if(data.length > 0) { 
						pushMenu(data, getMenuContainerId(loadURL));
					}
				}
			}
		});
	});
}
/**
 * injMenu
 * Used by setSWMenus to load menus stored as HTML.
 * Inserts a container tag into the DOM then inserts the
 * data parameter into that container tag.
 * 
 * param data String with escaped HTML fragment
 */
injMenu = function(data){
	if(data.length > 0) {
		var el = document.createElement("div");
		el.innerHTML = data;		// convert data to element to look for ID attribute
		var containerId = getMenuContainerId(el);
		addMenuContainer(containerId); //extra
		pushMenu(data, containerId);
	}
}
/**
 * reloadMenu
 * Constructs parameters and passes them on to the Ajax menu loader.
 * Will not work if called before the page has loaded. (see: function loadMenu)
 * param loadURL like "jsp/tools/menu/page.jsp"
 * 
 */
reloadMenu = function(loadURL){
	if(loadURL.length==0)return;
	loadURL = formatForAjax(loadURL);
	dojo.xhrGet({
		url: loadURL,
		handleAs: "text",
		handle: function(data,args){
			if(typeof data == "error"){
				console.warn("error!");
				console.log(args);
			}else{
				data = trim(data);
				if(data.length > 0) {
					pushMenu(data, getMenuContainerId(loadURL));
				}
			}
		}
	});
}
/**
 * pushMenu
 * Used by other menu functions to insert data into 
 * existing container tags.
 * 
 * param data String with HTML menu fragment
 * param containerId String id of container to put data into
 */
pushMenu = function(data, containerId) {
	if(data.length > 0) {
		var contentWrapper = document.getElementById(containerId);
		if (contentWrapper) { // Assumes the outter div already exists and replaces all of it's contents.
			data = startPane + data + endPane;
			contentWrapper.innerHTML = data;
			evalScripts(contentWrapper);
		} else {
			var errMsg = "Menu push failure. Location unspecified and existing object: '" + containerId + "' not found. ";
			window.alert(errMsg);
		}
	}
}
/**
* Adds a container span with the given Id and class if 
* a DOM object with the same ID doesn't already exist.
*/
addContainer = function(containerId, containerClass){
	if(containerId==null) return;
	if(containerClass==null) containerClass="container";
	var oContainer = document.getElementById(containerId);
	if(!oContainer){
		document.write("<span class='" + containerClass + "' id='" + containerId + "' ></span>");
	}
}
/**
* Adds a menuContainer classed span with the given containerId if 
* a DOM object with the same ID doesn't already exist.
*/
addMenuContainer = function(containerId){
	addContainer(containerId,"menuContainer screenOnly");
}
/**
 * Returns an ID string. 
 * Extrapolates an id from 
 * -either-
 * the file name in the url parameter 
 * -or- 
 * the first id attribute found in a DOM element
 * 
 * param obj url String or DOM Element
 */
getId = function(obj){
	if(obj.tagName == undefined){ 

			// get ID from URL
			obj = obj.split("?")[0];												// filter everything after the "?"
			obj = obj.split("/").pop();												// filter everything before the last "/"
			var ext = obj.split(".").pop();											// filter everything before the last "." to get file extension
			ext = ext.substring(0,1).toUpperCase()+ext.substring(1).toLowerCase(); 	// capitalize first char of the extension.
			obj = obj.split(".")[0];												// filter everything after the "." to get the file name
			obj += ext;																// add extension back to file name without the period
			return obj;
		
	} else {
		// get ID from DOM element
		var retVal = "notFound";
		var ch = obj.firstChild;
		var notFinished = true;
		do {
		    if (ch.nodeType == 1){
		    	retVal = ch.id;
		    	if(retVal!=undefined){ 
		    		notFinished = false;
		    	}
		    }
		    if(ch.nextSibling!=null){
		    	ch = ch.nextSibling;
		    } else {
		    	notFinished = false;   	
		    }
		} while(notFinished);
		return retVal;
	}
}
/**
 * Returns a script ID string. 
 * Extrapolates an id from the getId() plus the string "Script"
 * param url String
 */
getScriptId = function(url){
	return getId(url)+"Script";
}
/**
 * Returns a menu ID string. 
 * Extrapolates an id from the getId() plus the string "Menu"
 * param url String
 */
getMenuId = function(url){
	return getId(url)+"Menu";
}
/**
 * Returns a menu container ID string. 
 * Extrapolates an id from the getMenuId() plus the string "Container"
 * param url String. If the url has a screenID parameter then the
 * normal menucontainer id algorithm is skipped and the screenID is returned.
 * 
 * /web/AJAX/iwcontent/private/InASnap/html/intra-InASnapIntro.html
 * /web/AJAX/jsp/tools/menu/calendar.jsp?requestDate=3/1/2009&eventCat=All Events&swSite=InSite&swSiteSuite=InSite&swSiteScope=Intranet&swTheme=2009-02
 */
getMenuContainerId = function(url){
	if(url.indexOf("screenID")!=-1){
		//action/ACD.areas.GetTarget?screenID=personalizedMenu
		var s = url.split("screenID=")[1];//obj.substring(obj.indexOf("screenID")+9);
		s = s.split("&")[0];
		return s;
	}
	return getMenuId(url)+"Container";
}
formatForAjax = function(url){
	var urlRet = "/web/AJAX/";
	if (url.indexOf(urlRet) == -1){
		urlRet += url;
	} else {
		urlRet = url;
	}
	urlRet = addContextParam(urlRet);
	return urlRet;
}
addContextParam = function(url){
	var contextParam = "swContext=";
	/*contextParam += JSON.stringify(context); /* JSON.stringify(value, replacer, space) */
	dojo.require("dojo._base.json");
	contextParam += dojo.toJson(swRequest.context, true); /* replaced above with dojo version */
	var urlAry = url.split("?");
	var urlRet = urlAry[0];
	urlRet += "?";
	if(urlAry.length > 1){
		urlRet += urlAry[1];
		contextParam = "&" + contextParam;
	}
	urlRet += contextParam;
	return urlRet;
}
/**
 * Script for dynamically loading menu sections.
/**************************************************************************/

/**
 * adds menu to list of menus.
 * param menu String that is either an html fragment or a url to a menu component.
 * param weight int defaults to 0 used to effect order of menu items greater weights come before lesser weights.
 */
addSWMenu = function(menu, weight){
	var exists = false;
	if(weight==null) weight = 0;
	var swMenu = [weight, menu];
	// Check if menu already exists in array.
	menuList.forEach( function(swMenu){if (swMenu[1] == menu) exists = true;} );
	if (!exists) {
		menuList.push(swMenu);
	}
}

/******************************************************************************
 * The sort() method, by default, will sort an Array alphabetically. If you 
 * would like to create your own sorting criteria, supply a function for the 
 * sort method to call. Sort will pass your function (a,b). If a is less than b 
 * then return -1, if a is equal to b then return 0, if a is greater than b 
 * then return 1. Sort will take it from there. 
 */
setSWMenus = function(){
	menuList.sort(function(a,b){return a[0]-b[0];}).reverse();	// Sort menuList by weight numerically in desc order.
	menuList.forEach(function(swMenu){var m=trim(unescape(swMenu[1]));if(m.indexOf("<")==0){injMenu(m);}else{loadMenu(m);}});		// Load the url of each menuList item.
	loadMenu=[];
}
var setSWMenusFat = function setSWMenusFat(){
	// Function to compare first array element numerically.
	var compare = function (a,b) { 
		return a[0]-b[0];
	};
	// sort by weight which is the first element in each swMenu.
	menuList.sort(compare);									// Sort the weight numerically.	
	menuList.reverse();										// Sort decending.
	// Function to run loadMenu on the second array element in the swMenu parameter.
	var loadSWMenu = function(swMenu) {
		var m = swMenu[1];
		m = unescape(m);
		m = trim(m);
		if(m.indexOf("<")==0){
			injMenu(m);
		}else{
			loadMenu(m);
		}
	}
	menuList.forEach(loadSWMenu);
	loadMenu=[];
}
/**
 * evalScripts: 
 * Used to run scripts that are embeded inside content that 
 * was appended after the page was loaded.
 * Attempts to import or evaluate and run all script blocks 
 * contained in the DOM object parameter.
 * 
 * @param obj DOM element containing script tags.
 * @return
 */
var evalScripts = function(obj) {
	var scripts = obj.getElementsByTagName("script");
	if(scripts.length > 0){
		for (var i=0; i < scripts.length; i++) {
			var src = scripts[i].src;
	    	if(src==""){
	    		eval(scripts[i].innerHTML); // evaluate script body
	    	}else{
	    		loadJavaScript(src, getScriptId(src)); // load script tag into page header.
	    	}
		}
	}
}