/******************** AJAX Base Object 2.0 *********************************/
/************	NOTES START *******************************************************************************************
*
*	Author:	Gil Collins
*	Date: 09/29/05
*	Purpose: 	Effectively allows the programmer to send the user a "popup" 
*			type message , since most browsers disable Popup notifications.
*	Instructions:
*
*	
*	Prerequisites:    (note required versions on top of the page)
*		2.0  javascript_global/ajax/baseAjax.js			           --This File
*		1.0  javascript_global/ajax/AjaxErrorLookup.js		           --Used for Plain English Explanation of Error Codes
*		x.x  javascript_global/ajax/ajax-parser.js		           --At least one of these and possible more will be included
*											Used in parsing the results returned. (Custom by User)
*
*	Example: (files used)
*		2.0  javascript_global/ajax/baseAjax.js			           --This File
*		1.0  javascript_global/ajax/AjaxErrorLookup.js		           --Used for Plain English Explanation of Error Codes
*		1.0  javascript_global/ajax/ajax-parser.js		           --At least one of these and possible more will be included
*											Used in parsing the results returned. (Custom by User)
*		1.0  javascript_global/ajax/ajax-parser2.js		           --At least one of these and possible more will be included
*		1.0  javascript_global/ajax/example.html			   --Demontstrates usage of GET and POST
*
*
*   readystate :    (returns a 4-byte integer)
        0 ...Uninitialized  (created but open has not been called)
        1 ...Loading        (created but send has not been called)
        2 ...Loaded         (send has been called but status and headers are not available)
        3 ...Interactive    (some data has been received, calling responseBody and responseText properties at this state to obtain partial results will 
                                return an error, because status and response are not fully available)
        4 ...Completed      (All data has been received, and the complete data is available in the responseBody and responseText properties)
    
    responseBody:   (IE ONLY)(represents the response entity body as an array of unsigned bytes, namely as a SAFEARRAY of type VT_ARRAY | VT_UI1 contains raw
                        unencoded bytes as received directly from the server.  Therefore it may appear as binary-encoded data (UTF-8, UCS-2, UCS-4,
                        Shift_JIS, and so on)

    responseStream: (IE ONLY )(represents the response entity body as an IStream.  Stream returns the raw unencoded bytes as received directly from the server.
                        Therefore, depending on what the server sent it may appear as binary-encoded data (UTF-8, UCS-2, UCS-4, Shift_JIS, and so on)

    responseText:   (attempts to decode the response into a Unicode string.  It assumes the default encoding is UTF-8, but can decode any type 
                        UCS-2(big or little endian) or UCS-4 encoding as long as the server sends the appropriate Unicode byte-order mark.
                        It does NOT process the <? XML coding declaration.  If you know the response is going to be XML then use responseXML.

    responseXML:    (MS: default validation is turned off; If the response entity body is not valid XML, this property returns DOMDocument that was
                        parsed so that you can access the error.  This property does NOT return XMLDOMParseError itself but is accessible from
                        DOMDocument.  If the response is generated with ASP and the MIME type is not correctly set to "text/xml" using
                        Response.ContentType, responseXML will be empty.

    channel:        (Mozzila ONLY)

    status:         (Long integer, represents the returned status code as a long integer.  Valid only after the send method returns successfully.)
    			*See AjaxErrorLookup.js

    statusText:     (String. Represents the HTTP response as a BSTR value.  Valid only after the send method returns successfully)
    
*************************
** XMLHttpRequest METHODS
*************************

    abort:  (Request is returned to the UNINITIALIZED state and open method must be called next)

    getAllResponseHeaders:  (Each header name/value pair is separated by a combination carriage return-line feed character(vbCrLf in MS VB)
                                valid only after send has successfully completed)

    getResponseHeader:  (Valid only after send method has successfully completed.  The line xmlhttp.getResponseHeader("Content-Type");, returns
                            the string "text/xml", assuming the server set "text/xml" as the content type.  The full list of available
                            header variables are in getAllResponseHeaders)
    
    open:   (syntax: xmlhttp.open(String method, String Url, boolean Async, String User, String Password)
                method  : http(s) only
                url     : URL to send the request
                async   : synchronous or asynchronous
                user    :   if necessary
                password:   if necessary
                After calling this method you must call send to send the request and data if any to the server.
                Even though this method accepts parameters for user / pass they are not automatically sent until the server sends back a 401

    send:   (This method is synchronous or asynchronous, depending on the value of bAsync parameter in the open method call.  bAsync can be true or false
                if its false this call does NOT return until the entire response is received or the protocol stack times out.  If true it returns
                immediately.  UTF-8 is assumed unless a Content-Type header with the appropriate content type is set.  If XML is sent UTF-8 is assumed unless 
                <? declaration for encoding is set.

    setRequestHeader:   (sets a variable and its value, if another of this name already exists its overridden.
                        setRequestHeader(String header, String value)

    overrideMimeType:   (can be used to override the type sent from the server.  Must be sent prior to send())
*************************
** XMLHttpRequest EVENTS
*************************
*/

