
//TODO: getContentForDiv, getContentForDivUsingForm and possibly submitAjaxGetRequestUsingForm parameters 
// (div and form) should be changed so that they are string id's of html elements, rather than the html 
// elements themselves. 
// --I.E., the "document.getElementById('divId')" call should be in THIS file and not in the js or vm files 
// that make the calls to these functions.
// There are in the realm of 30 files that use these functions, so there's a bit of testing involved.


//======================================                  ========================================//
//====================================== PUBLIC FUNCTIONS ========================================//
//======================================                  ========================================// 

function getContentForDivUsingForm(url, form, div, avoidCaching) {
	url = appendFormValuesToUrl(url, form);
//alert("ajax.js getContentForDivUsingForm url="+url+"  form="+form)
	getContentForDiv(url, div, avoidCaching);
}

// replace DIV contents with html received from the server
function getContentForDiv(url, div, avoidCaching) {
	if (usingIFrame_AjaxWorkaround()) {
		// time delay is required so DOM completes rendering before IFrame is added	
		setTimeout(
			function () { GetContentForDivPrivateFunction(url, div, avoidCaching); },
		 	1500);
	} else {
		GetContentForDivPrivateFunction(url, div, avoidCaching);
	};
}

function submitAjaxGetRequestUsingForm(url, form, avoidCaching, processResponseCallback) {
	url = appendFormValuesToUrl(url, form);
	submitAjaxGetRequest(url, avoidCaching, processResponseCallback);
}

// generic ajax call
function submitAjaxGetRequest(url, avoidCaching, processResponseCallback) { 
//alert("ajax.js submitAjaxGetRequest url="+url+" processResponseCallback="+processResponseCallback);
  	var http_request = createRequestObject(url,avoidCaching,'GET',processResponseCallback);  

    if (!http_request) {

        return false;
    }
  
//alert("ajax.js submitAjaxGetRequest b4 send");  	
    http_request.send(null);
}

function browserSupportsAjax() {
	if (getHttpRequestObject()) {
		return true;
	}
	return false;
}

function submitAjaxPostRequestUsingForm(url, form, avoidCaching, processResponseCallback) {
	parameters = getParametersUsingForm(form);
	submitAjaxPostRequest(url, parameters, avoidCaching, processResponseCallback);
}

function submitAjaxPostRequest(url, parameters, avoidCaching, processResponseCallback) {

   var http_request = createRequestObject(url,avoidCaching,'POST',processResponseCallback);  
        	
   // Parameters sent with this content type have the expected format of name separated 
   // ... from the value by '=' and the pairs separated from each other by '&'.
   http_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
   http_request.setRequestHeader("Content-length", parameters.length);
   
   // The default implementation for a request is a Persistant Connection, that allows
   // ... the server to reply to many requests from the client using a TCP connection that is left open.
   // Right now we specify that the connection is NOT a Persistant Connection.
   // This is because our use of this expects no meaningful return object, 
   // ... but in the future this value may be changed.
   http_request.setRequestHeader("Connection", "close");
   
   http_request.send(parameters);
}


/*Removes PRE tags from text; necessary for JSON, sometimes browsers add it*/
function removePreTags(text) {
	text = text.replace("<PRE>","");
	text = text.replace("</PRE>","");
	return text;
}

//======================================                   ========================================//
//====================================== PRIVATE FUNCTIONS ========================================//
//======================================                   ========================================// 

function GetContentForDivPrivateFunction(url, div, avoidCaching) {
//alert("ajax.js GetContentForDivPrivateFunction url="+url+"  div="+div.toString()+" avoidCaching="+avoidCaching)
	submitAjaxGetRequest(url, 
					avoidCaching, 
					function(responseText) { // pass in anonymous function
						div.innerHTML = responseText;

						//parse responseText and call eval on any script in there
						var rgxScriptLineBreaks = new RegExp("\\n|\\r","g");
						responseText = responseText.replace(rgxScriptLineBreaks,"");
						
						var rgxGetScripts = new RegExp("<script[^>]*>(.*?)<\/script>","gi");
						var arrayOfScriptMatches = responseText.match(rgxGetScripts);
						var rgxStripScriptTags = new RegExp("<[\/]?script[^>]*>","gi");
				
						if (arrayOfScriptMatches != null){
							for(i=0; i < arrayOfScriptMatches.length; i++){
								arrayOfScriptMatches[i] = arrayOfScriptMatches[i].replace(rgxStripScriptTags,"");
							}
	
							eval(arrayOfScriptMatches.join(";"));
						}
					});
}

function getParametersUsingForm(myform) {
	// get form object if only form name was passed in
	if (!myform.elements) {
		myform = document.getElementById(myform);
	}
	
	var poststr = "";

  	for (i=0; i<myform.elements.length; i++) {

  		var currentInput = myform.elements[i];
		if ((currentInput.type != "radio" && currentInput.type != "checkbox") || currentInput.checked==true){
    		if (poststr != "") {
       			poststr += "&";
	       	}
    	   	poststr += myform.elements[i].name + "=" + myform.elements[i].value;
		}

  	}	
  	
  	return poststr;
}

function appendFormValuesToUrl(url, form) {
	var myform = form;
	
	// get form object if only form name was passed in
	if (!myform.elements) {
		myform = document.getElementById(form);
	}
	
	var poststr = "";
	
	if (myform.elements.length > 0){
		if (url.indexOf("?") == -1) {
			poststr = "?";
		} else {
			poststr = "&";
		}
	}
	poststr += getParametersUsingForm(myform);
  	return url + poststr;
}

