function Callback(rpcObject, targetId, onLoad) {
	this.rpcObject = rpcObject;
	this.targetId = targetId;
	this.onLoad = onLoad;
}

Callback.prototype.onError = function(errorCode, params) {
}

Callback.prototype.execute = function() {
	if (this.rpcObject && this.rpcObject.http_request && this.rpcObject.http_request.readyState) {
	    if (this.rpcObject.http_request.readyState==4) {
		    if (this.onPostLoad) {
		    	this.onPostLoad();
			}
	        if (this.rpcObject.http_request.status==200) {
				if (this.targetId) {
					var obj = document.getElementById(this.targetId);
					if (obj) {
					    obj.innerHTML=this.rpcObject.http_request.responseText;
						var heads = document.getElementsByTagName("head");
						if (heads && heads.length>0) {
							var cssTags = obj.getElementsByTagName("style");
							if (cssTags) {
								for(var no=0;no<cssTags.length;no++){
									heads[0].appendChild(cssTags[no]);
								}
							}
							var scriptTags = obj.getElementsByTagName("script");
							if (scriptTags) {
								for(var no=0;no<scriptTags.length;no++){
									heads[0].appendChild(scriptTags[no]);
								}
							}
						}
					}
				    else if (this.onError) {
				    	this.onError("targetError", [{"name":"target","value":this.targetId}]);
					}
				}
				else {
				    eval(this.rpcObject.http_request.responseText);
				}
			    if (this.onLoad) {
			    	this.onLoad();
				}
	        }
		    else if (this.onError) {
		    	this.onError("httpRequestStatusError", [{"name":"status","value":this.rpcObject.http_request.status}]);
			}
	    }
	    else if (this.onPreLoad) {
	    	this.onPreLoad();
		}
		
	}
    else if (this.onError) {
		if (!this.rpcObject) {
	    	this.onError("rpcObjectError");
		}
		else if (!this.rpcObject.http_request) {
	    	this.onError("httpRequestError");
		}
	}
}

function RPCClient( name, method, async ) {
	this.name = name;
	if (method!=undefined) {
		this.method = method;
	}
	else {
		this.method = "POST";
	}
	if (async!=undefined) {
		this.async = async;
	}
	else {
		this.async = true;
	}
    this.http_request = false;

    if (window.XMLHttpRequest) { // Mozilla, Safari,...
        this.http_request = new XMLHttpRequest();
        if (this.http_request.overrideMimeType) {
            this.http_request.overrideMimeType('text/xml');
        }
    }
    else if (window.ActiveXObject) { // IE
        try {
            this.http_request = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            try {
                this.http_request = new ActiveXObject("Microsoft.XMLHTTP");
            } 
            catch (e) {
            }
        }
    }
}

RPCClient.prototype.execute = function ( callback, url, params ) {
    if (!this.http_request) {
        return false;
    }
	if (this.http_request.readyState>0) {
		this.http_request.abort();
		/*
		if (this.http_request.readyState==4) {
			this.http_request.abort();
		}
		else {
			return true;
		}
		*/
	}
	if (callback.execute) {
	    this.http_request.onreadystatechange = function(){callback.execute();};
	}
	else {
	    this.http_request.onreadystatechange = callback;
	}
	var nc = (new Date()).getTime()+Math.floor(1000*Math.random());
	var prms = "nc="+(new Date()).getTime()+Math.floor(1000*Math.random());
    if (params && params.length>0) {
	    for (var i=0;i<params.length;i++) {
			if (typeof encodeURIComponent == "function") {
	    		prms += "&"+params[i].name+"="+encodeURIComponent(params[i].value);
			}
			else {
	    		prms += "&"+params[i].name+"="+escape(params[i].value);
			}
	    }
	}
	if (this.method=="POST") {
		this.http_request.open(this.method, url, this.async);
		this.http_request.setRequestHeader("Content-type","application/x-www-form-urlencoded; charset=utf-8");
		this.http_request.setRequestHeader("Accept-Charset", "utf-8");
		this.http_request.setRequestHeader("Content-length", prms.length); 
	    this.http_request.send(prms);
	}
	else {
		if (url.indexOf("?")!=-1) {
		    this.http_request.open(this.method, url+"&"+prms, this.async);
		}
		else {
		    this.http_request.open(this.method, url+"?"+prms, this.async);
		}
	    this.http_request.send(null);
	}
}
