var jsonRPC = function() {
	var _sUri           = "";
	var _sCharset       = "utf-8";
	var _aMethods       = [];
	var _xmlHttpRequest = {};
	
    try { _xmlHttpRequest = new window.XMLHttpRequest(); } 
    catch(e) {
        try { _xmlHttpRequest = new window.ActiveXObject("Msxml2.XMLHTTP"); } 
        catch(e) {
            try { _xmlHttpRequest = new window.ActiveXObject("Microsoft.XMLHTTP"); } 
            catch(e) {return false;}
        }
    }
	
	this.setUri      = function(s) { var _s = _sUri; if (s) _sUri = s; return _s; }
	this.setCharset  = function(s) { var _s = _sCharset; if (s) _sCharset = s; return _s; }
	this.addMethod   = function(s) { if (s) _aMethods[_aMethods.length] = s; }
	this.sendRequest = function(request) {
		request = request.toJSONString();
		_xmlHttpRequest.open("POST", _sUri, true);
		_xmlHttpRequest.onreadystatechange = function() {
			if (_xmlHttpRequest.readyState == 4) {
		    	if (_xmlHttpRequest.status == 200) {
		          	response = _xmlHttpRequest.responseText.parseJSON();
		          	for(var i = 0, count = _aMethods.length; i < count; i ++) {
		          		if (response.method == _aMethods[i]) {
							eval(response.method + "(" + response.params.toJSONString() + ")");
		          			break;
			          	}
		          	}
		      	} 
		 	}
		}
	    _xmlHttpRequest.setRequestHeader("Content-type", "text/plain; charset=" + _sCharset);
	    _xmlHttpRequest.setRequestHeader("Content-length", request.length);
		_xmlHttpRequest.send(request);
	}
}

