	/**
	 * Class jsonProxy; allows for cross-domain javascript-remoting
	 * you're better off using the authenticatedJsonProxy-class if you do not want bots to spam your site.
	 * 
	 * @author Ivo Toby, ivo@i-v-o.nl www.i-v-o.nl
	 * @version 0.01a
	 * @requires Prototype.js by Sam Stephenson (http://www.prototypejs.org/) and Scriptaculous (http://script.aculo.us/) by Thomas Fuchs and a fairly decent browser 
	 * @constructor initialize
	 * 
	 * THIS CLASS IS GPL, see licence.txt .
	 */
	
	var jsonProxy = Class.create({
		
		/**
		 * Constructor
		 */
		initialize: function(uri){
			this.instID = 'jsonProxy_' + parseInt(Math.random()*1000000); // internal OBJECTID, used as a reference to requested objects (instID is sent to server)
			this.params = $H({});
			this.debug = false;
			this.uri = uri;
		},
		
		doRequest : function(callBack){
			this.callBack = callBack;
			this._doRequest();
		},
		
		_doRequest : function(){
			if ($("script_" + this.instID)){
				// remove in-memory-objects
				window[this.instID] = null; 
			}
			this.params.set('objID', this.instID);
			if (this.uri.indexOf("?") > -1) {
				// URI already has a querystring; split into parts and set it to this.params:
				var baseURI = this.uri.substring(0, this.uri.indexOf("?"));
				var qs = this.uri.substring((this.uri.indexOf("?")+1), this.uri.length);
				var params = qs.split('&');
				$A(params).each(
					(function(param){
						if (param.indexOf('amp;') == 0) param = param.substring(4, param.length); // XML-yfied URI's can contain html-encoded ampersants; remove them to clean up the querystring
						var key = param.split('=')[0];
						var value = param.split('=')[1];
						this.set(key, value);
					}).bind(this)
				)
				this.uri = baseURI;
			}
			var reqURI = this.uri + '?' + this.params.toQueryString() + '&rand=' + parseInt(Math.random()*1000000); 
            if (this.debug) console.log(reqURI);
            if (!$(this.instID)){
	            var script = new Element('script', {
	                src: reqURI,
	                type: 'text/javascript',
	                id :"script_" + this.instID
	            });
	            $$('head')[0].appendChild(script);
            }else{
            	$(this.instID).src = reqURI; 
            }
            // start monitoring
            this.monitorOutput();			
		},
		
		monitorOutput : function(){
			try{
				this.req = eval(this.instID);
				if (!(this.req instanceof Object)) {
					this.timeout = setTimeout(this.monitorOutput.bind(this), 50);
					return;
				}
				this.callBack(this.req);
				setTimeout(this.close.bind(this), 500);
				return;
			}catch(e){
				this.timeout = setTimeout(this.monitorOutput.bind(this), 50);			
			}
		},
		
		set : function(key, value){
			if (key != 'objID'){
				this.params.set(key, value);
			}
		},
		
		close: function(){
			if (!this.debug) $("script_" + this.instID).remove();
		},
		
		debug : function(){
			this.debug = true;
		}
	});