//<!--
//# Written by Russell Moffitt, NOAA
//# Modified Aug 2006
//# License: GPL
//-->

/*
JSON-RPC functions require the MochiKit javascript library to handle JSON-RPC
requests with the XmlHttpRequest object.  Base.js and Async.js must be
imported in the HTML code before this script.  The rest of MochiKit
is not used at the moment, and the RPC code may be separated out from
MochiKit at some future time.
*/

/*
The server is sent a JSON-RPC formatted request with structured-hierarchical
parameters destined for a named server-side method function.  The server should return
a structured JSON response with object properties representing map info and image urls.
*/

//////////////////////////////////
// JSON-RPC Request Handlers
//////////////////////////////////

function sendJsonRpc(url, method, /*optional*/ params, /*optional*/ callback, /*optional*/ id) {
	// ARGUMENTS
	// url (server application)
	// method (string with remote method name)
	// params (array of javascript objects to be converted to JSON)
	// callback (function to be called with response object as only parameter. use a partial here to enable other arguments)
	// RETURNS: array of request object and json request id (string or object)
	
	var reqObj = {};
	reqObj.method = method;
	reqObj.params = (typeof(params)!='undefined' || params != null) ? params : [];
	// Server will not respond if id is null, so only explicity pass null if you want this behavior.
	// Leaving off id will create a random number for the id
	reqObj.id = (typeof(id)!='undefined' && null!=id)? id : Math.floor(Math.random()*900000)+100000 + '' + Date.parse(Date()); // random num 100k-999k + epoch seconds
	// Convert reqObj to JSON string
	var reqStr = MochiKit.Base.serializeJSON(reqObj);
	reqStr = "request=" + reqStr;
	var req = MochiKit.Async.getXMLHttpRequest();
	
	req.open("post", url);
	req.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
	
	function failedJsonRpc(error) {
		var msg = "Remote Procedure Call failed"
		msg += "\n\n** " + error.name + ": " + error.message;
		msg += "\n\nAlthough I have attempted to log this error,";
		msg += "\nplease contact the system administrator."
		alert(msg);
		//alert(error);
		return error;
	}
	function readJsonRpc(resObj) {

		var result = resObj.result;
		var error = resObj.error;
		var id = resObj.id;
		if (error != null) {
			var msg = "Remote Procedure Call returned error"
			msg += "\n\n** " + error.name + ": " + error.msg;
			msg += "\n\nAlthough I have attempted to log this error,";
			msg += "\nplease contact the system administrator."
			alert(msg);
			result = new MochiKit.Async.GenericError(msg);
		}
		return result;
	}
	
	// d is a MochiKit.Async.Deferred object
	var d = MochiKit.Async.sendXMLHttpRequest(req, reqStr);

	// convert JSON to javascript object
	if (callback) {

		// only need to handle response if there's a callback to pass it to
		d.addCallbacks(MochiKit.Async.evalJSONRequest, failedJsonRpc);
		d.addCallback(readJsonRpc);
		// pass result object on to callback only if the JSON-RPC response did not indicate error
		d.addCallback(callback);
	}

	return [req, reqObj.id];
}
