iCM = function() {
	/* === Private Area === */
	
	// Fetch the appropriate XML Http Object for the current browser
	function GetAjaxObject() {
		xmlhttp = null;
		if (window.XMLHttpRequest) {
			xmlhttp = new XMLHttpRequest();
		} else if (window.ActiveXObject) {
			xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
		}
		return xmlhttp;
	}
	
	// Try and retrieve where the page was launched from
	function GetURL(arguments, isget) { 
		var regex = /(.*)\/.*?$/;
		var loc = location.href.match(regex)[1] + '/';
		if (arguments.url)
		{
			loc += arguments.url;
			if (isget) {
				loc += '?' + arguments.method;
				for (key in arguments.params) {
					loc += '&' + key + '=' + encodeURI(arguments.params[key]);
				}
			}
		}
		return loc;
	} 

	// Make an AJAX Call
	function MakeCall(method, target, url, content, okcallback, failcallback, rpccall) {
		var x = GetAjaxObject();
		x.onreadystatechange = function() {
			if (x.readyState == 4) {
				if (x.status == 200)
				{
					if (rpccall)
					{
						response = x.responseText == "" ? {} : Ext.util.JSON.decode(x.responseText);
						if (okcallback) {
							okcallback(target, response);
						}
					}
					else 
					{
						if (x.responseText && x.responseText.length > 0)
						{ 
							response = Ext.util.JSON.decode(x.responseText);
							for (respidx=0;respidx<response.length;respidx++) {
								area = response[respidx];
								for(key in area)
								{
									areaId = key;
									areaElem = Ext.get(areaId);
									if (areaElem) {
										areaElem.dom.innerHTML = area[key];
										RewriteFrameLinks(areaElem.dom);
									}
									if (okcallback) {
										okcallback(key, area[key]);
									}
								}
							}
						}
						else if (failcallback)
						{
							failcallback('no response');
						}
					}
				}
				else if (failcallback) 
				{
					failcallback(x.status);
				}
			}
		};
		x.open(method, url, true);
		if (rpccall) {
			x.setRequestHeader("Content-Type", "application/json");
			x.setRequestHeader("Accept", "application/json");
			if (method == "POST") {
				content = Ext.util.JSON.encode(content);
				x.setRequestHeader("Content-Length", content.length);
				x.send(content);
			}
			else x.send(content);
		}
		else 
		{
			if (method == "POST") {
				x.setRequestHeader("Content-Length", content.length);
				x.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
				x.setRequestHeader("Connection", "close");
			}
			x.send(content);
		}
	}

	function RewriteFrameLinks(element) {
		var links = element.getElementsByTagName('a');
		for (ilink=0;ilink<links.length;ilink++) {
			var link = links[ilink];
			if (link.getAttribute("href") && (link.getAttribute("rel") == "external") || link.getAttribute("rel") == "parent") {
				link.target = "_top";
			}
		}
	}

	/* === Public Area === */
	return {
		// Ascertain if cookie exists
		CookieExists: function(name) {
			var nameEQ = name + "=";
			var cookies = document.cookie.split(';');
			for (var cookieidx=0; cookieidx<cookies.length;cookieidx++) {
				var cookie = cookies[cookieidx];
				if (cookie.indexOf(nameEQ) >= 0) return true;
			}
			return false;
		},
		
		// Make an AJAX Get Request
		Get: function(request, okcallback, failcallback) {
			url = request.url + '?__ajax=';
			for (i=0;i<request.target.length;i++) {
				if (i>0) url += ',';
				url += request.target[i];
			}
			for (var key in request.arguments) {
				if (request.arguments[key]) {
					url += '&' + key + '=' + escape(request.arguments[key]);
				}
			}
			this.MakeGetCall(request.target, url, okcallback, failcallback);
		},
		
		// Make an AJAX post request
		FormPostRequest: function(targetId, url, form, okcallback, failcallback) {
			params = "";
			inputs = Ext.get(targetId).query('input');
			for (i=0; i<inputs.length; i++) {
				if (params != '')
					params += '&';
				params += inputs[i].name + '=' + escape(encodeURI(inputs[i].value));
			}
			this.MakePostCall(targetId, url, params, okcallback, failcallback);
		},

		// Set a cookie's value
		SetCookie: function(name, value, days, hours, minutes) {
			var expire = new Date();
			var today = new Date();
			var ticks = (minutes * 60 * 1000) +
									(hours * 60 * 60 * 1000) +
									(days * 24 * 60 * 60 * 1000);
			expire.setTime(today.getTime() + ticks);
			document.cookie = name + '=' + escape(value) + ';expires=' + expire.toGMTString();
		},

		// Make an AJAX call via the 'get' mechanism
		MakeGetCall: function(targets, url, okcallback, failcallback) {
			MakeCall("GET", targets, url, null, okcallback, failcallback, false);
		},
		
		MakePostCall: function(targets, url, params, okcallback, failcallback) {
			MakeCall("POST", targets, url, params, okcallback, failcallback, false);
		},

		// Make an RPC Call via the 'get' mechanism
		MakeGetRPCCall: function(arguments, okcallback, failcallback, targets) {
			url = GetURL(arguments, true);
			MakeCall("GET", targets, url, null, okcallback, failcallback, true);
		},

		// Make an RPC Call via the 'post' mechanism
		MakePostRPCCall: function(arguments, okcallback, failcallback, targets) {
			url = GetURL(arguments, false);
			MakeCall("POST", targets, url, arguments, okcallback, failcallback, true);
		},
		
		// Prepare a new request. Request will contain target areas to update and arguments for call
		NewRequest: function(target) {
			req = {};
			req.target = [];
			req.target.push(target);
			req.arguments = {};
			
			return this.SetHREF(req, location.href);
		},

		// Populate request with contents of given href		
		SetHREF: function(request, href) {
			idx = href.indexOf('?');
			if (idx > 0) {
				// Take everything after the '?' as arguments to the call
				href = href.substring(idx + 1);
				args = href.split('&');
				for (iarg=0;iarg<args.length;iarg++) {
					var arg = args[iarg];
					if (arg.indexOf('=') > 0) {
						argparts = arg.split('=');
						argkey = argparts[0];
						argval = argparts[1];
						req.arguments[argkey] = argval;
					}
				}
				
				// Everything before the '?' is the destination Url
				req.url = location.href.substring(0, idx);
			}
			return req;
		}
	}
}();

iCMRPC = function()
{
	return {
	}
}();

iCM.RPC = iCMRPC;

