/* AV AJAX */
/* Based on Ajaxelation http://ajaxelation.com/ */

function $(id) {
	return document.getElementById(id);
}

Cookies = {
	get: function(name) {
		var match = document.cookie.match(name+"=(.*?)(?:;|$)");
		return match ? unescape(match[1]) : null;
	},

	set: function(name, value, days, path) {
		if (days) {
			var date = new Date();
			date.setDate(date.getDate()+days);
			days = date.toGMTString();
		}
		document.cookie = name+"="+escape(value)+"; expires="+(days?days:'')+"; path="+(path?path:'/');
	},

	del: function(name, path) {
		Cookies.set(name, '', -1, path);
	}
}

var soundEmbed = null;

function soundPlay(which)
{
	if (soundEmbed) {
		document.body.removeChild(soundEmbed);
		soundEmbed.removed = true;
		soundEmbed = null;
	}
	soundEmbed = document.createElement("embed");
	soundEmbed.setAttribute("src", which);
	soundEmbed.setAttribute("hidden", true);
	soundEmbed.setAttribute("height", 0);
	soundEmbed.setAttribute("autostart", true);

	soundEmbed.removed = false;
	document.body.appendChild(soundEmbed);
}

/* Request object */
function Request(url, get, post, callback, params, id) {
	/* Start Contructor */
	this.url = url; // URL
	this.get = get; // Parameters via GET
	this.post = post; // Parameters via POST
	this.callback = callback; // Callback
	this.params = params; // Params for Callback
	this.id = id;
	/* End Contructor */
}

ajax = {
	/* Start Constructor */
	history: [],
	handler: undefined,
	request: undefined,
	queue_length: 3, // Default queue length
	id: 0,
	/* End Constructor */

	/* Enqueues a new request */
	request_enqueue: function(url, get, post, callback, params) {
		if (this.history.length >= this.queue_length) return false;
		this.history.push(new Request(url, get, post, callback, params, this.id++));
		this.go();
	},

	/* Sends a request. */
	go: function() {
		if (this.history.length == 0 || this.request != undefined) return;
		this.request = this.history.shift();

		// Istantiate the XMLHttpRequest object
		if (this.handler == undefined) {
			if (window.ActiveXObject) this.handler = new ActiveXObject('Microsoft.XMLHTTP'); // IE
			else if (window.XMLHttpRequest) this.handler = new XMLHttpRequest(); // All Others
			else {
				alert('Error: Your browser is not remote scripting enabled.');
				return false;
			}
			if (typeof(this.handler) != 'object') {
				alert('Error: Your browser is not remote scripting enabled.');
				return false;
			}
		}

		// Sets response function
		this.handler.onreadystatechange = function() {
			if (ajax.handler.readyState != 4) return;
			if (ajax.handler.status == 200) ajax.response();
			ajax.stop();
		};

		// Cache busting
		this.request.get = (this.request.get == undefined ? '' : this.request.get + '&') + 'cb='+(new Date()).getTime()+(100+Math.floor(899 * Math.random()));

		// The request
		if (this.request.post != undefined) {
			this.handler.open('POST', this.request.url + '?' + this.request.get, true);
			this.handler.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
			this.handler.send(this.request.post);
		} else {
			this.handler.open('GET', this.request.url + '?' + this.request.get, true);
			this.handler.send(null);
		}
	},

	/* Receives the data */
	response: function() {
		if (this.handler.responseXML == undefined || (root = this.handler.responseXML.documentElement) == undefined) {
			alert('ERROR: XML response seems not valid.');
			this.stop();
			return false;
		}

		var params = {};

		for (var i = 0; i < root.childNodes.length; i++) {
			var node = root.childNodes.item(i);
			if (node.nodeType != 1) continue; // Only ELEMENT_NODE
			if (node.tagName == 'xhtml') {
				document.getElementById(node.getAttribute("target")).innerHTML = node.firstChild.nodeValue;
			} else if (node.tagName == 'javascript') {
				var content = node.firstChild.nodeValue;
				eval(content);
			} else if (node.tagName == 'param') {
				var name = node.getAttribute("name");
				if (name == undefined) continue;
				var content = node.firstChild.nodeValue;
				if (content == undefined) continue;
				params[name] = content;
			}
		}

		if (this.request.callback != undefined) this.request.callback(this.request.params, params);
		this.stop();
	},
	
	stop: function() {
		this.handler.abort();
		this.request = undefined;
		setTimeout("ajax.go()", 25);
	},
	
	/* *** Wrapper functions *** */

	split_link: function(url) {
		var ret = new Array();
		if (url.indexOf('?') > 0) {
			ret['path'] = url.substr(0, url.indexOf("?"));
			ret['get'] = url.substr(url.indexOf("?") + 1);
		} else {
			ret['path'] = url;
			ret['get'] = undefined;
		}
		return ret;
	},

	wrapper_link: function(link, callback, params) {
		var url = this.split_link(link.href);
		this.request_enqueue(url['path'], url['get'], undefined, callback, params);
		return false;
	},

	wrapper_get: function(url, get, callback, params) {
		this.request_enqueue(url, get, undefined, callback, params);
		return false;
	},

	wrapper_post: function(url, get, post, callback, params) {
		this.request_enqueue(url, get, post, callback, params);
		return false;
	}
}


