if((typeof Prototype=='undefined') || 
   (typeof Element == 'undefined') || 
   (typeof Element.Methods=='undefined') ) 
{
   throw("Ajax.JsonRpc requires the Prototype JavaScript Framework");
}

Prototype.debug = function(s){
	if (console && console.debug){
		console.debug(s);
	} else {
		alert(s);
	}
}

Ajax.JsonRpc = Class.create(Ajax.Request, {
	initialize: function($super, url, className, methodName, parameters, options) {
		var requestParameters = {
			json: Object.toJSON({
				className: className,
				methodName: methodName,
				params: parameters
			})
		};
		options.parameters = requestParameters;
		options.onSuccess = this.onSuccess.bind(this);
		options.onFailure = this.onFailure.bind(this);
		$super(url, options);
		this.options.callback = options.callback;
	},
	onSuccess: function(transport) {
		var methodReturn = transport.responseText.evalJSON();
		if (methodReturn && methodReturn.TYPE) {
			if (methodReturn.TYPE.toLowerCase() == "success") {

				(this.options.callback || Prototype.emptyFunction)((methodReturn.VALUE || null));
			} else if (methodReturn.TYPE.toLowerCase() == "failure") {
				(this.options.errback || this.errback)(transport, methodReturn.MESSAGE || null);
			} else { //invalid methodReturn packet: this treated as a transport-level failure, not an errback/handled exception. 
				this.onFailure(transport, "Invalid JSON-RPC packet");
			}
		} else { //failure, json did not eval
			this.onFailure(transport, "Invalid JSON-RPC packet");
		}
	},
	
	/**
	 * Default handler for when underlying XHR triggers a 
	 * status of failure (@see Ajax.Request / Ajax.Response)
	 */
	onFailure: function(transport, message) {
		Prototype.debug("jsonrpc failed with: " + message + "\n\nResponseText: " + transport.responseText);
	},
	
	/**
	 * Default handler for when a methodReturn Packet has a 
	 * trapped application-level error (or exception) in it. i.e: 
	 * MethodReturnPacket.type == "failure"
	 */
	errback: function(transport, methodReturn) {
		Prototype.debug("jsonrpc found an exception:\n" + methodReturn.message + "\n\nResponseText: " + transport.responseText);
	}
});

