var sg_requests = new Array();

var SupAjaxFactory = {};
SupAjaxFactory.RequestMaker = Class.create();
Object.extend(SupAjaxFactory.RequestMaker.prototype, {
	initialize: function(name, host, callbackObject, action, langID, loaderImg) {
		this.name = name;
		if (document !== undefined && document.location !== undefined && document.location.hostname !== undefined && document.location.hostname.indexOf('supremacy1914') == -1) {
			this.host = host;
		} else {
			this.host = '';
		}		
		this.callbackObject = callbackObject;
		this.callbackObject.setRequestName(name);
		this.action = action;
		this.langID = langID;
		this.keys = new Array();
		this.values = new Array();
		this.resetValues = new Array();
		this.resetForms = new Array(); 
		this.resetFormValues = new Array();
		this.loaderImg = loaderImg;
		this.loaderImgStyle = '';
		this.currentRequest = 0;
		this.bufferRequests = false;
		this.clearDivOnload = false;
		this.isPolling = false;
		sg_requests[name] = this;
	},
	performCall: function() {
		var tstamp = new Date().getTime();
		var url = this.host + '/index.php?eID=ajax';
		url += '&action=' + this.action;
		url += '&L=' + this.langID;
		url += '&ref=' + this.callbackObject.name + '&req=' + this.name;
		if (this.isPolling) {
			url += '&poll=1';
		}
		var params = '';
		for (var i = 0; i < this.keys.length; i++) {
			if (this.keys[i] !== undefined && this.values[i] !== undefined) {
				params = params + '&' + this.keys[i] + '=' + this.values[i];
				if (this.keys[i] == 'eventID' || this.keys[i] == 'code' || this.keys[i] == 'tstamp' || this.keys[i] == 'ses_id'
					|| this.keys[i] == 'gid' || this.keys[i] == 'mid') {
					url += '&'+this.keys[i]+'='+this.values[i];
				}
			}
		}
		if (this.bufferRequests) {
			var buffered = this.callbackObject.getBufferedResponse(url+params);
			if (buffered === -2) {
				if (this.clearDivOnload) {
					this.callbackObject.updateDiv('');
				}
				//this is the first request for these params: execute it
				this.callbackObject.setBufferedRequest(this.currentRequest, url+params);
			} else if (buffered === -1) {
				//this is a subsequent call for the same question. igonre it and wait for the previous result
				return;
			} else if (buffered === -3) {
				//if we are already showing that request, do not update the div
				return;
			} else {
				//we already have the answer to that question so do not ask again but simply call the callback
				sg_ajaxCallback(buffered);
				return;
			}
		} else if (this.clearDivOnload) {
			this.callbackObject.updateDiv('');
		}
		
		if (this.loaderDiv !== undefined) {
			$(this.loaderDiv).innerHTML = '<img src="'+this.loaderImg+'" '+this.loaderImgStyle+' />';
		}
		//this has to be appended _after_ we check the buffer
		url += '&reqID='+this.currentRequest;
		url += '&' + tstamp;
		
		this.callbackObject.setCurrentRequest(this.currentRequest);
		this.currentRequest++;
		var myAjax = new Ajax.Request(url, {method: "post", parameters: params, onComplete: sg_ajaxCallback});
	},
	addParam: function (key, value, defaultValue) {
		this.keys[this.keys.length] = key;
		this.values[this.values.length] = value;
		this.resetValues[this.resetValues.length] = defaultValue;
		//console.log(key + " auf default " + defaultValue + " gesetzt.");
	},
	setParam: function (key, value, defaultValue) {
		for (var i = 0; i < this.keys.length; i++) {
			if (this.keys[i] == key) {
				this.values[i] = value;
				//this.resetValues[i] = defaultValue; //only set on first add
				//console.log(key[i] + " auf default " + defaultValue + " gesetzt.");
				return;
			}
		}
		//if we reach this point, the key is new
		this.addParam(key, value, defaultValue);
	},
	setPolling: function (value) {
		this.isPolling = value;
	},
	setLoaderDiv: function (id) {
		this.loaderDiv = id;
	},
	setLoaderImgStyle: function (style) {
		this.loaderImgStyle = style;
	},
	reset: function () {
		for (var i = 0; i < this.values.length; i++) {
			if (this.resetValues[i] !== undefined) {
				//console.log(this.keys[i] + ': ' + this.values[i] + ' -> ' + this.resetValues[i]);
				this.values[i] = this.resetValues[i];
			} else {
				//console.log('skipping value ' + this.keys[i] + " (" + this.resetValues[i] + ")");
			}
		}
		for (var i = 0; i < this.resetForms.length; i++) {
			elem = $(this.resetForms[i]);
			if (elem !== undefined) {
				try {
					elem.selectedIndex = this.resetFormValues[i];
//					console.log("resetform " + this.resetForms[i] + ' zurückgesetzt auf ' + this.resetFormValues[i]);
				} catch (err) {}
			}
		}
		this.performCall();
	},
	addFormForReset: function (id, resetTo) {
		//console.log(id + " mit reset index " + resetTo + " initialisiert.");
		this.resetForms[this.resetForms.length] = id;
		this.resetFormValues[this.resetFormValues.length] = resetTo;
	},
	setBufferRequests: function (val) {
		this.bufferRequests = val;
		this.callbackObject.setBufferRequests(val);
	},
	setClearDivOnLoad: function (val) {
		this.clearDivOnload = val;
	}
});

var sg_callbacks = new Array();