Chat = {
	users: {},
	blinks: {state: 0},
	url: '/chatty/index.php',
	me: null,
	lastid: 0,
	timer: 0,
	timer_d: 32, // Half-seconds
	timer_h: null,

	list_switch: function() {
		var ul = $('chatty_list');
		if (ul.style.display == 'none') {
			ul.style.display = '';
			for (var id in this.users) if (this.users[id].chat) this.users[id].chat.style.display = 'none';
		} else {
			ul.style.display = 'none';
		}
		return false;
	},
	
	user_state: function(id, state) {
		$('chatty_list').style.display = 'none';
		var user = this.users[id];

		if (!state) state = user.state == 'down' ? 'show' : 'down';

		switch (state) {
			case 'show':
				if (user.state == 'hide') $('chatty').appendChild(user.div);
				if (this.blinks[id]) this.blinks[id] = false;
				for (var i in this.users) if (i != id && this.users[i].state == 'show') {
					this.users[i].chat.style.display = 'none';
					this.users[i].state = 'down';
				}
				user.chat.style.display = '';
				user.list.scrollTop = 10000;
			break;
			case 'down':
				if (user.state == 'hide') $('chatty').appendChild(user.div);
				user.chat.style.display = 'none';
			break;
			case 'hide':
				if (user.state != 'hide') $('chatty').removeChild(this.users[id].div);
			break;
		}

		user.state = state;
		
		var serialize = [];
		for (i in this.users) serialize.push(i+':'+this.users[i].state);
		Cookies.set('chatusers', serialize.join(','), 7);

		return false;
	},
	
	user_create: function(id) {
		var div = document.createElement('div');
		div.className = 'chatty_item';
		div.innerHTML = '<img src="/style/cancel.png" alt="chiudi" width="16" height="16" style="display:inline;vertical-align:top" onclick="return Chat.user_state('+id+',\'hide\')"/> <a href="#" onclick="return Chat.user_state('+id+')">'+this.users[id].user+'</a>';

		var chat = document.createElement('div');
		chat.className = 'chatty_chat';
		chat.innerHTML = '<ul class="chat"></ul><form onsubmit="return Chat.send(this)"><input type="hidden" name="user" value="'+id+'"/><input type="text" name="row" class="row" maxlength="255"/></form>';
		chat.style.display = 'none';
		div.appendChild(chat);

		this.users[id].div = div;
		this.users[id].chat = chat;
		this.users[id].list = chat.getElementsByTagName('ul')[0];
		this.users[id].state = 'hide';
	},

	callback: function(par_local, par_remote) {
		try {
			var i, id, ul = $('chatty_list');
			var users = eval("("+par_remote.users+")");

			// Users list
			for (id in users) {
				if (users[id]['me']) {
					Chat.me = users[id];
				} else {
					if (!Chat.users[id]) {
						var li = document.createElement('li');
						li.innerHTML = '&raquo; <a href="#" onclick="Chat.user_state('+users[id].id+',\'show\')">'+users[id].user+'</a>';
						Chat.users[users[id].id] = users[id];
						Chat.users[users[id].id].li = li;
						ul.appendChild(li);
						Chat.user_create(id);
					}
				}
			}

			for (id in Chat.users) if (!users[id]) {
				try {
					ul.removeChild(Chat.users[id].li)
				} catch (e) {
					/* nothing */
				}
			}
			if (par_local) {
				var init;
				if (init = Cookies.get('chatusers')) {
					init = init.split(',');
					for (i = 0; i < init.length; i++) {
						init[i] = init[i].split(':');
						if (Chat.users[init[i][0]]) Chat.user_state(init[i][0], init[i][1]);
					}
				}
			}

			// Messages
			var messages
			if (messages = eval(par_remote.messages)) for (i = 0; i < messages.length; i++) {
				var li = document.createElement('li');
				li.setAttribute('title', messages[i].datetime);

				if (messages[i].user_to == Chat.me.id) {
					id = messages[i].user_from;
					if (!users[id]) continue;
					li.className = 'recv';
					li.innerHTML = '<b>&raquo; '+users[id].user+ '</b><br/>'+messages[i].message;
					if (Chat.users[id].state != 'show') Chat.blinks[id] = true;
				} else {
					id = messages[i].user_to;
					if (!users[id]) continue;
					li.className = 'send';
					li.innerHTML = messages[i].message;
					li.innerHTML = '<b>&raquo; '+Chat.me.user+ '</b><br/>'+messages[i].message;
				}

				Chat.users[id].list.appendChild(li);
				Chat.users[id].list.scrollTop = 10000;
				if (Chat.users[id].state == 'hide') Chat.user_state(id, 'down');

				soundPlay('/chatty/ding.wav');

				if (parseInt(messages[i].id) > Chat.lastid) Chat.lastid = parseInt(messages[i].id);
			}

			if (par_local) for (id in Chat.blinks) if (id != 'state') Chat.blinks[id] = false;
		} catch (e) {
			alert('Errore: '+e.message);
		}
	},

	send: function(form) {
		ajax.wrapper_post(this.url, 'lastid='+this.lastid, 'user='+form.user.value+'&row='+encodeURIComponent(form.row.value), Chat.callback);
		form.row.value = '';
		this.timer = this.timer_d;
		return false;
	},
	
	timeout: function(init) {
		for (var id in this.blinks) {
			if (id == 'state' || !this.blinks[id]) continue;
			this.users[id].div.className = this.blinks.state ? 'chatty_item blink' : 'chatty_item';
		}
		this.blinks.state++;
		this.blinks.state %= 2;

		if (--this.timer > 0) return;
		ajax.wrapper_get(this.url, 'lastid='+this.lastid, Chat.callback, init);
		this.timer = this.timer_d;
	},
	
	toggle: function() {
		var chatty = $('chatty');

		if (Chat.timer_h) {
			clearInterval(Chat.timer_h);
			Chat.timer_h = null;
			Cookies.set('chatstatus', 'hide', 7);
			this.set_state(false);
		} else {
			Chat.timer = this.timer_d;
			Chat.timer_h = setInterval("Chat.timeout()", 1000);
			Cookies.del('chatstatus');
			this.set_state(true);
		}
		return false;
	},
	
	set_state: function(m) {
		var chatty = $('chatty');

		if (m) {
			chatty.style.width = '100%';
			chatty.style.borderRightWidth = '0';
			chatty.style.overflow = '';
		} else {
			for (var i in this.users) this.users[i].chat.style.display = 'none';
			chatty.style.width = '23px';
			chatty.style.borderRightWidth = '1px';
			chatty.style.overflow = 'hidden';
		}
	}
}

document.write('<div id="chatty" style="display:none"><div id="chatty_status"><ul id="chatty_list" style="display:none"></ul><img src="/style/nintendo.gif" alt="apri chiudi" title="Attiva / Disattiva" width="16" height="16" style="display:inline;vertical-align:top" onclick="return Chat.toggle()"/> <a href="#" onclick="return Chat.list_switch()">Chat</a></div></div>');

if (Cookies.get('chatstatus') == 'hide') {
	Chat.set_state(false);
} else {
	Chat.set_state(true);
	Chat.timeout(true);
	Chat.timer_h = setInterval("Chat.timeout()", 500);
}
