/**
 * Ajax.js
 *
 * Collection of Scripts to allow in page communication from browser to (struts) server
 * ie can reload part instead of full page
 *
 * How to use
 * ==========
 * 1) Call retrieveURL from the relevant event on the HTML page (e.g. onclick)
 * 2) Pass the url to contact (e.g. Struts Action) and the name of the HTML form to post
 * 3) When the server responds ...
 *		 - the script loops through the response , looking for <span id="name">newContent</span>
 * 		 - each <span> tag in the *existing* document will be replaced with newContent
 *
 * NOTE: <span id="name"> is case sensitive. Name *must* follow the first quote mark and end in a quote
 *		 Everything after the first '>' mark until </span> is considered content.
 *		 Empty Sections should be in the format <span id="name"></span>
 */

//global variables
  var req;
  var which;
  var displayId;	
  var submitMethod;
  var userforms = [];
  var count = 0;
  var index = 0;
  var getuserform;
  var scripts = [];
  var global_script_pool = [];

  function userForm(url,formname,divid,callbackfun)
  {
  	this.url=url;
  	this.formname=formname;
  	this.divid=divid;
  	this.callbackfun=callbackfun
  }
  //submit for post
  function doPost(url,nameOfForm,displayIds)
  {
  	submitMethod="POST";
  	if(userforms[0])
  	{
  		userforms[count] = new userForm(url,nameOfForm,displayIds,getCallBackFun(url));
  		count = count + 1;
  	}
  	else
  	{
  		userforms[count] = new userForm(url,nameOfForm,displayIds,getCallBackFun(url));
  		getuserform = userforms[count];
  		count = count + 1;
  		doRequestUsingPost(url,nameOfForm,displayIds);
  	}
  }
  //submit for get
  function doGet(url,displayIds)
  {
  	submitMethod="GET";
  	if(userforms[0])
  	{
  		userforms[count] = new userForm(url,nameOfForm,displayIds,getCallBackFun(url));
  		count = count + 1;
  	}
  	else
  	{
  		userforms[count] = new userForm(url,nameOfForm,displayIds,getCallBackFun(url));
  		getuserform = userforms[count];
  		count = count + 1;
  		doRequestUsingGet(url,displayIds);
  	}
  }
  
  function doRequestUsingGet(url,displayIds)
  {
  	displayId=displayIds;
    showDiv();
    if (window.XMLHttpRequest)
    { // Non-IE browsers
      req = new XMLHttpRequest();
      req.onreadystatechange = processStateChange;
      try 
      {
	      	req.open(submitMethod, url, true); //was post
	  }
	  catch (e) 
	  {
        alert("Problem Communicating with Server\n"+e);
      }
      req.send(null);
    } 
    else if (window.ActiveXObject) 
    { // IE
      req = new ActiveXObject("Microsoft.XMLHTTP");
      if (req) 
      {
        req.onreadystatechange = processStateChange;
        req.open(submitMethod, url, true); //was post
        req.send(null);
      }
    }
  }
  /**
   * Get the contents of the URL via an Ajax call
   * url - to get content from (e.g. /struts-ajax/sampleajax.do?ask=COMMAND_NAME_1) 
   * nodeToOverWrite - when callback is made
   * nameOfFormToPost - which form values will be posted up to the server as part 
   *					of the request (can be null)
   */
  function doRequestUsingPost(url,nameOfForm,displayIds) 
  {
    //get the (form based) params to push up as part of the get request
    displayId=displayIds;
    if (null != url && url.indexOf("?")<0)
    {
    	url += "?a=a";
    }
    //Do the Ajax call
    showDiv();
    if (window.XMLHttpRequest)
    { // Non-IE browsers
      req = new XMLHttpRequest();
      req.onreadystatechange = processStateChange;
      try 
      {
	      	req.open(submitMethod, url, true); //was post
	      	req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
	  }
	  catch (e) 
	  {
        alert("Problem Communicating with Server\n"+e);
      }
      req.send(getFormAsString(nameOfForm));
    } 
    else if (window.ActiveXObject) 
    { // IE
      req = new ActiveXObject("Microsoft.XMLHTTP");
      if (req) 
      {
        req.onreadystatechange = processStateChange;
        req.open(submitMethod, url, true); //was post
	    req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
        req.send(getFormAsString(nameOfForm));
      }
    }
  }

