(function($){
	$.extend({
		/**
		 * The main rpc function.
		 * @param {String} url	The url to the jsonrpc service
		 * @param {Function} fn	The callback to execute when the call is finished
		 * 
		 * TODO: Is this needed now since the XMLRPC part of it is removed? 
		 * Maybe just go with the standard jQuery version with a wrapper function for extra data handling.
		 */
		rpc: function(url,fn){
			var opt = $.extend({}, $.rpc.settings, url);
			opt.data = $.rpc.getCall(opt.method,opt.data);
			opt.error = function( a, b, c ) {
				alert( "Error status: " + a.status + ", error msg: " + c + ", data: " + opt.data );
			};
			fn = fn || opt.callback || null;
			if(fn) {
				if(opt.success){
					var succ = opt.success;
					opt.success = function(data,status){
						// Process data to return an array of values instead (more JSON like)
						var dta = $.rpc.processResponse(data);

						// Check to see if the rpc returned an error and if so, don't continue.
						if(dta.error && $.rpc.error) $.rpc.error(dta, status);
						else {
							// Apply the object callback
							succ.apply(this,[dta,status]);
							
							// Apply general success function
							if($.rpc.success) $.rpc.success();
							
							// Apply the function callback
							fn.apply(this, [dta, status]);
						}
						
						// Apply the after callback
						if($.rpc.after) $.rpc.after();
					};
				}
				else {
					opt.success = function(data, status){
						// Process data to return an array of values instead (more JSON like)
						var dta = $.rpc.processResponse(data);

						// Check to see if the rpc returned an error and if so, don't continue.
						if(dta.error && $.rpc.error) $.rpc.error(dta, status);
						else {
							// Apply general success function
							if($.rpc.success) $.rpc.success(dta, status);
	
							// Apply the function callback
							fn.apply(this, [dta, status]);
						}

						// Apply the after callback
						if($.rpc.after) $.rpc.after();
					};
				}
			}
			// No callback was defined but we still need to execute general callbacks.
			else {
				opt.success = function(data, status){
					// Process data to return an array of values instead (more JSON like)
					var dta = $.rpc.processResponse(data);

					// Check to see if the rpc returned an error and if so, don't continue.
					if(dta.error && $.rpc.error) $.rpc.error(dta, status);

					// Apply general success function
					else if($.rpc.success) $.rpc.success(dta, status);

					// Apply the after callback
					if($.rpc.after) $.rpc.after();
				};
			}
			
			// Execute before send function
			if($.rpc.before) $.rpc.before();

			$.ajax(opt);
			return this;
		}
	});
	
	$.extend($.rpc,{
	
		methods: {},
		list: [],
		fetched: false,

		/**
		 * Returns an rpc request string based on a method name and a data array.
		 */
		getCall: function(method, params){
			var ret = { method: method };

			if(params) ret.data = params;
			
			// Adding some metadata that some server-side functions need.
			ret.meta = {
				currentHash: document.location.hash
			};
			return jQuery.toJSON(ret);
		},
		
		processResponse: function(data, noEval){
			// Need to check if there's any css in the content since webkit doesn't handle dynamically added css well.
			// TODO: Adding css twice in some browsers?.
			if(jQuery.browser.safari && data.match(/\<style[^\>]*?\>/gi)){
				var matches = data.replace(/\\n/gi,'\n').replace(/\\/gi,'').match(/\<style[^\>]*?\>([^\<])*?\<\/style\>/gi);
				for(var i = 0; i < matches.length; i++){
					jQuery(matches[i]).appendTo("head");
				}
				data = data.replace(/\<style[^\>]*?\>([^\<])*?\<\\\/style\>/gi, "");
			}
			
			// TODO: Eval is evil...
			if(!noEval) eval("var output = (" + data + ")");
			return output;
		},
		
		/**
		 * Initial settings for the rpc/ajax calls.
		 */
		settings: {
			url: "UNDEFINED",
			type: "POST",
			autorunScripts: true
		}
	});
})(jQuery);