/*
	Copyright 2008 Lee S. Barney
	
	
    This file is part of QuickConnectiPhoneHybrid.

    QuickConnectiPhoneHybrid is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    QuickConnectiPhoneHybrid is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with QuickConnectiPhoneHybrid.  If not, see <http://www.gnu.org/licenses/>.


 */
 /*
 * A representaion of the unititialized request state '0'.
 */
ServerAccessObject.UNITITIALIZED = 0;

/*
 * A representaion of the setup but not sent request state '1'.
 */
ServerAccessObject.SETUP = 1;

/*
 * A representaion of the sent but not having recieved request state '2'.
 */
ServerAccessObject.SENT = 2;

/*
 * A representaion of the in process request state '3'.
 */
ServerAccessObject.IN_PROCESS = 3;

/*
 * A representaion of the complete request state '4'.
 */
ServerAccessObject.COMPLETE = 4;



/*
 * A representaion of the HTTP status code for file retrieval on OSX 'undefined'.  For other HTTP status codes go to www.w3.org/Protocols/rfc2616/rfc2616-sec10.html.
 */
ServerAccessObject.OSX_HTTP_File_Access = null;

/*
 * A representaion of the HTTP status code for OK '200'.  For other HTTP status codes go to www.w3.org/Protocols/rfc2616/rfc2616-sec10.html.
 */
ServerAccessObject.HTTP_OK = 200;

/*
 * A representaion of the HTTP status code for Bad Request '400'.  For other HTTP status codes go to www.w3.org/Protocols/rfc2616/rfc2616-sec10.html.
 */
ServerAccessObject.HTTP_BADREQUEST = 400;

/*
 * A representaion of the HTTP status code forVersion Not Supported '505'.  For other HTTP status codes go to www.w3.org/Protocols/rfc2616/rfc2616-sec10.html.
 */
ServerAccessObject.HTTP_VERSION_NOT_SUPPORTED = 505;

/*
* The two legal values for the data retrieval type
*/

ServerAccessObject.TEXT = 'Text';
ServerAccessObject.XML = 'XML';
ServerAccessObject.REFRESH = true;
ServerAccessObject.NO_REFRESH = false;

/*
*Constructor for a new ServerAccessObject instance. The purpose the Server Access Object is to 
*  create all requests for data from the server as well as requests for posting of data
*  to the server and make all preparations required to successfully make 
*  these calls.  All calls made are asynchronous.
*  parameter 1: URL - the URL of the main access point for the application
*/
function ServerAccessObject(URL){
	//attribute
	this.URL = URL;
	
	
	//put the getData and setData methods in delay loop until the data is returned and then return the data to the user.
	//methods
	this.getData = function(dataType, refresh, parameterSequence, HTTPHeaders){
		this.makeCall('GET', dataType, refresh, parameterSequence, null, HTTPHeaders);
	}
	this.setData = function(dataType, parameterSequence, data, HTTPHeaders){
		this.makeCall('POST', dataType, true, parameterSequence, data, HTTPHeaders);
	}

	/*
	* Executes the call to the server to post or get data. Creation and use of an xmlHttpRequestObject happens within this method.
	* parameter 1: {String} callType - GET, POST, or other HTTP type
	* parameter 2: {String} callBackCmd - the command to execute when the server returns a completed response.
	* parameter 3: {String} dataType - the data type of the response data with acceptable values of either Text or XML
	* parameter 4: {boolean} refresh - a flag indicating if refreshing should be enforced even if the data is currently cached on the server.
	* parameter 5: {String} parameterSequence - the parameter list to be added to the URL
	* parameter 6: {String or DOM element} data - any data to be sent with a POST type request
	* parameter 7: {Object} HTTPHeaders - a map of headers and header values to send to the server
	* returns true if request object can be used otherwise it returns false.
	*/
	this.makeCall = function(callType, dataType, refresh, parameterSequence, data, HTTPHeaders){
		var isJSONCall = false;
        if(callType != 'GET'){
            callType = 'POST';
        }
		if(dataType != ServerAccessObject.XML){
			dataType = 'Text';
		}
		if(refresh == null){
			refresh = false;
		}
		if(parameterSequence == null){
			parameterSequence = '';
		}
        /*
        * Get the request object to use
        */
		var http = null;
		try {
			http = new XMLHttpRequest();
		} 
		catch(e) {
			return false;
		}
		var isAsynch = true;//enforce always asynchronous
	
		if(parameterSequence != ''){
			parameterSequence = '?ajax=true&'+parameterSequence;
		}
			/*
		*	open a connection to the server located at 'this.URL'.
		*/
		http.open(callType,this.URL+parameterSequence, isAsynch);
		if(refresh){
		/*
		*   if we are to disable caching and force a call to the server, then the 'If-Modified-Since' header will 
		*	need to be set to some time in the past.
		*/
		  http.setRequestHeader( "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT" );
		}
		//if there are headers then add them to the request
		if(HTTPHeaders != null){
			for(var key in HTTPHeaders){
				http.setRequestHeader(key,HTTPHeaders[key]);
			}
		}
        //if a POST is being done and data is to be sent, set the content type header so that the data will be encoded correctly and sent on to the server for decoding
        if(callType =="POST" && data !=null){
            http.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
        }
		/*
		*	Set the function to be called when the server communicates with the client.
		*	For the ServerAccessObject this is an inline function that is the callback function defined below.
		*	The reason for the inline function is so that variables from within the makeCall method can be used.  If a non-inline 
		*	function is used then only the name of the function to be called is set as the onreadystatechange 
		*	method of the http class.
		*/
		http.onreadystatechange = function(){
            /*
            *	Only handle completed, finished messages from the server
            */
            if(http.readyState == ServerAccessObject.COMPLETE){
            	/*
            	* Set the default values
            	*/
                var resultData = null;
                //get the error command sent from the server if there was one
                var errorCommand = http.getResponseHeader('QC-Error-Number');
                var errorMessage = http.getResponseHeader('QC-Error-Message');
               
                /*
                * Firefox sets errorNumber equal to null if there is no error
                * IE7 sets it equal to an empty string
                */
                if(errorCommand != null && errorCommand.length > 0) {
                    dispatchToError(errorCommand, errorMessage);
                    return;
                }
                if(http.status != ServerAccessObject.HTTP_OK 
                    && http.status != ServerAccessObject.OSX_HTTP_File_Access){
                    dispatchToError('dataSecurityFailure');
                    return;
                }
               /*
                *  Retrieve the data if the server returns that the processing of the request was successful or if
                *  the request was directly for a file on the server disk.
                *  Get it as either Text or XML
                */
                resultData = http['response' + dataType];
				//window.alert(resultData);
				if(!checkSecurity(session.getAttribute('curCmd'), resultData)){
					dispatchToError('badData', 'insecure data recieved');
				}
                dispatchToVCF(session.getAttribute('curCmd'), resultData);
            }

        };
		/*
		*	Send off the completed request and include any data for a 'POST' request.
		*/
		http.send(data);
		return true;
	}
}