SupAjaxFactory.Callback = Class.create();
Object.extend(SupAjaxFactory.Callback.prototype, {
	initialize: function(name) {
		this.name = name;
		this.requestName = '';
		this.callbackData = '';
		this.ignoreOldRequests = false;
		this.currentRequest = 0;
		this.currentlyShown = 0;
		this.bufferRequests = false;
		this.requestBuffer = new Array();
		this.responseBuffer = new Array();
		sg_callbacks[this.name] = this;
	},
	setRequestName: function(val) {
		this.requestName = val;
	},
	getRequestName: function() {
		return this.requestName;
	},
	updateDiv: function(resText) {
		if (this.loaderDiv !== undefined) {
			$(this.loaderDiv).innerHTML = '';
		}
		//An dieser stelle hat die callback Methode vergessen, zu welchem Object sie gehörte.... dumm. müssen wir also wieder mit zurückgeben.		
		$(this.targetDiv).update(resText);
	},
	setTargetDiv: function(id) {
		//remember the name only since the browser may not yet have the actual div.
		this.targetDiv = id;
	},
	setLoaderDiv: function (id) {
		this.loaderDiv = id;
	},
	setEvalJS: function(js) {
		this.evalJS = js;
//		console.log("setter : " + this.evalJS);
	},
	exec: function () {
//		console.log("auszuführen : " + this.evalJS);
		if (this.evalJS !== undefined && this.evalJS.length > 0) {
			try {
				eval(this.evalJS);
			} catch (e) {}
		}
	},
	setForwardURL: function (url) {
		this.forwardURL = url;
	},
	setExecuteOnResponse: function (js) {
		this.execOnResponse = js;
	},
	setIgnoreOldRequests: function (val) {
		this.ignoreOldRequests = val;
	},
	isIgnoreOldRequests: function () {
		return this.ignoreOldRequests;
	},
	getCurrentRequest: function () {
		return this.currentRequest;
	},
	setCurrentRequest: function (val) {
		this.currentRequest = val;
	},
	getCurrentlyShown: function () {
		return this.currentlyShown;
	},
	setCurrentlyShown: function (val) {
		this.currentlyShown = val;
	},
	executeOnResponse: function() {
		if (this.execOnResponse !==  undefined && this.execOnResponse.length > 0) {
			try {
				eval(this.execOnResponse);
			} catch (e) {}
		}
	},
	setBufferedRequest: function (id, url) {
		this.requestBuffer[id] = url;	//remembers the id of the request
		//nconsole.log('Call ' + id + " = " + url);
	},
	getBufferedResponse: function(url) {
		for (var i = 0; i < this.requestBuffer.length; i++) {
			if (this.requestBuffer[i] !== undefined && this.requestBuffer[i] == url) {
				if (this.responseBuffer[i] !== undefined) {
					if (this.getCurrentlyShown() == i) {
						//this is the one whcih is currently showing.
						return -3;
					}
					//console.log('Returning buffered response for: ' + url);
					response = this.responseBuffer[i];
					var res = response.responseText.split('&', 3);
					var code = parseInt(res[0]);
					var ref = res[1];
					var reqID = parseInt(res[2]);
					//console.log('found buffered reqID ' + reqID + " --> " + response.responseText + " in buffer slot " + i);
					return this.responseBuffer[i];
				} else {
					//request is on its way, wait for it
					return -1;
				}
			}
		}
		//request has not yet been made
		return -2;
	},
	bufferResponse: function (reqID, response) {
		if (this.bufferRequests && this.responseBuffer[reqID] === undefined) {
			var res = response.responseText.split('&', 3);
			var code = parseInt(res[0]);
			var ref = res[1];
			var reqID = parseInt(res[2]);
			
			//nconsole.log('Storing answer to reqID ' + reqID + " --> " + response.responseText);
			this.responseBuffer[reqID] = response;
		} else {
			//nconsole.log('Soll garnich speichern');
		}
	},
	setBufferRequests: function (val) {
		this.bufferRequests = val;
	}
});

function sg_ajaxCallback(response) {
	//An dieser stelle hat die callback Methode vergessen, zu welchem Object sie gehörte.... dumm. müssen wir also wieder mit zurückgeben.
	var res = response.responseText.split('&', 4);
	var code = parseInt(res[0]);
	var ref = res[1];
	var reqID = parseInt(res[2]);
	var continuePolling = parseInt(res[3]);
	//nconsole.log('hab dem callback gesagt, dass er speichern soll');
	//show only results newer as the current one
	if (sg_callbacks[ref].isIgnoreOldRequests() && (reqID < sg_callbacks[ref].getCurrentlyShown())) {
		//ignore
		return;
	}
	sg_callbacks[ref].setCurrentlyShown(reqID);
	sg_callbacks[ref].bufferResponse(reqID, response);
	var startIndex = res[0].length+res[1].length+res[2].length+5;
	var content = response.responseText.substr(startIndex);
	
	sg_callbacks[ref].callbackData = content;
	if (code == 1) {
		sg_callbacks[ref].updateDiv(content);
	} else if (code == 2) {
		location.href = content;
	} else if (code == 3) {
		sg_callbacks[ref].exec();
	}
	sg_callbacks[ref].executeOnResponse();
	if (sg_callbacks[ref].forwardURL !== undefined && sg_callbacks[ref].forwardURL.length > 0) {
		location.href = sg_callbacks[ref].forwardURL;
	}
	
	if (continuePolling==1) {
		setTimeout(function() {	sg_pollAgain(ref); }, 5000);
	} 
}

function sg_pollAgain(sg_pollerName) {
	var requestName = sg_callbacks[sg_pollerName].getRequestName();
	sg_requests[requestName].performCall();
}

function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}
