//Copyright EQAL, Inc. 2008

Request.Periodical= new (Class)({
	Extends : Request,
	initaliaze : function(options) {
		 _proxy_jslib_handle(this, 'parent', '', 1, 0)(options);
		this.timer = null;
		this.frequency = this.options.frequency || 1;
	},
	start : function(options) {
		var me = this;
		$log('frequency = '+this.frequency);
		this.timer = this._continue.periodical(1000, this, options);
		this.send(options);
	},
	_continue : function(options) {
		$log('sending again');
		this.cancel();
		this.send(options);
	},
	stop : function() {
		$log('stopping request');
		$clear(this.timer);
		this.cancel();
	} 
});

U.Request = new (Class)({
	Implements : Events,
	initialize : function(config, noKill) {
		this.currentRequest = null;
		this.setConfig(config);
		this.noKill = noKill || false;
		this.uid = $newid();
		this.aborted = false;
	},
	
	setConfig : function(config) {
		this.config = ($type(config) == 'string'? U.Request.Manager(config):config);
		return this;
	},
	sendPeriodical : function(config, onsuccess, frequency) {
		var config = config || this.config;
		config.data.frequency = $pick(frequency,1);
		this._send(config, onsuccess, true);
		return this;
	},
	send : function(config, onsuccess) {
		var config = config || this.config;
		this._send(config, onsuccess, false);
		return this;
	},
	_send : function(config, onsuccess, isPeriodical) {
		this.fireEvent('beforesend');
		config.data.v = U.version;
		if (config.fresh) config.data.r=$time();
		if (onsuccess == null) onsuccess = $empty;
		if (!this.noKill) U.Request.Manager.checkIn(this);
		var options = $extend(config.toOption(), {
			
			onSuccess: function(responseText) {
				if (this.__checkServerError(responseText)) return;
				try {
					this.fireEvent('success', responseText);
					onsuccess(responseText);
				} catch (e) {
					var error = U.Error.getString(e);
					this.__handleClientError();
				} finally {
					if (!this.noKill) U.Request.Manager.checkOut(this);	
				}
			}.bind(this),
            onFailure: this._onFailure.bind(this),
            onException: this._onException.bind(this),
			headers : {'If-Modified-Since':'Sat, 1 Jan 2000 00:00:00 GMT'}
		});
		
		$log('_send before create request url='+options.url);
		if (!this.currentRequest) this.currentRequest = (!isPeriodical)?new (Request)(options):new (Request.Periodical)(options);
		
		$log('_send before sending request');
		 _proxy_jslib_handle(this.currentRequest, ((isPeriodical)?'start':'send'), 1, 0)(options);
		this.fireEvent('aftersend');
	},
	_onFailure : function(instance) {
		U.Error.log("AJAX FAILURE: "+this.__buildErrorLog());
		this.fireEvent('failure');
		this.currentRequest.cancel();
	},
	_onException : function(headerName, value) {
		U.Error.log("AJAX FAILURE: headerName : "+headerName+" value : "+ _proxy_jslib_handle(null, 'value', value, 0, 0));
		this.fireEvent('exception');
		this.currentRequest.cancel();
	},
	
	processScripts : function(responseText) {
		var script = responseText.getTagContent('eval');
		$exec(script);
		return this;
	},
	__checkServerError : function(responseText) {
		var index = responseText.indexOf('<b>Fatal error</b>');
		if (index > -1) {
			try {
				var error = responseText.substr(index);
				$log('SERVER SIDE ERROR: '+error);
				this.fireEvent('error', ['server', error]);
			} catch (e) {}
			return true;
		}
		return false;
	},
	__handleClientError : function(error) {
		$log('CLIENT SIDE ERROR: '+error);
		this.fireEvent('error', ['client', error]);
	},
	__buildErrorLog : function() {
        var config = this.config;
        var message = 'URL: '+config.url+"\n\n";
        params = config.data;
        for (var i in data) {
            message += 'param: '+i+' - value: '+ _proxy_jslib_handle(data, (i), 0, 0)+"\n"
 };
        return message;
	},
	stopPeriodical : function() {
		if (!this.currentRequest) return this;
		this.currentRequest.stop();
		this.currentRequest = null;
		return this;
	},
	cancel : function() {
		if (this.currentRequest && this.currentRequest.running) {
			this.aborted = true;
			this.currentRequest.cancel();
			this.currentRequest = null;
		}
		return this;
	}
});