/*
   * Set as the callback method for when XmlHttpRequest State Changes 
   * used by retrieveUrl
  */
  function processStateChange() 
  {
  	  if (req.readyState == 4) 
  	  { // Complete
	      if (req.status == 200) 
	      { // OK response
	        setInnerHTML(displayId,req.responseText,0,getuserform.callbackfun);
	        hideDiv();
	        index = index+1;
	       	if(index<count)
	        {
	        	getuserform = userforms[index];
	        	if(submitMethod=="POST")
	        	{
	        		doRequestUsingPost(getuserform.url,getuserform.formname,getuserform.divid);
	        	}
	        	else
	        	{
	        		doRequestUsingGet(getuserform.url,getuserform.formname,getuserform.divid);
	        	}
	        }
	        else
	        {
	        	count = 0;
	        	index = 0;
	        	userforms = [];
	        	getuserform=null;
	        }
	      }
	      else if(req.status == 500)
	      {
	      	var errorAllMsg=req.responseText;
	      	var returnElements=errorAllMsg.split("<SPAN>");
	      	if(returnElements.length==1)
	      	{
		      	var tmpstrPos=errorAllMsg.indexOf("<SPAN");
		      	var tmpStr=errorAllMsg.substring(spanPos);
		      	var spanPos=errorAllMsg.indexOf(">")+1;
		      	var spanEndPos=errorAllMsg.indexOf("</SPAN>");
		      	alert(tmpStr.substring(spanPos,spanEndPos));
	      	}else
	      	{
	      		alert("error");
	      	}
	      }
	      else 
	      {
	        alert("Problem with server response:\n " + req.statusText);
	      }
    }
  }
 
 /**
  * gets the contents of the form as a URL encoded String
  * suitable for appending to a url
  * @param formName to encode
  * @return string with encoded form values , beings with &
  */ 
 function getFormAsString(formName)
 {
 	
 	//Setup the return String
 	returnString ="";
 	
 	if(document.forms[formName] == null)
 	{
 		return returnString;
 	}
  	//Get the form values
 	formElements=document.forms[formName].elements;
 	//loop through the array , building up the url
 	//in the form /strutsaction.do&name=value
 	
 	for ( var i=formElements.length-1; i>=0; --i )
 	{
 		if((formElements[i].type=="checkbox" && !formElements[i].checked) || (formElements[i].type=="radio" && !formElements[i].checked)) continue;
 		if(i==formElements.length)
 		{
 			returnString=formElements[i].name+"="+formElements[i].value;
 		}
 		else
 		{
 			returnString=returnString+"&"+formElements[i].name+"="+formElements[i].value;
 		}
 	}
 	returnString = returnString+"&submitByAjax=true"
 	//return the values
 	return returnString; 
 }
 
 function showDiv()
 {
 	var div = document.getElementById("AA_" + this.id + "_loading_div");
    if (div == null) {
    	var elementTop=(window.document.body.offsetHeight-parseInt(20))/2 + "px";
    	var elementLeft=(window.document.body.offsetWidth-parseInt(100))/2 + "px";
        div = document.createElement("DIV");

        document.body.appendChild(div);
        div.id = "AA_" + this.id + "_loading_div";

        div.innerHTML = "<img src='"+contextpath+"/images/loading.gif'>&nbsp;"; //+loading+"<img src='"+contextpath+"/images/load.gif'>";
        div.style.position = "absolute";
        //div.style.border = "1 solid #3E7ACE";
        //div.style.color = "black";
        //div.style.backgroundColor = "c0b9a7";
        //div.style.width = "60px";
        //div.style.height = "10px";
        //div.style.fontFamily = "Arial, Helvetica, sans-serif";
        //div.style.fontWeight = "bold";
        //div.style.fontSize = "11px";
        div.style.top =elementTop;
        div.style.left =elementLeft;
    }
    div.style.display = "";
}
function hideDiv()
{
	var div = document.getElementById("AA_" + this.id + "_loading_div");
    if (div != null)
        div.style.display = "none";
}