/********************* START OF AJAX EXAMPLE ********************************/
function test2() {
	
	var shipMethodForms = new Array(2);					//Create an Array of Size 2
	shipMethodForms[0]='shipMethodForm';					//Set our array indices
	shipMethodForms[1]='sackInfo';
        
	var call1 = new BaseAjax();						//Create an Instance of our Object
	var xmlobj1 = call1.createRequest();					//Create our xmlObject
	call1.readystatechange(xmlobj1, exampleParse, 'text', true);		//xmlObject, parser, return type, debug
	call1.setCallType('POST');						//Send Type
	call1.setFormNamesArray(shipMethodForms, 2, 'test1', false);		//form names array, size of forms, field exceptions, debug
	call1.process(xmlobj1, '/Utils/servlet/YourIPAddress');			//xmlObject, URI
	
	var call2 = new BaseAjax();
	var xmlobj2 = call2.createRequest();
	call2.readystatechange(xmlobj2, exampleParse2, 'text', false);
	call2.setCallType('GET');
	call2.process(xmlobj2, '/Utils/servlet/PullIPData');
}

/********************* START OF AJAX OBJECT ********************************/
var uninitializedReadyState = 0;
var loadingReadyState = 1;
var loadedReadyState = 2;
var interactiveReadyState = 3;
var completedReadyState = 4;

function BaseAjax() {
}
BaseAjax.prototype.init = function() {
	
}
BaseAjax.prototype.createRequest = function() {
	if(window.XMLHttpRequest){
	    return new XMLHttpRequest();
	} else if(window.ActiveXObject){
	    return new ActiveXObject("Microsoft.XMLHTTP");
	} else {
	    return;
        }
}
BaseAjax.prototype.readystatechange = function(xmlObj, thisfunction, returnAs, debug) {

xmlObj.onreadystatechange = function() {
	switch (xmlObj.readyState) {
	        case loadedReadyState, interactiveReadyState:
	            break;
       		case completedReadyState:
       		    if (xmlObj.status == 200) {
       		     	thisfunction(xmlObj, returnAs, debug);
       		    }
       		    else if (xmlObj.status == 404) {
	                alert(new AjaxErrorLookup(xmlObj.status));
	            }
	            else if (xmlObj.status == 500) {
	                alert(new AjaxErrorLookup(xmlObj.status));
	            }
	            else{
	              	alert(new AjaxErrorLookup(xmlObj.status));
	            }
	            xmlObj = null;
       		    break;
		}
	}
	
}
BaseAjax.prototype.setCallType = function(type) {
	//Must be GET or POST
	if(type.length > 0 && (type == 'GET' || type == 'POST')) {
		this.callType = type;
	}
	else if (type.length > 0){
		this.callType = 'GET';
		alert("Type must be GET or POST");
	}
	else if (type.length <= 0){
		this.callType = 'GET';
	}
}
BaseAjax.prototype.setFormNamesArray = function(formNamesArray, properFormArraySize, theseExceptions, debug) {
	this.formNamesArray = formNamesArray;
	this.theseExceptions = theseExceptions;
	this.properFormArraySize = properFormArraySize;
	this.debug = debug
}
BaseAjax.prototype.process = function(xmlObj, uri) {
	if(this.callType == 'GET') {
		try {
			xmlObj.open ('GET', uri, true);
			xmlObj.send (null);
	        }
	        catch(e) {
	        	alert("Error at XML Object Open in Get: "+e);
	        }
	}
	else {
		try {
			xmlObj.open("POST", uri);
			xmlObj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
			xmlObj.send(getFormData(this.formNamesArray, this.theseExceptions, this.properFormArraySize, this.debug));
        	}
        	catch(e) {
		      	alert("Error at XML Object Open in POST: "+e);
	        }
	}
}



/********************************** UTILITY FUNCTIONS ****************************************/
/*************
	Send in an Array of formNames and retrieve All name/value pairs for a POST
    ********************************************************************************/
function getFormData(formNames, exceptions, properFormArraySize, thisdebug) {

    if(thisdebug) {
        alert("|"+properFormArraySize+"|");
    }

    if(isArray(formNames)) {
        var data = "";

        for(var j = 0; j < formNames.length; j++) {

                var form = parent.document.forms[formNames[j]];
                var fields = form.elements;
                for (i=0;i<fields.length;i++){
                    if (fields[i].type.indexOf("button")==-1){
                        if (exceptions.indexOf(fields[i].name) == -1) {
                            data = data + fields[i].name + "=" + fields[i].value + "&";
                        }
                    }
                }
        }
    }
    else if(isString(formNames)){
        if(thisdebug) {
            alert("Passed in the Array of formNames as size: "+properFormArraySize+" but it believes that its the size of : "+formNames.length);
        }
        var data = "";

        var formNamesArray = formNames.split(",");
        for(var j = 0; j < formNamesArray.length; j++) {

                var form = parent.document.forms[formNamesArray[j]];
                var fields = form.elements;
                for (i=0;i<fields.length;i++){
                    if (fields[i].type.indexOf("button")==-1){
                        if (exceptions.indexOf(fields[i].name) == -1) {
                            data = data + fields[i].name + "=" + fields[i].value + "&";
                        }
                    }
                }
        }
    }

    if(thisdebug) {
        alert(data);
    }

    return data;
}


/*******
	Is this an Array Type
	*********************/
function isArray(a) {
    return isObject(a) && a.constructor == Array;
}

/*******
	Is this an Object Type
	*********************/
function isObject(a) {
    return (a && typeof a == 'object') || isFunction(a);
}