/*
IO Tower - AJAX communication
--
Written by Ivik Injerd
--
Requires:
jQuery (jquery.js)
JSON (json.js)
*/

var active_iotower = null;
var iotower_timeout = null;

function IOTower(){
	// "All that is visible must grow beyond itself, and extend into the realm of the invisible."

	// Init...
	this.uid = iotower_uid;
	this.sess_key = iotower_sess_key;
	this.outgoing = [];
	this.outgoing_active = [];
	this.timeout = 0.5; // Seconds between sending of requests in queue
	this.sess_timeout = 1800; // Seconds
	this.active = true; // Use timeouts?

	// Add a request to request queue
	this.addRequest = function(data,callback,upd){
		upd = (upd==undefined)?false:upd;
		if (callback == undefined || typeof callback != 'function') callback = null;
		if (
		 data.wid == undefined &&
		 data.wik == undefined &&
		 data.tid == undefined &&
		 data.tik == undefined &&
		 data.uid == undefined
		 ){
			throwError('ERROR: Invalid request!');
			return false;
		}
		var exists = false;
		for (var key in this.outgoing){
			if (isSame(data,this.outgoing[key].data)){
				exists = true;
			}
			if (upd && data.id == this.outgoing[key].data.id){
				//delete this.outgoing[key];
				upd = 'CONFIRMED';
				var idx = key;
			}
		}
		if (upd == 'CONFIRMED'){
			this.outgoing[idx] = {data:data,callback:callback};
			return true;
		}else if (!exists){
			this.outgoing.push({data:data,callback:callback});
			return true;
		}else{
			throwError('ERROR: Duplicate request!');
			return false;
		}
	}

	// Add a requests to queue and then send it out to server
	this.doRequest = function(data,callback,upd){
		if (this.addRequest(data,callback,upd)){
			this.sendRequest();
		}else{
			throwError('ERROR: Unable to send request due to another error!');
		}
	}

	// Send request queue out to server
	this.sendRequest = function(){ //debug_mode = 1;
		if (active_iotower != null){ // If we are already processing a request, let's patiently wait for it to finish.
			clearTimeout(iotower_timeout);
			iotower_timeout = setTimeout('dumont.sendRequest();',this.timeout*100);
		}else if (this.outgoing.length){
			clearTimeout(iotower_timeout);
			//this.debugObj(this);
			var json_data = this.buildRequestJSON();
			active_iotower = this;
			$.post(iotower_base_url+'/ajax', {data:json_data}, function(data){
				var raw_dbg = (debug_mode==2)?false:true;
				debugWin(data,raw_dbg,'#0f0');
				for(var r in data.responses){
					if (typeof active_iotower.outgoing_active[r].callback == 'function')
						active_iotower.outgoing_active[r].callback(data.responses[r]);
				}
			},((debug_mode==2)?'text':'json'));
		}else{
			if (this.active)
				iotower_timeout = setTimeout('dumont.sendRequest();',this.timeout*1000);
		}
	}
	this.buildRequestJSON = function() {
		if (this.outgoing.length == 0) return false;
		this.outgoing_active = [];
		for (var key in this.outgoing){
			this.outgoing_active[key] = {data:this.outgoing[key].data};
		}
		var obj = {
			info:{
				uid:this.uid,
				sess_key:this.sess_key
			},
			requests:this.outgoing_active
		}
		this.outgoing_active = [];
		this.outgoing_active = this.outgoing.slice();
		this.outgoing = [];
		debugWin(obj,false,'#00f');
		objStr = JSON.stringify(obj);
		//debugWin(objStr,false,'#00f');
		return objStr;
	}
}

// We need this defined only once.
$(document).ajaxComplete(function(event, request, settings){
	if (active_iotower != null){
		active_iotower.outgoing_active = [];
		if (active_iotower.active)
			iotower_timeout = setTimeout('dumont.sendRequest();',active_iotower.timeout*1000);
		active_iotower = null;
	}
});

