/**

 * SOE Platform - Remote Procedure Call Object 2

 * @class rpc

 * @version 2.0

 * @requires debug.js

 * @author Scott Clarke

 * @constructor none

 */

if (typeof common !== "undefined") {

	common.load('util.browser', 1, null);

}



window.rpc = {



	/**

	 *  RPC Object Properties

	 */

	async: true,

	httpResponseText: null,

	showRPCStatus: false,

	responseHandler: null,

	currentState: "Connection Uninitialized.",

	connState: ["Connection Uninitialized.","Connection Open. Wait for Request.","Data recieved.","Processing Data.","Request Complete","Unknown RPC state."],

	version : 2.0,

	statusIcon : "<div align='center' style='padding: 10px;'><img src='/images/ajax-loader.gif' align='absmiddle' alt='Loading'/></div>",

	preventCaching : true,

	toJSON : false,

	cometFrameObj : null,

	cometHttpRequest : null,

	cometWatcher : null,

	cometRestart : null,

	

	/**

	 * Main worker function

	 * Example request:

	 * 

			function handleCallback (response) {

				if(response.statusCode === 200) {

					document.getElementById('testContentDiv').innerHTML = response.contentText;

				} else {

					document.getElementById('testContentDiv').innerHTML = response.error;

				}

			}

				 

			function bareMinumumRequest () {

				var requestData = {

					"url" : "pspTest.html",

					"callback" : handleCallback

				};

				rpc.request(requestData);

			};

			

	 * @param {Object} inputParams

	 */

	request : function (inputParams) {

		var currTimestamp = rpc.createTimestamp();

		var requestId = (typeof inputParams.id === "string") ? inputParams.id : "";

		var urlString = (typeof inputParams.url === "string") ? inputParams.url : "";

		var paramArr = (typeof inputParams.params === "object") ? inputParams.params : [] ;

		var paramCount = paramArr.length;

		var requestMethod = (typeof inputParams.method === "string") ? inputParams.method : "get";

		var callback = (typeof inputParams.callback === "function") ? inputParams.callback : null;

		var isAsync  = (typeof inputParams.async === "boolean") ? inputParams.async : this.async ;

		var preventCache  = (typeof inputParams.preventCache === "boolean") ? inputParams.preventCache : this.preventCaching ;

		var useComet  = (typeof inputParams.comet === "boolean") ? inputParams.comet : false ;

		var restart = (typeof inputParams.restart === "function") ? inputParams.restart : null ;

		

		//build param string

		var paramString = "";

		for(i=0; i<paramCount; i=i+1) {

			var currParam = paramArr[i];

			if(i !== 0) { paramString += "&"; } else {  if(requestMethod === "get") { paramString = "?" } else { paramString = "" } }

			paramString += currParam[0] + "=" + currParam[1];

		}

		if(paramCount === 0 && preventCache && requestMethod !== "post") {

			paramString = "?xtsx=" + currTimestamp;

		} else if (preventCache && requestMethod !== "post") {

			paramString += "&xtsx=" + currTimestamp;

		}

		

		var fullUrl = urlString + paramString; 

		if(useComet) {

			this.makeCometRequest(requestId, urlString, paramString, requestMethod, isAsync, callback, restart);

		} else {

			this.makeRequest(requestId, urlString, paramString, requestMethod, isAsync, callback);

		}

		

	},

	

	

	/**

	 * 

	 * @param {Object} requestId

	 * @param {Object} url

	 * @param {Object} params

	 * @param {Object} method

	 * @param {Object} async

	 * @param {Object} callback

	 */

	makeRequest : function (requestId, url, params, method, async, callback) {

		var requestHandler = null;

		var http_request = this.createRequestObject(false);



		requestHandler = function() {

			//console.debug(http_request);

			

			if(http_request.readyState <= 4) {

				switch(http_request.readyState) {

					case 0 :

						currState = rpc.connState[0];

						//debug.setStatusText(rpc.connState[0]);

						break;

					case 1 :

						currState = rpc.connState[1];

						//debug.setStatusText(rpc.connState[1]);

						break;

					case 2 :

						currState = rpc.connState[2];

						//debug.setStatusText(rpc.connState[2]);

						break;

					case 3 :

						currState = rpc.connState[3];

						//debug.setStatusText(rpc.connState[3]);

						break;

					case 4 :			

						//debug.setStatusText((http_request.status) + ' - ' + rpc.connState[4]);

						rpc.sendResultsToHandler(requestId, http_request,callback);

						break;

					default :

						//debug.setStatusText(http_request.status + ' - ' + rpc.connState[5]);

						currState = rpc.connState[5];

						break;

				}

			}						

		};

		



		http_request.onreadystatechange = requestHandler;

		if(method === "get") {

			http_request.open('GET', url + params, async);

			http_request.send(null);

		} else {

			http_request.open('POST', url, async);

			http_request.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");

			http_request.send(params);		

			

		}

	},

	

	checkCometConnection : function() {

		//alert(rpc.cometHttpRequest.contentWindow.document.body);

		if(rpc.cometHttpRequest.contentWindow.document.body !== null) {

			rpc.cometRestart();

		} else {

			rpc.cometWatcher = setTimeout("rpc.checkCometConnection()", 2000);	

		}

	},

	

	makeCometRequest : function (requestId, url, params, method, async, callback, restart) {

		var requestHandler = null;

		var http_request = this.createRequestObject(true);

		

		if (browser.name === "IE") { 

				// set the iframe up to call the server for data



				var ifrDiv = http_request.createElement("div");

				http_request.parentWindow.callback = callback;

				http_request.parentWindow.restart = restart;



				ifrDiv = http_request.createElement('iframe');

				ifrDiv.src = common.contextPath + '/' + url + params;

				http_request.appendChild(ifrDiv);

				//ifrDiv.contentWindow.onload = function() { restart() };	



				rpc.cometRestart = function() { restart() };

				rpc.cometHttpRequest = ifrDiv;

				rpc.checkCometConnection();			

		} else {

			requestHandler = function() {

				//document.getElementById('test').innerHTML += "State:" + http_request.readyState + " ";

				if(http_request.readyState <= 4) {

					switch(http_request.readyState) {

						case 0 :

							currState = rpc.connState[0];

							//debug.setStatusText(rpc.connState[0]);

							break;

						case 1 :

							currState = rpc.connState[1];

							//debug.setStatusText(rpc.connState[1]);

							break;

						case 2 :

							currState = rpc.connState[2];

							//debug.setStatusText(rpc.connState[2]);

							break;

						case 3 :

							currState = rpc.connState[3];

							//debug.setStatusText(rpc.connState[3]);

							//if(typeof http_request.readyState !== "undefined") {

								rpc.sendResultsToHandler(requestId, http_request, callback, "error");

							//}

							break;

						case 4 :			

							//debug.setStatusText((http_request.status) + ' - ' + rpc.connState[4]);

							rpc.sendResultsToHandler(requestId, http_request, restart, "error");

							break;

						default :

							//debug.setStatusText(http_request.status + ' - ' + rpc.connState[5]);

							currState = rpc.connState[5];

							break;

					}

				}						

			};

			

	

			http_request.onreadystatechange = requestHandler;			

			if(method === "get") {

				http_request.open('GET', url + params, async);

				http_request.setRequestHeader("Content-Type","multipart/x-mixed-replace");

				http_request.send(null);

				

			} else {

				http_request.open('POST', url, async);

				http_request.setRequestHeader("Content-Type","multipart/x-mixed-replace");

				http_request.send(params);		

				

			}

		}

	},	

	

	/**

	 * 

	 * @param {Object} requestId

	 * @param {Object} http_request

	 * @param {Object} callback

	 * @param {Object} errorStr

	 */

	sendResultsToHandler : function(requestId, http_request, callback, errorStr) { 

		var state = http_request.readyState;

		var content_type = http_request.getResponseHeader('Content-Type');

		var response = [ {

				"statusCode" : 0,

				"error" : null,

				"contentText" : "",

				"contentXml" : "" ,

				"contentType" : "",

				"isJson" : false}

			];



		//build response object

		response.statusCode = (typeof http_request.status !== "unknown") ? http_request.status : 200;

		response.contentText = (typeof http_request.responseText !== "unknown") ? http_request.responseText : '';

		response.contentType = (typeof content_type !== "unknown") ? content_type : '';

		response.isJson =(typeof content_type !== "unknown") ? (content_type.indexOf('application/json') >= 0) : false;

		response.contentXml = http_request.responseXML;

		callAfterRequestDone = function() {rpc.handleResponse(requestId, response, callback)};

		window.setTimeout(callAfterRequestDone, 10);

	},

		

	/**

	 * 

	 * @param {Object} requestId

	 * @param {Object} response

	 * @param {Object} callback

	 */

	handleResponse : function(requestId, response, callback) {

		if(requestId !== "") {

			window[requestId] = null;

		}

		//document.getElementById('test').innerHTML += "SC: " + response.statusCode + " ";

		switch(response.statusCode) {

			//handle redirect

			case 302:

				// not perfect but, better -- 

				// a redirect is most likely an attempt to reauthenticate, redirect to cas

				window.location = getCasReloginUrl();

				break;

			//handle any error codes

			case 404:

				response.error = "Page not found. (404)";

				callback(response);

				break;



			case 405:

				response.error = "invalid HTTP request error. (405)";

				callback(response);

				break;



			case 500:

				response.error = "There was a server error.(500)";

				callback(response);

				break;



			case 501:

				response.error = "Method not implimented.(501)";

				callback(response);

				break;



			// handle correct response

			case 200:

				//debug.append("var response = [" + response.contentText + "];");

				if(requestId !== "") {

					window[requestId] = response;

				}

				if(callback !== null) {

					callback(response);

				}

				break;



			// catch any unkown error that may occur				

			default :

				response.error = "There was an unknown error.(" + response.statusCode + ")";

				callback(response);

				break;

				

		}		

	},

	

	/**

	 * 

	 */

	createTimestamp : function () {

		currentDate = new Date();

		return currentDate.getUTCDay() + '' + currentDate.getUTCHours() + '' + currentDate.getUTCMonth() + '' + currentDate.getUTCMinutes() + '' +currentDate.getUTCSeconds() + '' + currentDate.getUTCMilliseconds();

	},

	

	/**

	 * function to handle making a new http request ojbect

	 */

	createRequestObject : function(useComet) {



		var http_request = false;

		if (window.XMLHttpRequest) { // Mozilla, Safari,...

			//debug.append('Mozilla HTTP request method');

			http_request = new XMLHttpRequest();

			if (http_request.overrideMimeType) {

				http_request.overrideMimeType('text/xml');

			}

		} else if (window.ActiveXObject) { // IE

			if(useComet) {

				var http_request = null;

				http_request = new ActiveXObject("htmlfile"); 



				http_request.open();

				http_request.write("<html>");

				http_request.write("</html>");

				http_request.close();



				rpc.cometHttpRequest = http_request;

				

			} else {		

				try {

					http_request = new ActiveXObject("Msxml2.XMLHTTP");

				} catch (e) {

				try {

					http_request = new ActiveXObject("Microsoft.XMLHTTP");

				} catch (e) {}

					http_request = false;

				}

			}

		}

		if (!http_request) {

			//debug.append('Cannot create XMLHTTP instance');

			http_request = false;

		}	

		//http_request.multipart = true;

		return http_request;

	}	

	



};