/**
 * 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 <ins id="name">newContent</ins>
 * 		 - each <ins> 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 flag=true;


  /**
   * 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 span_retrieveURL(url,nameOfFormToPost) {
    //get the (form based) params to push up as part of the get request
    
    //alert(url+" flag "+flag);
    if (nameOfFormToPost != null) {
	    url=url+span_getFormAsString(nameOfFormToPost);
	}
	
    //Do the Ajax call
    if(flag){
	    flag=false;
	    if (window.XMLHttpRequest) { // Non-IE browsers
	      req = new XMLHttpRequest();
	      req.onreadystatechange = span_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 = span_processStateChange;
	        req.open("GET", url, true);        
	        req.send();
	      }
	    }	    
	    flag=true;
    }    
  }

/*
   * Set as the callback method for when XmlHttpRequest State Changes 
   * used by retrieveUrl
  */
  function span_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 = span_splitTextIntoSpan(req.responseText);
        
        //Use these span elements to update the page
        span_replaceExistingWithNewHtml(spanElements);
        
      } 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 span_getFormAsString(formName){
 	//alert("Form "+formName);
 	//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
		// FEI
 		// necessaire ? la bonne transmission des select multiples
		if(formElements[i].type == "select-multiple") {
			selectOptions = formElements[i].options;
			for (var j=selectOptions.length-1; j>=0; --j){
				if (selectOptions[j].selected == true) {
					returnString=returnString+"&"+escape(formElements[i].name)+"="+escape(selectOptions[j].value);
				}
			}
		}
		// necessaire ? la transmission des radio buttons check?s.
		else if((formElements[i].type == "radio" || formElements[i].type == "checkbox")) {
 			if (formElements[i].checked) {
				returnString=returnString+"&"+escape(formElements[i].name)+"="+escape(formElements[i].value);
			}
		} 
		else {
			// cas classique
			returnString=returnString+"&"+escape(formElements[i].name)+"="+escape(formElements[i].value);
		}
 	}

 	//return the values
 	return returnString; 
 }
 
 /**
 * Splits the text into <span> elements
 * @param the text to be parsed
 * @return array of <span> elements - this array can contain nulls
 */
 function span_splitTextIntoSpan(textToSplit){
  	//Split the document
 	returnElements=textToSplit.split("</span>");
 	//alert(returnElements);
 	//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 span_splitTextIntoSpan)
  *					in the format <span id=name>texttoupdate
  */
 function span_replaceExistingWithNewHtml(newTextElements){

	// TODO: ajax
	// FEI: suppression de toutes les node <script> attach?es au head
	// par un appel pr?c?dent de retrieveURL.
	var head = document.getElementsByTagName("head")[0];
	// iteration sur les fils du head.
	var noeud = head.firstChild;
	while (noeud!=null) {
		if (noeud.nodeName=="SCRIPT") {
			//alert(noeud.nodeName + " " + noeud.getAttributeNode("ajax"));
			if (noeud.getAttributeNode("ajax") != null) {
				var nodeToRemove = noeud;
				noeud = noeud.nextSibling;
				head.removeChild(nodeToRemove);
				continue;
			}
		}
		noeud = noeud.nextSibling;
	}
	

 	//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;
 			
 			// RMG
 			//text = newTextElements[i];
 			contenu = newTextElements[i].substring(startContentPos);
 			//alert("Nouveau block pour span = "+name+" :\n"+contenu);
 			//content=newTextElements[i].substring(startContentPos);
 			//alert("Contenu ? remplacer "+content );
 			
 			//Now update the existing Document with this element
 			
	 			//check that this element exists in the document
	 			if(document.getElementById(name)){
	 			
	 				//alert("Replacing Element:"+name);
	 				document.getElementById(name).innerHTML = contenu;
	 				// FEI
	 				// ex?cution du code html
	 				// cf: http://kratcode.wordpress.com/2006/03/07/javascript-script-execution-in-innerhtml-the-revenge/
	 				// TODO: ajax
	 				span_execJS(document.getElementById(name));
	 			} else {
	 				//alert("Element:"+name+"not found in existing document");
	 			}
 		}
 	}
 }

function span_execJS(node){
  var bSaf = (navigator.userAgent.indexOf('Safari') != -1);
  var bOpera = (navigator.userAgent.indexOf('Opera') != -1);
  var bMoz = (navigator.appName == 'Netscape');

  if (!node) return;

  /* IE wants it uppercase */
  var st = node.getElementsByTagName('SCRIPT');
  var strExec;

  for(var i=0;i<st.length; i++){
    if (bSaf) {
      strExec = st[i].innerHTML;
      st[i].innerHTML = "";
    } else if (bOpera) {
      strExec = st[i].text;
      st[i].text = "";
    } else if (bMoz) {
      strExec = st[i].textContent;
      st[i].textContent;
    } else {
      strExec = st[i].text;
      st[i].text = "";
    }

    try {
      var x = document.createElement("script");
      x.type = "text/javascript";

	  // FEI: ajout d'un attribut sp?cifique permettant de savoir que le script 
	  // a ?t? cr?? par ajax.js.
	  var ajax = document.createAttribute("ajax");
      ajax.nodeValue = "true";
      x.setAttributeNode(ajax);
       
      /* In IE we must use .text! */
      if ((bSaf) || (bOpera) || (bMoz))
        x.innerHTML = strExec;
      else x.text = strExec;

	  if (!strExec.match(/^\s*$/)) {
	      document.getElementsByTagName("head")[0].appendChild(x);
	  }
    } catch(e) {
      alert(e);
    }
  }
}



