/*  AJAX framework, version 1.0
 *  (c) 2008 Donato Tagliabue
 *
 *  Generic purpose AJAX (XHR) and XML functions
 *  Dependencies: none
 *
 *--------------------------------------------------------------------------*/

//AJAX
//Main object to start an ajax call.
//url can be any remote url, without parameters
//method is 'GET' or 'POST'
//parameters are the parameters appended to the url for GET calls
//output is 'TEXT' or 'XML' (for returned values)
//callback is the name of the function called when readyState is 4
//notify, true is a message should be displayed for readyState < 4
//NOTE: parameters are not escaped by the AjaxFetcher object
var AjaxFetcher = function(url, method, parameters, output, callback, notify) {
	this.url        = url + '?time=' + new Date().getTime(); //IE cache bug
	this.method     = method.toLowerCase() == 'post' ? 'POST' : 'GET';
	this.parameters = parameters;
	this.output     = output;
	this.callback   = callback;
	this.notify     = notify;

	this.transport  = this.getTransport();			//Get the XHR object
	this.timeoutHandler;

	if (this.transport) var isOpen = this.open();	//Open the connection
	if (isOpen) this.setready(this); 				//Set onreadystatechange
	if (isOpen) this.send(this);					//Start the call
}

AjaxFetcher.prototype.timeOut = 10; // request timeout, in seconds

//Create the XHR object (ok, IE5 is not supported..)
AjaxFetcher.prototype.getTransport = function() {
	try {
		if (window.XMLHttpRequest)
			return new XMLHttpRequest(); //Other browsers
		else if (window.ActiveXObject)
			return new ActiveXObject('Msxml2.XMLHTTP'); //IE 6+
	}
	catch(e) {
		this.error(e);
	}
}

//Open the connection
AjaxFetcher.prototype.open = function() {
	try {
		if (this.method == 'POST')
			this.transport.open('POST', this.url, true);
		else
			this.transport.open('GET', this.url + '&' + this.parameters, true);
		return true;
	}
	catch(e) {
		this.error(e);
	}
}

//Set the onreadystatechange function (before sending the request)
//readyState < 4 might not be supported in some browsers
AjaxFetcher.prototype.setready = function(ajax) {
	ajax.transport.onreadystatechange = function() {
		try {
			if (ajax.transport.readyState == 1) {
				if (ajax.notify) display_message('info', 'Connecting...', false);
			}
			else if (ajax.transport.readyState == 2) {
				if (ajax.notify) display_message('info', 'Sending request...', false);
			}
			else if (ajax.transport.readyState == 3) {
				if (ajax.notify) display_message('info', 'Receiving data...', false);
			}
			else if (ajax.transport.readyState == 4) {
				ajax.transport.onreadystatechange = new Function; //IE memory leak bug
				clearTimeout(ajax.timeoutHandler);

				//This is needed because the status could not be set properly
				var status;
				try {
					status = ajax.transport.status || 0;
				}
				catch (e) {
					status = 0;
				}

				if (status == 200) {
					var serverResponse;
					if (ajax.output == 'TEXT')
						serverResponse = ajax.transport.responseText;
					else
						serverResponse = ajax.transport.responseXML;
					eval(ajax.callback + '(serverResponse);');
				}
				else if (status == 404) {
					ajax.error('Address not found');
				}
				else {
					ajax.error('Unknown error');
				}
			}
		}
		catch(e) {
			ajax.error(e);
		}
	}
}

//Finally, send the request
AjaxFetcher.prototype.send = function(ajax) {
	try {
		if (this.method == 'POST') {
			//No other headers are really needed
			this.transport.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
			this.transport.send(this.parameters); //To be encoded before passing them here...
		}
		else {
			this.transport.send(null); //No body for GET requests
		}

		if (this.timeOut != 0)
			this.timeoutHandler = setTimeout(function() { AjaxAbort(ajax) }, this.timeOut * 1000);
	}
	catch(e) {
		this.error(e);
	}
}

//Abort the connection if readyState is not 4 after timeOut seconds
function AjaxAbort(ajax) {
	ajax.transport.abort();
	ajax.error('Connection timeout. Retry later');
}

//Display the error message if something went wrong with the XHR object
AjaxFetcher.prototype.error = function(e) {
	var description = (typeof e == 'string') ? e : (e.description ? e.description : e.message);
	display_message('error', 'Ajax error: ' + description, true);
}

//The following is a stub method, to be implemented here or overwritten elsewhere,
//to display error messages for AJAX or XML
if (typeof window.display_message == 'undefined') {
	var display_message = function(type, text, autohide) {
		//Do something as document.getElementById('errordiv').innerHTML = text;
	};
}


//Ajax functions site specific
var ajax_div, ajax_div2;
var ajax_href = location.href.replace(/[^\/]+$/, '');
var ajax_lang = location.href.indexOf('_en') > 0 ? 'en' : 'it';

function display_message(type, text, autohide) {
	if (type == 'error')
		document.getElementById(forum_div).innerHTML = text;
}

function fill_ajax_div(div, op) {
	ajax_div = div;
	new AjaxFetcher(ajax_href + 'vt_forum.asp', 'GET',
		'lang=' + ajax_lang + '&o=' + op, 'TEXT', 'ajax_callback', true);
}

function ajax_callback(o) {
	if (o) document.getElementById(ajax_div).innerHTML = o;
}

function ajax_callback2(o) {
	if (o) document.getElementById(ajax_div2).innerHTML = o;
}

function post_ajax_form() {
	var autore;
	var messaggio;

	autore    = escape(document.getElementById('autore').value);
	messaggio = escape(document.getElementById('messaggio').value);

	ajax_div = 'newpost_div';
	new AjaxFetcher(ajax_href + 'vt_forum.asp', 'POST',
		'lang=' + ajax_lang + '&o=insert&a=' + autore + '&m=' + messaggio, 'TEXT', 'ajax_callback', true);
}

function edit_message(id) {
	ajax_div = 'msg_' + id;
	new AjaxFetcher(ajax_href + 'vt_forum.asp', 'GET',
		'lang=' + ajax_lang + '&o=edit&id=' + id, 'TEXT', 'ajax_callback', true);
}

function post_ajax_edit(id) {
	var messaggio, approvato, visualizza, risposta, cancella;

	messaggio  = escape(document.getElementById('messaggio_' + id).value);
	approvato  = document.getElementById('approvato_' + id).checked ? 'y' : '';
	visualizza = document.getElementById('visualizza_' + id).checked ? 'y' : '';
	cancella   = document.getElementById('cancella_' + id).checked ? 'y' : '';
	risposta   = escape(document.getElementById('risposta_' + id).value);

	ajax_div = 'msg_' + id;
	new AjaxFetcher(ajax_href + 'vt_forum.asp', 'POST',
		'lang=' + ajax_lang + '&o=answer&id=' + id + '&a=' + approvato + '&v=' + visualizza
		+ '&d=' + cancella + "&r=" + risposta + "&m=" + messaggio,
		'TEXT', 'ajax_callback', true);
}

function fill_news_div(div) {
	ajax_div2 = div;
	new AjaxFetcher(ajax_href + 'news_' + ajax_lang + '.htm', 'GET', '', 'TEXT', 'ajax_callback2', true);
}
