/**
 * 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 onLoadReq; 
  var which;


  /**
   * 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 retrieveURL(url,nameOfFormToPost,stateformfieldname,isTextField) {
  
    if (isTextField == null)	
    	isTextField = false; 
   
    //get the (form based) params to push up as part of the get request
    // JMR - changed logic - some forms are way too long to put on the QS 
    //url=url+getFormAsString(nameOfFormToPost,stateformfieldname);
    url=url+getSpecifiedFormFieldsAsString(nameOfFormToPost,stateformfieldname,stateformfieldname,isTextField);
    
    //Do the Ajax call
    if (window.XMLHttpRequest) { // Non-IE browsers
      req = new XMLHttpRequest();
      req.onreadystatechange = processStateChange;
      try {
      	req.open("GET", url, true); //was get
      } 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("GET", url, true);
        req.send();
      }
    }
  }
  
  
  /**
   * Get the contents of the URL via an Ajax call
   * Special case - for onLoad to work around an IE select box redraw problem.
   *  - load the special onLoadProcessStateChange instead of the default.
   * 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 onLoadRetrieveURL(url,nameOfFormToPost,stateformfieldname,isTextField) {
  
    if (isTextField == null)	
    	isTextField = false; 
   
    //get the (form based) params to push up as part of the get request
    // JMR - changed logic - some forms are way too long to put on the QS 
    //url=url+getFormAsString(nameOfFormToPost,stateformfieldname);
    url=url+getSpecifiedFormFieldsAsString(nameOfFormToPost,stateformfieldname,stateformfieldname,isTextField);
	
	//alert("onLoadRetrieveURL"); 
    
    //Do the Ajax call
    if (window.XMLHttpRequest) { // Non-IE browsers
      onLoadReq = new XMLHttpRequest();
      onLoadReq.onreadystatechange = onLoadProcessStateChange;
      try {
      	onLoadReq.open("GET", url, true); //was get
      } catch (e) {
        //alert("Problem Communicating with Server\n"+e);
      }
      onLoadReq.send(null);
    } else if (window.ActiveXObject) { // IE
      
      onLoadReq = new ActiveXObject("Microsoft.XMLHTTP");
      if (onLoadReq) {
		//alert("update onLoadReq"); 
        onLoadReq.onreadystatechange = onLoadProcessStateChange;
        onLoadReq.open("GET", url, true);
        onLoadReq.send();
      }
    }
  }

  /**
   * 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 retrieveURLusingID(url,nameOfFormToPost,stateformfieldname,stateformid,isTextField) {
  
    if (isTextField == null)	
    	isTextField = false; 
   
    //get the (form based) params to push up as part of the get request
    // JMR - changed logic - some forms are way too long to put on the QS 
    //url=url+getFormAsString(nameOfFormToPost,stateformfieldname);
    url=url+getSpecifiedFormFieldsAsString(nameOfFormToPost,stateformfieldname,stateformfieldname,isTextField);
    url=url+getSpecifiedFormFieldsAsStringByID(nameOfFormToPost,stateformid);
    
    // Oui VEY! 
    //alert("URL="+url); 
    
    //Do the Ajax call
    if (window.XMLHttpRequest) { // Non-IE browsers
      req = new XMLHttpRequest();
      req.onreadystatechange = processStateChange;
      try {
      	req.open("GET", url, true); //was get
      } 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("GET", url, true);
        req.send();
      }
    }
  }  

  /*
   * 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
        
        //alert("Ajax response:"+req.responseText);
        
        //Split the text response into Span elements
        spanElements = splitTextIntoSpan(req.responseText);
        
        //Use these span elements to update the page
        replaceExistingWithNewHtml(spanElements, false);
        
      } else {
        //alert("Problem with server response:\n " + req.statusText);
      }
    }
  }
 
 
  /*
   * Set as the callback method for when XmlHttpRequest State Changes 
   * used by onLoadRetrieveUrl
   * This is a special case for onLoad to work around an IE select box redraw. 
   */
  function onLoadProcessStateChange() {
  
    if (onLoadReq.readyState == 4) { // Complete
      if (onLoadReq.status == 200) { // OK response
        
        //alert("onLoad Ajax response:"+onLoadReq.responseText);
        
        //Split the text response into Span elements
        spanElements = splitTextIntoSpan(onLoadReq.responseText);
        
        //Use these span elements to update the page
        replaceExistingWithNewHtml(spanElements, true);
        
      } else {
        //alert("Problem with server response:\n " + onLoadReq.statusText);
      }
    }
  }
 
 
 function blankCounty() {
        //Split the text response into Span elements
        spanElements = splitTextIntoSpan("<span id=\""+"countyselect\""+"><select name='county' disabled style=\"width:220px; font-size:12px;\" ></select></span>");
        
        //Use these span elements to update the page
        replaceExistingWithNewHtml(spanElements);
 
 }
 
 /**
  * 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,stateformfieldname){
 	
 	//Setup the return String
 	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 ){
 		//we escape (encode) each value
 		if (formElements[i].name == stateformfieldname){
			var multiSelectString = getSelectedForGet(formElements[i],formElements[i].name);
			returnString=returnString+"&"+multiSelectString;
 		}
 		else{
	 		returnString=returnString+"&"+escape(formElements[i].name)+"="+escape(formElements[i].value);
	 	}
 		
 	}
	//alert(returnString);
 	
 	//return the values
 	return returnString; 
 }


 /**
  * 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 getSpecifiedFormFieldsAsString(formName,stateformfieldname,specificformfieldnames,isTextField){
 	
 	//Setup the return String
 	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 ){
 		//we escape (encode) each value
		//alert("form fieldname Name="+formElements[i].name); 		
		//alert("form fieldname  ID="+formElements[i].id); 		
 		if (formElements[i].name == specificformfieldnames){
 		
			if (formElements[i].name == stateformfieldname){
				if (isTextField == true){
					returnString=returnString+"&"+escape(formElements[i].name)+"="+escape(formElements[i].value);
				}
				else{
					var multiSelectString = getSelectedForGet(formElements[i],formElements[i].name);
					returnString=returnString+"&"+multiSelectString;
				}
			}
			else{
				returnString=returnString+"&"+escape(formElements[i].name)+"="+escape(formElements[i].value);
			}
		}	
 		
 	}
	//alert(returnString);
 	
 	//return the values
 	return returnString; 
 }


 /**
  * 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 getSpecifiedFormFieldsAsStringByID(formName,stateformfieldid){
 	
 	//Setup the return String
 	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 ){
 		//we escape (encode) each value
		//alert("id form fieldname Name="+formElements[i].name); 		
		//alert("id form fieldname  ID="+formElements[i].id); 		
		if (formElements[i].id == stateformfieldid){
			returnString=returnString+"&"+escape(formElements[i].id)+"="+escape(formElements[i].value);
		}
 		
 	}
	//alert(returnString);
 	
 	//return the values
 	return returnString; 
 }


 
  function getSelected(opt) {
      var selected = new Array();
      var index = 0;
      for (var intLoop=0; intLoop < opt.length; intLoop++) {
         if (opt[intLoop].selected) {
            index = selected.length;
            selected[index] = new Object;
            selected[index].value = opt[intLoop].value;
            selected[index].index = intLoop;
         }
      }
      return selected;
   }
   
  function getSelectedForGet(opt,paramName) {
      var selected = new Array();
      var index = 0;
      var mStringValues = ""; 
      for (var intLoop=0; intLoop < opt.length; intLoop++) {
         if (opt[intLoop].selected) {
            index = selected.length;

	    mStringValues = mStringValues + "&" + escape(paramName)+"="+escape(opt[intLoop].value)
         }
      }
      // remove starting comma 
      if (mStringValues.charAt(mStringValues,0) == '&'   )
      {
      	//  remove it 
      	mStringValues = mStringValues.substr(1); 
	//alert("new string="+mStringValues);
      }
      return mStringValues;
   }


  function getSelectedAsCommaDelmitedString(opt) {
      var selected = new Array();
      var index = 0;
      var mStringValues = ""; 
      for (var intLoop=0; intLoop < opt.length; intLoop++) {
         if (opt[intLoop].selected) {
            index = selected.length;
            mStringValues = mStringValues + "," + opt[intLoop].value;
         }
      }
      // remove starting comma 
      if (mStringValues.charAt(mStringValues,0) == ','   )
      {
      	//  remove it 
      	mStringValues = mStringValues.substr(1); 
	//alert("new string="+mStringValues);
      }
      
      return mStringValues;
   }
 
 
 /**
 * Splits the text into <span> elements
 * @param the text to be parsed
 * @return array of <span> elements - this array can contain nulls
 */
 function splitTextIntoSpan(textToSplit){
 
  	//Split the document
 	returnElements=textToSplit.split("</span>")
 	
 	//Process each of the elements 	
 	for ( var i=returnElements.length-1; i>=0; --i ){
 		
 		//Remove everything before the 1st span
 		spanPos = returnElements[i].indexOf("<span");		
 		
 		//if we find a match , take out everything before the span
 		if(spanPos>0){
 			subString=returnElements[i].substring(spanPos);
 			returnElements[i]=subString;
 		
 		} 
 	}
 	
 	return returnElements;
 }
 
 /*
  * Replace html elements in the existing (ie viewable document)
  * with new elements (from the ajax requested document)
  * WHERE they have the same name AND are <span> elements
  * @param newTextElements (output of splitTextIntoSpan)
  *					in the format <span id=name>texttoupdate
  */
 function replaceExistingWithNewHtml(newTextElements, isOnLoad){
 
 	//loop through newTextElements
 	for ( var i=newTextElements.length-1; i>=0; --i ){
  
 		//check that this begins with <span
 		if(newTextElements[i].indexOf("<span")>-1){
 			
 			//get the name - between the 1st and 2nd quote mark
 			startNamePos=newTextElements[i].indexOf('"')+1;
 			endNamePos=newTextElements[i].indexOf('"',startNamePos);
 			name=newTextElements[i].substring(startNamePos,endNamePos);
 			
 			//get the content - everything after the first > mark
 			startContentPos=newTextElements[i].indexOf('>')+1;
 			content=newTextElements[i].substring(startContentPos);
 			
 			//Now update the existing Document with this element
 			
			//check that this element exists in the document
			var spanelem = document.getElementById(name)
			if(spanelem)
			{	
				var oldCountyOnChange = null; 	
				var oldCountySelectBox = spanelem.getElementsByTagName("select")[0]; 							
				
				if (oldCountySelectBox)
				{
					oldCountyOnChange = oldCountySelectBox.onchange;
				}
				
				spanelem.innerHTML = content;
				
				if (oldCountyOnChange)
				{
					var newCountySelectBox = spanelem.getElementsByTagName("select")[0];
					
					newCountySelectBox.onchange = oldCountyOnChange;
				}
				
				if (isOnLoad) 
				{					
					//alert("Replacing Element:"+name);
					var countyselectbox; 					
					
					//alert("try to find the county box"); 						
					// find the select element from the inside the span text that was just replaced. 
					countyselectbox = spanelem.getElementsByTagName("select"); 
					
					if (countyselectbox) 
					{
						//alert("span: found select"); 
						// assume that there 1st select element is the one we want. 
						countyselectbox = countyselectbox[0]; 
					}
	
					if (countyselectbox) 
					{
						spanelem.getElementsByTagName("select"); 
						// set focus on the the select box. 
						countyselectbox.focus();
						
						// iterate through all the items in list and find the last selected items
						//for(var index = countyselectbox.options.length - 1; index >= 0; index--)
						
						// iterate through all the items in list and find the first selected items
						for(var index = 0; index < countyselectbox.options.length; index++)
						{
							if (countyselectbox.options[index].selected == true)
							{
								// found a selected option
						
								// check if the select box is larger than one element height. 
								if (countyselectbox.size > 1) {
									// the box is bigger than one element high
									// now check if there is another element below the current element
									if (index < countyselectbox.options.length - 1) {
										// toggle this element
										// this force the browser to redraw the select box slightly higher
										countyselectbox.options[index + 1].selected = ! (countyselectbox.options[index + 1].selected); 
										countyselectbox.options[index + 1].selected = ! (countyselectbox.options[index + 1].selected); 
									}
								} 
								
								// now toggle the selected element
								// this force the select box redraw for the last element or the single element high select box
								countyselectbox.options[index].selected = false; 
								countyselectbox.options[index].selected = true; 
								
								break; 
							}
						}
	
						// undo the focus back to the default state. 
						countyselectbox.blur();					
					}
				}
				
			} else {
				//alert("Element:"+name+"not found in existing document");
			}
 		}
 	}
 }

 /**
 * test if previous county selection has been saves on the form and retrieve it.
 * to be on called when a page with county select ajax form is loaded = <body onLoad=..> 
 * @param the based string of the url to be used for the form. 
 */