//Get callback function
function getCallBackFun(url)
{
	var funPos=url.indexOf("callbackFuncName");
	var callbackFunction="";
	if(funPos != -1)
	{
		var tmpStr=url.substring(funPos);
		var equalPos=tmpStr.indexOf("=");
		var andPost=tmpStr.indexOf("&");
		if(andPost != -1)
		{
			callbackFunction=tmpStr.substring(equalPos+1,andPost)+'()';
		}else
		{
			callbackFunction=tmpStr.substring(equalPos+1)+'()';
		}
	}
	return callbackFunction;
}

//set innerhtml and execute javascript
function setInnerHTML(divid,html,time,callbackfun)
{
	var inputHtml = getHTMLWithoutJS(req.responseText);
	if(displayId!=null && displayId!='')
	{
		document.getElementById(displayId).innerHTML = inputHtml;      		
	}
	if(callbackfun!=null && callbackfun!='')
	{
		scripts[scripts.length] = {text: callbackfun, src: '' };
	}
	execJS(time);
}

//Get all html codes without javascript
function getHTMLWithoutJS(html)
{
	html = html.split(/<\/script>/i);
	var purpleHTML="";
	for(var i=0;i<html.length;i++)
	{
		var currentHTML;
		currentHTML = html[i].replace(/<script[\s\S]*$/ig, "");
		purpleHTML = purpleHTML + currentHTML;
		scripts[i] = {text: '', src: '' };
		scripts[i].text = html[i].substr(currentHTML.length);
		scripts[i].src = scripts[i].text.substr(0, scripts[i].text.indexOf('>') + 1);
		scripts[i].src = scripts[i].src.match(/src\s*=\s*(\"([^\"]*)\"|\'([^\']*)\'|([^\s]*)[\s>])/i);
		if (scripts[i].src) 
		{
            if (scripts[i].src[2]) 
            {
                scripts[i].src = scripts[i].src[2];
            }
            else if (scripts[i].src[3]) 
            {
                scripts[i].src = scripts[i].src[3];
            }
            else if (scripts[i].src[4]) 
            {
                scripts[i].src = scripts[i].src[4];
            }
            else 
            {
                scripts[i].src = "";
            }
            scripts[i].text = "";
        }
        else 
        {
            scripts[i].src = "";
            scripts[i].text = scripts[i].text.substr(scripts[i].text.indexOf('>') + 1);
            scripts[i].text = scripts[i].text.replace(/^\s*<\!--\s*/g, "");
        }
	}
	return purpleHTML;
}

//execute javascript
function execJS(time)
{
	var script, add_script, remove_script,s;
	if (typeof(time) == "undefined") {
        s = 0;
    }
    else {
        s = time;
    }
	for (var i = 0; i < scripts.length; i++)
	{
		script = document.createElement("script");
		if (scripts[i].src) 
		{
            script.src = scripts[i].src;
        }
        else
        {
        	script.text = scripts[i].text;
        }
        script.defer = true;
        script.type =  "text/javascript";
        script.id = get_script_id();
        global_script_pool[script.id] = script;
        add_script = "document.getElementsByTagName('head').item(0)";
        add_script += ".appendChild(global_script_pool['" + script.id + "']);\n";
        window.setTimeout(add_script, s);
        remove_script = "document.getElementsByTagName('head').item(0)";
        remove_script += ".removeChild(document.getElementById('" + script.id + "'));\n";
        remove_script += "delete global_script_pool['" + script.id + "'];\n";
        window.setTimeout(remove_script, s + 10000);
	}
	scripts=[];
}

function get_script_id() 
{
        return "script_" + (new Date()).getTime().toString(36)
          + Math.floor(Math.random() * 100000000).toString(36);
}
