function RPC(remoteModel,remoteMethod,listener,method,parameters){
	rpc = new Call
	rpc.listener = listener;
	rpc.onComplete = function (){
		if(this.listener[method]){
			this.listener[method](this.retval);
		}else{
			alert(method);
		}
	}
	if(parameters){
		rpc.doCallA(remoteModel,remoteMethod,parameters);
	}else{
		rpc.doCall(remoteModel,remoteMethod);
	}
}

function RequestPoolObj(){
	this.req = 0;
	this.uniqueHandler = reponse_handler;
	this.state = 0;
	this.retObj = 0;
}

var requestPoolSize = 4;

var requestPool = Array(requestPoolSize);

for(var i = 0; i<requestPoolSize; i++){
	requestPool[i] = new RequestPoolObj();
}

function Call(){
	this.retval = 0;
	this.onComplete = 0;		
	this.reuse = 0;
}

function doCall(obj,method){
	if(arguments.length<2){
		return;
	}
	var url = "/javascriptInterface.php"
	post = "";
	post += "object="+escape(obj).replace("+","%2B")+"&";
	post += "method="+escape(method).replace("+","%2B");
	if(arguments.length>2){
		post+="&";
	}
	for (var i = 2;i < arguments.length;i++){
		
		post += "arg"+i+"="+escape(arguments[i]).replace("+","%2B");
		if(i+1 < arguments.length)post+="&";
	}
	loadXMLDoc(url,this,post);
}

function doCallA(obj,method,param){
	if(arguments.length<2){
		return;
	}
	var url = "/javascriptInterface.php"
	post = "";
	post += "object="+escape(obj).replace("+","%2B")+"&";
	post += "method="+escape(method).replace("+","%2B");
	if(arguments.length>2){
		post+="&";
	}
	if(param){
		for (var i = 0;i < param.length;i++){
			post += "arg"+i+"="+escape(param[i]).replace("+","%2B");
			if(i+1 < param.length)post+="&";
		}
	}
	
	loadXMLDoc(url,this,post);
}

Call.prototype.doCall = doCall;
Call.prototype.doCallA = doCallA;

function find_by_url(){
	loadXMLDoc(buildRequest("Product","find_all"));
}

function reponse_handler(){
	if (this.req.readyState == 4) {
		this.state = 0
        if (this.req.status == 200) {
			if(this.req.responseXML){
				
				response  = this.req.responseXML.documentElement;
				if(!response){
					alert(this.req.responseText);
					return;
				}			
				this.retObj.retval = parseXML(response,null);
				this.retObj.onComplete();	
				d = new Date();
				//alert(d.getTime() - this.startTime);
				//alert(this.req.responseText);
			}else{
				alert(this.req.responseText);
			}
        } else {
            //alert("There was a problem retrieving the XML data:\n" + this.req.statusText);
        }
    }
}

function parseXML(d,obj){
	var x = d.childNodes;
	switch(d.nodeName){
		case 'response':
			for(i=0; i<x.length; i++){
				if(x[i].nodeType==1){
					return parseXML(x[i],null);
				}
			}
		break;
		case 'scaler':
			return d.getAttribute('value');
		break;
		case 'json':
			eval('tmp = (' + x[0].nodeValue + ')');
			return tmp;
		break;
		case 'array':{
			var  tmp = new Array();
			for(var i=0; i<x.length; i++){
				if(x[i].nodeType==1){
					tmp[tmp.length] = parseXML(x[i],null);
				}
			}
			return tmp;
			break;
		}
		case 'arrayitem':{
			for(i=0; i<x.length; i++){
				if(x[i].nodeType==1){
					return parseXML(x[i],null);
				}
			}
			break;
		}
		case 'php_object':
			eval ('var  tmp = new Object()');
			for(i=0; i<x.length; i++){
				if(x[i].nodeType==1){
					parseXML(x[i],tmp);
				}
			}
			return tmp;
			break;
		case 'php_object_attribute':
			for(i=0; i<x.length; i++){
				if(x[i].nodeType==1){
					eval('obj.'+d.getAttribute('name') +' = parseXML(x[i],null)');
					return "";
				}
			}
		break;
	}
	return "";
}

function loadXMLDoc(url,retobj,post) {
	var d = new Date();
	for(var i=0;i<requestPool.length;i++){
		if (requestPool[i].state==0){
			break;
		}else{
			if((retobj == requestPool[i].retObj) && (retobj.reuse == true)){
				break;
			}
		}
	}
	if(requestPool.length==i){
		//alert("too many open requests");
		return;
	}
    // branch for native XMLHttpRequest object
	if(requestPool[i].state){
		requestPool[i].req.abort();
		requestPool[i].state = 0;
	}
    if (window.XMLHttpRequest) {
        requestPool[i].req = new XMLHttpRequest();
		requestPool[i].uniqueHandler = reponse_handler;
        eval ('requestPool[i].req.onreadystatechange = function() { requestPool['+i+'].uniqueHandler() }');
        requestPool[i].req.open("POST", url, true);
        requestPool[i].req.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=utf-8');
        requestPool[i].req.send(post);
   
        requestPool[i].startTime = d.getTime();
		requestPool[i].state = 1;
		requestPool[i].retObj = retobj;
    // branch for IE/Windows ActiveX version
    } else if (window.ActiveXObject) {
        requestPool[i].req = new ActiveXObject("Microsoft.XMLHTTP");
        if (requestPool[i].req) {
			requestPool[i].uniqueHandler = reponse_handler;
            eval ('requestPool[i].req.onreadystatechange = function() { requestPool['+i+'].uniqueHandler() }');
			requestPool[i].req.open("POST", url, true);
			requestPool[i].req.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=utf-8');
        	requestPool[i].req.send(post);
			requestPool[i].state = 1;
			requestPool[i].startTime = d.getTime();
			requestPool[i].retObj = retobj;
        }
    }
}
