/*
    Copyright (C) 2008  Ivo Toby, Internet Voor Ondernemers, http://www.i-v-o.nl / http://syntacticsugar.nl 

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

	Crudder Version : 0.50b
 */

/**
* @author Ivo Toby <ivo@i-v-o.nl> 
* @copyright Internet Voor Ondernemers 2008
* @package WPS
* @version $Id: rpc.js,v 2.61 2006/7/12
**/ 
	var crudderRPC = Class.create({
		initialize : function(crudderConfig, rpcPath){
			this.instID = 'rpc.' + parseInt(Math.random()*1000000);
			this.crudderConfig = crudderConfig;
			this.URI = rpcPath;
			this.params = new Array();
			this.rpcArgs = new Array();
			this.reserved = ['action', 'chid', 'xmlReq', 'node', 'rpc'];
			this.qs = '';
			this.xPath = ''
			this.debug = false;
			this.async = true;
			this.waiter = this.dummyWaiter;
			this.unWaiter = this.dummyWaiter;
			this.encoding = 'UTF-8';
			this.callMethod = null;
			this.reqHeader = new Array();
		},

		createCall : function(callBack, pob){
			if (!this.URI) this.URI = this.getURI();
			this.callBack = callBack;
			this.pob = pob;
			this.qs = '&rpc=1&config=' + this.crudderConfig;
			if (this.xPath){
				this.qs += '&node=' + this.xPath;
			}
			$A(this.params).find(
				(function(param){
					this.qs += param
				}).bind(this)
			)
			return true;
		},

		createIframedCall : function(callBack, pob){
			if (!this.URI) this.URI = this.getURI();
			this.callBack = callBack;
			this.pob = pob;
			this.qs = '&rpc=1&config=' + this.crudderConfig;
			if (this.xPath){
				this.qs += '&node=' + this.xPath;
			}
			$A(this.params).find(
				(function(param){
					this.qs += param
				}).bind(this)
			)
			return true;
		},
		
		callIframe : function(){
			if (this.callMethod){
				var method = this.callMethod;
			}else{
				var method = arguments[0];
			}
			var xmlReq = '<command><call>';
			xmlReq +=  '<method>' + method + '</method>';
			// create RPC-arguments from rpcArgs-array;
			$(this.rpcArgs).each(
				(function(arg){
						xmlReq += '<arg>' + arg.key  + '=' +arg.value +  '</arg>';
				}).bind(this)
			);
			// create RPC_arguments from the arguments passed to this function (overrides the args set before doing the call)
			$A(arguments).each(
				(function(arg){
					if (arg != method) 	
						if (this.is_array(arg)){
							$A(arg).each(
								(function (argToo){
									xmlReq += '<arg>' + argToo + '</arg>';
								}).bind(this)
							)
						}else{
							xmlReq += '<arg>' + arg + '</arg>';
						}
				}).bind(this)
			)
			xmlReq += '</call></command>';
	        this.qs += '&xmlReq=' + xmlReq;
	        if ( (this.debug) && (window.location.host =='localhost' || (window.location.host.indexOf('laptop.i-v-o.nl') > -1)) ){
	        	try{
	        		console.log(this.URI + this.qs);
	        	}catch(e){
	        		//alert(this.URI + this.qs);
	        	}
	        }
			var iframe = new Element('iframe', {width:'0',height:'0', frameborder:'0', name:this.instID + '_download', id:this.instID + '_download', src:''});
			$(document.body).insert(iframe);
			iframe.setAttribute('src', this.URI + this.qs)
			this.callBack();
		},
		
		setMethod : function (methodStr){
			this.callMethod = methodStr;
		},

		setCallback : function (callBack){
			this.callBack = callBack;
		},

		setURI : function (URI){
			this.URI = URI;
		},

		/**
		 * Execute the AJAX-call
		 */
		call : function(){
			if (this.callMethod){
				var method = this.callMethod;
			}else{
				var method = arguments[0];
			}
			var xmlReq = '<command><call>';
			xmlReq +=  '<method>' + method + '</method>';
			// create RPC-arguments from rpcArgs-array;
			$(this.rpcArgs).each(
				(function(arg){
						xmlReq += '<arg>' + arg.key  + '=' +arg.value +  '</arg>';
				}).bind(this)
			);
			// create RPC_arguments from the arguments passed to this function (overrides the args set before doing the call)
			$A(arguments).each(
				(function(arg){
					if (arg != method) 	
						if (this.is_array(arg)){
							$A(arg).each(
								(function (argToo){
									xmlReq += '<arg>' + argToo + '</arg>';
								}).bind(this)
							)
						}else{
							xmlReq += '<arg>' + arg + '</arg>';
						}
				}).bind(this)
			)
			xmlReq += '</call></command>';
	        this.qs += '&xmlReq=' + xmlReq;
	        if ( (this.debug) && (window.location.host =='localhost' || (window.location.host.indexOf('laptop.i-v-o.nl') > -1)) ){
	        	try{
	        		console.log(this.URI + this.qs);
	        	}catch(e){
	        		//alert(this.URI + this.qs);
	        	}
	        }
	        if (this.qs.indexOf('undefined') == -1){ // added 20-10-06 => check for "undefined", if there's one; do not call.
		        new Ajax.Request(this.URI, {
					    method: 		'post',
					    parameters:		this.qs,
					    requestHeaders: this.reqHeader,
					    encoding:		this.encoding,
					    onLoading:		this.waiter.bind(this.waiterObj),
					    onLoaded:		this.unWaiter.bind(this.unWaiterObj),
					    asynchronous:	this.async,
			            onException:	this.handleErr.bind(this),
			            onFailure:		this.handleErr.bind(this),
			            onComplete: 	this.callBack.bind(this.pob),
			            myRPC:			this
		                });
		         return true;
		    }
		    return false;
		},
	
		setHeader : function(aKey, aValue){
			this.reqHeader.push(aKey);
			this.reqHeader.push(aValue);
		},
	
		setEncoding : function(aValue){
			this.encoding= aValue;
		},

		setParams : function(anArray){
			this.params = anArray;
		},
	
		execute : function(){
			this.call(arguments);
		},
	
		setNode : function(xPathQuery){
			this.xPath = xPathQuery;
		},
	
		addArgument : function(aKey, aValue){
			this.rpcArgs.push({key:aKey, value:aValue}); 		
		},

		replaceArgument : function(oldArgKey, newArgValue){
		 	$A(this.rpcArgs).each(
		 		function(arg){
		 			if (arg.key == oldArgKey){
		 				arg.value = newArgValue;
		 			}
		 		}
		 	);
		},
	
		hasEmptyArgs : function(){
			for(var i=0;i<this.rpcArgs.length;i++){
				var arg = this.rpcArgs[i];
				if (!arg.value){
					return true;
				}
			}
			return false;
		},
	
		addParam : function(key, value){
			if (this.reserved.indexOf(key) == -1){
				this.params[key] = value;
			}else{
				alert('That keyword is reserved');
			}
		},
	
		attachWaiter : function(waiterFunc, obj){
			this.waiterObj = obj;
			this.waiter = waiterFunc;
		},

		attachUnWaiter : function(unWaiterFunc, obj){
			this.unWaiterObj = obj;
			this.unWaiter = unWaiterFunc;
		},

		handleErr : function(){
				alert(arguments[0] + '/' + arguments[1].message);
		},
		
		getURI : function(){
			var localArr = new String(window.location);
			localArr = localArr.split("&");
			var collectURL = '';
			for (var i=0;i<localArr.length;i++){
				if (i >= 1){
				}else{
					collectURL = localArr[0];
				}
			}
			//collectURL = collectURL);
			if (collectURL.indexOf('#') > -1) collectURL = collectURL.substr(0,collectURL.indexOf('#')); 
			return collectURL + "?";		
		},
		
		is_array:function(a){
			return this.is_object(a) && a.constructor == Array;
		},
		
		is_object : function(a){
			return (a && typeof a == 'object') || this.is_function(a);
		},

		is_function : function(a){
		    return typeof a == 'function';
		},

		dummyWaiter : function(){}
		
	});