U.Request.Manager = {
	_active : {},
	_items : {},
	hasConfig : function(key) {
		return  _proxy_jslib_handle(this._items, (key), 0, 0) != null;
	},
	addConfig : function(key, url, data, method, fresh) {
		//this._items[key] = new U.Request.Config(U.getRequestUrl(name), data, method, name, fresh);
		 _proxy_jslib_assign('', this._items, (key), '=', ( new (U.Request.Config)(url, data, method, name, fresh)));
	},
	getConfig : function(key, urlreplace) {
		//return this._items[key] || new U.Request.Config(U.getRequestUrl("notconfigured"), null);
		var config = $pick( _proxy_jslib_handle(this._items, (key), 0, 0), this._findInForm(key), new (U.Request.Config)(U.constructActionUrl("notconfigured"), null));
		if (urlreplace) {
			for(var i in urlreplace) {
				config.url =  _proxy_jslib_handle(config.url, 'replace', '', 1, 0)('#'+i, _proxy_jslib_handle(urlreplace, (i), 0, 0));
			}
		}
		return config
 },
	getFormConfig : function(key) {
		var config = this._findInForm(key);
		var form = $(key);
		for(var i=0,nL=form.elements.length,elm;i<nL;i++) {
			var val = this._getElmValue(elm = $( _proxy_jslib_handle(form.elements, (i), 0, 0)));
			if (val != null) {
				 _proxy_jslib_assign('', config.data, (elm.name), '=', ( val));
			}
		}
		return config;
	},
	_getElmValue : function(elm) {
		var val = null;
		switch (elm.type) {
			case 'password':
			case 'text':
			case 'textarea':
			case 'hidden':
				val =  _proxy_jslib_handle(elm, 'value', '', 0, 0);
				break;
			case 'checkbox':
			case 'radio':
				if (elm.checked) val =  _proxy_jslib_handle(elm, 'value', '', 0, 0);
				break;
			case 'select-one':
				val = U.UI.Select.getValue(elm);
				break;
			default:
				break;
		}
		return val;
	},
	checkIn : function(request) {
		 _proxy_jslib_assign('', this._active, (request.uid), '=', ( request));
	},
	checkOut : function(request) {
		var ref =  _proxy_jslib_handle(this._active, (request.uid), 0, 0);
		ref = null;
		(ref= _proxy_jslib_assign_rval('delete', 'ref', '', '', ref));
	}, 
	unload : function() {
		var active;
		for(var i in this._active) {
			active =  _proxy_jslib_handle(this._active, (i), 0, 0);
			if (active != null) active.cancel();
		}
	},
	_findInForm : function(key) {
		var obj = $(key+'-ajax-url');
		if (obj) {
			 _proxy_jslib_assign('', this._items, (key), '=', ( new (U.Request.Config)( _proxy_jslib_handle(obj, 'value', '', 0, 0))));
			return  _proxy_jslib_handle(this._items, (key), 0, 0);
		}
		return null;
	}
};

U.Request.Config = new (Class)({
	initialize : function(url, data, method, name, fresh) {
		this.url = url;
		this.data = data || {};
		this.method = method||'post';
		this.name = name;
		this.fresh = fresh || false;
	},
	toOption : function() {
		return {url : this.url, data: this.data, method : this.method};
	}
});
window.addEvent('unload', function() {U.Request.Manager.unload()});
U.Request.Manager.addConfig('getHtml', 'GetHtml', {file:''});
U.Request.Manager.addConfig('performAction', 'PerformAction', {module_url_string:'',action:'',params:''}); ;
_proxy_jslib_flush_write_buffers() ;