function usingIFrame_AjaxWorkaround() {
	var http_req = getHttpRequestObject();
	if (http_req && http_req instanceof HttpReqIFrameWorkaround) {
		return true;
	}
	return false;
}

// gets browser-specific implementation of http request object
function getHttpRequestObject() {
	var http_request = false;
    if (window.XMLHttpRequest) { // Mozilla, Safari, IE7 ...
        http_request = new XMLHttpRequest();
        if (http_request.overrideMimeType) {
            http_request.overrideMimeType('text/xml');
            // See note below about this line
        }
    } else if (window.ActiveXObject) { // IE 6 and previous ...
        try {
            http_request = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            try {
                http_request = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e) { }
        }
    }
    
    if (!http_request) {  // try workaround for IE 6 with ActiveX disabled (custom object uses IFrames)
    	try {
    		http_request = new HttpReqIFrameWorkaround();
    	} catch (e) {
    	}
    }
    
    return http_request;
}

// This method creates a new HttpREquestObject based on the HTTPMETHOD you provide along with the 3 paramters.
function createRequestObject(url,avoidCaching,httpMethod,processResponseCallback){

	var http_request = getHttpRequestObject();

    if (!http_request) {
        // alert('Giving up :( Cannot create an XMLHTTP instance');
        // TODO handle error
        return false;
    }

	//The third parameter of open method is to set that the method is asynchronous.
	//If TRUE, the execution of the JavaScript function will continue while the response of the server has not yet arrived. 
	//This is the A in AJAX.
    http_request.open(httpMethod, url, true);     

    if (avoidCaching) {
    	http_request.setRequestHeader( "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT" ); // avoids caching in IE
    }

    http_request.onreadystatechange = function() {    
 			// anonymous function definition
 			if (http_request.readyState == 4) {
     			if (http_request.status == 200) {
  
//alert("ajax.js createRequestObject");   			
         			processResponseCallback(http_request.responseText);
     			} else {
     				// alert('There was a problem with the request.');
     				// TODO handle error
     			}
 			}
    };

    return http_request;
}


//======================================                  ========================================//
//====================================== CUSTOM OBJECTS   ========================================//
//======================================                  ========================================// 


/*
 * A custom object for IE browsers that don't run ActiveX.  Used as
 *  a workaround for Ajax, using IFrames under hood.  Exposes the 
 *  same properties and methods
 * 
 *
 *    Define its methods and properties using the js 'prototype' definitions below
 */
var HttpReqIFrameWorkaround = function() {
    this.method = "POST";
    this.url = null;
    this.async = true;
    this.iframe = null;
    this.responseText = null;
    this.header = new Object();
    this.id = "_xmlhttp_" + new Date().getTime() + Math.random();
    this.container = document.body;
}

HttpReqIFrameWorkaround.prototype.open = function(method, url, async) {
    // this.method = method; // always keep it default POST, or else query params in the url will be ignored
    this.url = url;
    this.async = async;
    this.readyState = 0;

    this.iframe = document.createElement("IFRAME");
    this.iframe.style.visibility = "hidden";
    this.iframe.id = this.id;
    this.iframe.src = "javascript:''";
    
    if(document.getElementById(this.id) == null) {
        this.container.appendChild(this.iframe);
    }
    
    this.setRequestHeader("___xmlhttp", "iframe");
}

HttpReqIFrameWorkaround.prototype.setRequestHeader = function(name, value) {
    // if(typeof(this.header[name]) == "undefined")
        this.header[name] = value;
}

HttpReqIFrameWorkaround.prototype.send = function(data) {
	//alert('in send');
	var html = [];
    html[html.length] = '<html><body><form method="' + this.method + '" action="' + this.url + '">';
    
    for(name in this.header)
        html[html.length] = '<textarea name="' + name + '">' + this.header[name] + '</textarea>';
    
    if(data != null && data.length > 0)
        html[html.length] = '<textarea name="_data">' + data + '</textarea>';

    html[html.length] = '<s'+'cript>document.forms[0].submit();</s'+'cript>';
    // html[html.length] = '<input type="submit">';
    
    html[html.length] = '</form></body></html>';

    this.iframe._xmlhttp = this;
    this.iframe._xmlhttp._fix = -1;
    this.iframe._xmlhttp.responseText = null;
    this.iframe.onreadystatechange = this._onreadystatechange;
    
    this.iframe.src = "javascript:document.write('" + html.join('').replace(/\'/g,"\\'").replace(/\r\n/g, "\\r\\n") + "');void(0);";
    //alert(this.iframe.src);
	//alert('end send');    
}

HttpReqIFrameWorkaround.prototype._onreadystatechange = function() {
	//alert('in _onreadystatechange');
    this._xmlhttp._fix++;
    
    if(this._xmlhttp._fix < 1)
        return;
    
    if(this._xmlhttp._fix == 1) {
        this._xmlhttp.readyState = 1;
    }
    else if(this._xmlhttp._fix > 1) {
    	
        switch(this.readyState.toString()) {
            case "loading":
                this._xmlhttp.readyState = 2;
                break;

            case "interactive":
                this._xmlhttp.readyState = 3;
                break;

            case "complete":
                this._xmlhttp.responseText = window.frames[this.id].document.childNodes[0].childNodes[1].innerHTML;
                this.onreadystatechange = function(){}
                this._xmlhttp.readyState = 4;
                this._xmlhttp.status = 200; // fake a valid http response
                break;
        }   
    }
    
    if(typeof(this._xmlhttp.onreadystatechange) == "function") {
            this._xmlhttp.onreadystatechange();
    }
    //alert('end _onreadystatechange');
}