function initLoadCounty(hiddenid, url,stateformfieldname,stateformid)
{
	// window.alert("saveCountySel");
	
	// retrieve the hidden field where the previous county selection would be saved. 
	var field = document.getElementById(hiddenid);
	
	// we assume the field is by default initialized to 'init' string. This indicates no
	// county information has been saves before. 
	if (field && field.value != 'init')
	{
		// there is a previously cache value, retrieve and update form. 
		url = url + '&preselected=' + field.value; 
		onLoadRetrieveURL(url,stateformfieldname,stateformid);
	}
}

/**
 * create a comma delimited list of select values and
 * save list into the hidden field
 * this function is to be called with onChange event
 * @param - the name of the hidden field
 * @param - the selection list object 
 */ 
function saveCountySelection(hiddenid, object)
{
	var field = document.getElementById(hiddenid);
	var temp = '';
	var count = 0; 
	
	// JMR added null check for pages that do not use this back button stuff
	if (field != null){
		// iterate through all the items in list and find the selected items
		for(var index = 0; index < object.options.length; index++)
		{
			if (object.options[index].selected == true)
			{
				// build out a comma delimted string to represent the selection
				if (count == 0)
				{
					temp = object.options[index].value;
					count++; 
				}
				else
				{
					temp = temp + ',' + object.options[index].value;
				}
			}
		}

		// same the selection in the hidden field. 
		field.value = temp; 
	}
}
