/*
Class: Ajax (timeout)
	<Ajax> class extensions

Options:
	timeout - timeout in milliseconds; default is 6000 (six seconds)
	onTimeout - timeout event
	windowSpinner - show spinner in the middle of the window; default is true

Author:
	Stefan Lange-Hegermann (lange-hegermann@sipgate.de)
*/

Ajax = Ajax.extend({
	options: {
		timeout:12000,
		onTimeout:Class.empty,
		onStateChange:Class.empty,
		windowSpinner:true,
		sgjson:false,
		cache:false,
		force:false
	},
	
	onStateChange: function() {
		this.fireEvent('onStateChange', [this.transport.readyState]);
		if (this.transport.readyState != 4 || !this.running) return;
		if (window.spinnerCount && this.options.windowSpinner) {
			window.spinnerCount--;
			if (window.spinnerCount===0) {
				window.spinner.removeProperty('style');
				window.spinner.remove();
				window.spinner=null;
			}
		}
		this.parent();
	},

	cancel: function() {
		this.removeTimer();
		this.parent();
	},

	request: function(data){
		if (this.url.substr(0,4)==="http" && ZendFramework['systemarea']==="dev") {
			this.url="/ajax/files/ajaxproxy?path="+this.url;
		}
		if (this.options.sgjson) {
			this.setHeader('X-Sipgate-JSON', 'true');
		} else {
			this.setHeader('X-Sipgate-JSON', 'false');
		}
		
		data = data || this.options.data;
		this.data=data;
		
		if (this.options.cache) {
			if (!$type(window.AJAXCACHE)) {
				window.AJAXCACHE={};
			}
			
			if (window.AJAXCACHE[hex_md5(this.url+Json.toString(this.data))] && !this.options.force) {
				this.fireEvent('onComplete', [window.AJAXCACHE[hex_md5(this.url+Json.toString(this.data))]], 20);
				return;
			}
		}
		
		if (this.options.timeout) {
			this.timeoutTimer=window.setTimeout(this.callTimeout.bindAsEventListener(this), this.options.timeout);
			this.addEvent('onComplete', this.removeTimer);
		}
		if (this.options.windowSpinner && !window.spinnerCount) {
			window.spinnerCount=0;
			window.spinner=new Element('div', {
				styles:{
					top:(window.getHeight()/2-30)+window.getScrollTop(),
					left:window.getWidth()/2-30,
					background:"url('"+getImagePath('spinner/loading_trans_40.gif')+"')",
					width:60,
					height:60,
					backgroundColor:'#eeeeee',
					backgroundRepeat:'no-repeat',
					backgroundPosition:'10px 10px',
					border:'1px solid #cccccc',
					position:'absolute',
					zIndex:1005,
					opacity:0.8
				}
			}).injectInside(document.body);

			window.spinnerCount++;
		}
		this.parent(data);
	},
	
	send: function(url, data){
		if (this.options.autoCancel) this.cancel();
		else if (this.running) return this;
		this.running = true;
		if (data && this.options.method == 'get'){
			url = url + (url.contains('?') ? '&' : '?') + data;
			data = null;
		}
		this.transport.open(this.options.method.toUpperCase(), url, this.options.async);
		this.transport.onreadystatechange = this.onStateChange.bind(this);
		if (!window.webkit)
			if ((this.options.method == 'post') && this.transport.overrideMimeType) this.setHeader('Connection', 'close');
		$extend(this.headers, this.options.headers);
		for (var type in this.headers) try {this.transport.setRequestHeader(type, this.headers[type]);} catch(e){};
		this.fireEvent('onRequest');
		this.transport.send($pick(data, null));
		return this;
	},
	
	callTimeout: function () {
		this.transport.abort();
		this.onFailure();
		this.fireEvent('onTimeout');
	},

	removeTimer: function() {
		window.clearTimeout(this.timeoutTimer);
	},
	
	onComplete: function() {
		var err=false;
		if (!this.options.sgjson) {
			nq.log(this.url+' is not using sgjson. This is not necessarily bug - if you are the developer and want to fix it call Lange-Hegermann (84)');
			return this.parent();
		}
		
		result=this.response.text;
		var jsr=false;
		
		try {
			jsr=Json.evaluate(result);
		} catch (e) {
			err=true;
			nq.err('invalid json ('+this.url+')', "\nURL: "+this.url+"\n\nData:\n"+Json.toString(this.data)+"\n\nResult:\n"+result+"\n\nError:\n"+Json.toString(e), 'lange-hegermann+js@sipgate.de');
			this.fireEvent('onFailure');
		}
		
		if (jsr!==null) {
			if ($chk(jsr['error']) && jsr['error']!=0) {
				err=true;
				if (!jsr['result']) {
					nq.err('controller failed ('+this.url+')', "\nURL: "+this.url+"\n\nData:\n"+Json.toString(this.data)+"\n\nResult:\n"+Json.toString(jsr), 'lange-hegermann+js@sipgate.de');
				}
				if ($chk(jsr['result'])) {
					nq.err(jsr['call']+' failed ['+jsr['result']['faultCode']+':'+jsr['result']['faultString']+'] ('+this.url+')', "\nURL: "+this.url+"\n\nData:\n"+Json.toString(this.data)+"\n\nResult:\n"+Json.toString(jsr), 'lange-hegermann+js@sipgate.de');
				}
				if ($chk(jsr['userError'])) {
					sgUserError(jsr['userError']);
				}
				this.fireEvent('onFailure');
			}
		}
		
		if (this.options.cache && !err) window.AJAXCACHE[hex_md5(this.url+Json.toString(this.data))]=jsr;
		this.fireEvent('onComplete', [jsr], 20);
	}
});

/*
	use the browsers native JSON parser and generator when available
*/
if (typeof JSON!=="undefined") {
	Json = {
	
		toString: function(obj){
			return JSON.stringify(obj);
		},

		evaluate: function(str, secure){
			if (!str) return false;
			return JSON.parse(str);
		}
	
	};
}
