/**
* chat.js
*
* @package Chat
* @version 0.1
* @copyright (c) 2008 LEW21
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/

chat = {
	action: null,

	construct: function()
	{
		chat.template.construct();
		chat.updater.construct();
		chat.postingEngine.construct();
	},

	template: null, // To be set by the template.

	updater: {
		updateEveryXSeconds: 5,

		running: false,
		XHRObject: null,
		interval: null,
		lastMessageID: null,

		construct: function()
		{
			if (!window.XMLHttpRequest)
			{
				return;
			}

			chat.updater.XHRObject = new XMLHttpRequest();
			chat.updater.interval  = window.setInterval(this.checkForChanges, this.updateEveryXSeconds * 1000);
		},

		checkForChanges: function()
		{
			if (chat.postingEngine.running || chat.updater.running)
			{
				// Running two XHR request at one time is a bad idea.
				return;
			}

			chat.updater.running = true;
			chat.updater.XHRObject.open('GET', chat.action + '&mode=getNew&messageID=' + chat.updater.lastMessageID, true);
			chat.updater.XHRObject.onreadystatechange = chat.updater.onReadyStateChange;
			chat.updater.XHRObject.send(null);
		},

		onReadyStateChange: function()
		{
			if (chat.updater.XHRObject.readyState == 4)
			{
				chat.updater.applyChanges();
			}
		},

		applyChanges: function()
		{
			chat.updater.running = false;

			if (!chat.updater.XHRObject.responseXML)
			{
				return;
			}

			var response = chat.updater.XHRObject.responseXML.documentElement;
			if (!response.hasChildNodes())
			{
				return;
			}
			var responseChildren = response.childNodes;

			for (var i = 0; i < responseChildren.length; i++)
			{
				var messages = responseChildren[i];

				if (!messages.getAttribute('id'))
				{
					// null error... No idea why it occurs, but it occurs.
					return;
				}

				if (!document.getElementById(messages.getAttribute('id')))
				{
					chat.template.addDate(messages.getAttribute('id'), messages.getAttribute('date'));
				}

				var messages = messages.childNodes;

				for (var j = 0; j < messages.length; j++)
				{
					var message = messages[j];
					chat.template.addMessage(message.getAttribute('id'), message)
					chat.updater.lastMessageID = message.getAttribute('id');
				}
			}
		}
	},

	postingEngine: {
		lang: null, // To be set by the template.
		running: false,
		XHRObject: null, // To be set by postingEngine.post and deleted by postingEngine.handleResult.

		construct: function()
		{
			// :)
		},

		// Should be called by the template
		post: function(form)
		{
			if (!window.XMLHttpRequest)
			{
				// Continue without AJAX.
				return true;
			}

			if (chat.postingEngine.running)
			{
				alert(chat.postingEngine.lang.engineRunning);
				return false;
			}

			if (!form.message.value)
			{
				alert(chat.postingEngine.lang.emptyMessage);
				return false;
			}

			chat.postingEngine.running = true;

			if (chat.template.onMessageSent)
			{
				chat.template.onMessageSent();
			}

			var postdata = encodeURIComponent('message') + '=' + encodeURIComponent(form.message.value);

			action = chat.action + '&mode=post';
			if (form.author)
			{
				action += '&author=' + author;
			}

			if (chat.postingEngine.XHRObject)
			{
				alert(chat.postingEngine.lang.engineRunning);
				return false;
			}

			chat.postingEngine.XHRObject = new XMLHttpRequest();

			chat.postingEngine.XHRObject.open('POST', action, true);
			chat.postingEngine.XHRObject.onreadystatechange = chat.postingEngine.onReadyStateChange;
			chat.postingEngine.XHRObject.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
			chat.postingEngine.XHRObject.send(postdata);

			return false;
		},

		onReadyStateChange: function()
		{
			if (chat.postingEngine.XHRObject.readyState == 4)
			{
				chat.postingEngine.handleResult();
			}
		},

		handleResult: function()
		{
			chat.postingEngine.running = false;

			if (chat.template.onMessagePosted)
			{
				chat.template.onMessagePosted();
			}

			var response = chat.postingEngine.XHRObject.responseXML.documentElement;

			if (response.getAttribute('type') == 'OK')
			{
				if (chat.template.onMessagePostedSuccessfully)
				{
					chat.template.onMessagePostedSuccessfully(response);
				}

				chat.updater.checkForChanges();
			}
			else
			{
				if (chat.template.onPostingErrorOccured)
				{
					chat.template.onPostingErrorOccured(response);
				}

				alert(chat.postingEngine.lang.errorOccured.title + ' ' + chat.postingEngine.lang.errorOccured.type + ': ' + response.getAttribute('type') + ', ' + chat.postingEngine.lang.errorOccured.message + ': ' + ((response.textContent) ? response.textContent : response.innerText));
			}

			chat.postingEngine.XHRObject = undefined;
		}
	}
}
