/**
 * @author	Sebastian Oettl
 * @copyright	2009-2010 WCF Solutions <http://www.wcfsolutions.com/index.php>
 * @license	GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
 */
var Shoutbox = Class.create({
	/**
	 * Inits Shoutbox.
	 */
	initialize: function(shoutboxID, entries, lastUpdateTime) {
		this.shoutboxID = shoutboxID;
		this.lastUpdateTime = lastUpdateTime;
		this.standby = false;
		this.options = Object.extend({
			langDeleteEntry:	'',
			langDeleteEntrySure:	'',
			imgDeleteEntrySrc:	'',
			entryReloadInterval: 	0,
			entrySortOrder: 	'ASC',
			unneededUpdateLimit:	1
		}, arguments[3] || { });
		this.unneededUpdates = 0;
		
		// remove entries
		$(this.shoutboxID+'Content').update();
		
		// show smileys
		$(this.shoutboxID+'SmileyContainer').removeClassName('hidden');
		
		// add event listener
		$(this.shoutboxID+'EntryAddForm').onsubmit = function() { this.addEntry(); return false; }.bind(this);
		
		// set entries
		this.addEntries(entries);
		
		// start entry update
		this.startEntryUpdate();
	},
	
	/**
	 * Starts the entry update.
	 */
	startEntryUpdate: function() {
		if (this.options.entryReloadInterval != 0) {
			this.executer = new PeriodicalExecuter(this.updateEntries.bind(this), this.options.entryReloadInterval);
		}
	},
	
	/**
	 * Stops the entry update.
	 */
	stopEntryUpdate: function() {
		if (this.options.entryReloadInterval != 0) {
			this.executer.stop();
		}
	},
	
	/**
	 * Starts the standby mode.
	 */
	startStandby: function() {
		if (!this.standby) {			
			this.standby = true;
			
			// change opacity
			new Effect.Opacity(this.shoutboxID+'Content', { from: 1, to: 0.5 });
		}
	},
	
	/**
	 * Stops the standby mode.
	 */
	stopStandby: function() {
		if (this.standby) {
			this.standby = true;
			this.unneededUpdates = 0;
			
			// change opacity
			new Effect.Opacity(this.shoutboxID+'Content', { from: 0.5, to: 1 });
		}
	},	
	
	/**
	 * Inserts a smiley.
	 */
	insertSmiley: function(code) {
		var shoutboxMessage = $('shoutboxMessage');
		shoutboxMessage.value = shoutboxMessage.value+' '+code+' ';
		shoutboxMessage.focus();
	},
	
	/**
	 * Adds a new entry.
	 */
	addEntry: function() {
		// get message
		var message = $(this.shoutboxID+'Message').value;

		// get username
		var username = '';
		if ($(this.shoutboxID+'Username')) username = $(this.shoutboxID+'Username').value;

		// add entry
		new Ajax.Request('index.php?action=ShoutboxEntryAdd'+SID_ARG_2ND, {
			method: 'post',
			parameters: {
				message: message,
				username: username,
				ajax: 1
			},
			onSuccess: function() {
				// reset message
				var messageInputField = $(this.shoutboxID+'Message');
				messageInputField.value = '';
				messageInputField.focus();

				// stop update
				this.stopEntryUpdate();

				// update entries
				this.updateEntries();
				
				// restart entry update			
				if (this.standby) {
					this.stopStandby();
				}
				this.startEntryUpdate();
			}.bind(this),
			onFailure: function(response) {
				alert(response.responseText);
			}
		});
	},

	/**
	 * Deletes an entry.
	 */	
	deleteEntry: function(id) {
		new Ajax.Request('index.php?action=ShoutboxEntryDelete&t='+SECURITY_TOKEN+SID_ARG_2ND, {
			method: 'post',
			parameters: {
				entryID: id,
				ajax: 1
			},
			onSuccess: function() {				
				// remove entry row
				var row = $(this.shoutboxID+'Entry'+id);
				if (row) {
					row.blindUp();
				}
			}.bind(this)
		});
	},
	
	/**
	 * Updates the entries.
	 */
	updateEntries: function() {
		// start request
		new Ajax.Request('index.php?page=ShoutboxEntryXMLList&t='+SECURITY_TOKEN+SID_ARG_2ND, {
			method: 'post',
			parameters: {
				startTime: this.lastUpdateTime
			},
			onSuccess: function(response) {			
				// get entries
				var entries = response.responseXML.getElementsByTagName('entries');
				if (entries.length > 0) {
					if (entries[0].childNodes.length == 0) {
						this.unneededUpdates++;
						if (this.options.unneededUpdateLimit != 0 && this.unneededUpdates >= this.options.unneededUpdateLimit) {
							this.startStandby();
							this.stopEntryUpdate();
						}
						return;
					}
					var newEntries = new Hash();
					for (var i = 0; i < entries[0].childNodes.length; i++) {
						newEntries.set(entries[0].childNodes[i].childNodes[0].childNodes[0].nodeValue, {
							userID: entries[0].childNodes[i].childNodes[1].childNodes[0].nodeValue,
							username: entries[0].childNodes[i].childNodes[2].childNodes[0].nodeValue,
							time: entries[0].childNodes[i].childNodes[4].childNodes[0].nodeValue,
							message: entries[0].childNodes[i].childNodes[5].childNodes[0].nodeValue,
							canDelete: entries[0].childNodes[i].childNodes[6].childNodes[0].nodeValue
						});
						
						// set last update time
						if (i == entries[0].childNodes.length - 1) {
							this.lastUpdateTime = entries[0].childNodes[i].childNodes[3].childNodes[0].nodeValue;
						}
					}
					this.unneededUpdates = 0;
					this.addEntries(newEntries, true);
				}
			}.bind(this)
		});
	},
	
	/**
	 * Adds the given entries to the shoutbox.
	 */
	addEntries: function(entries, animate) {
		var shoutboxMessageDiv = $(this.shoutboxID+'Content');
		if (shoutboxMessageDiv) {
			// update shoutbox content
			var idArray = entries.keys();
			if (idArray.length > 0) {
				for (var i = 0; i < idArray.length; i++) {
					var id = idArray[i];
					var entry = entries.get(id);
					
					// update entry string
					var newEntryString = '<p id="'+this.shoutboxID+'Entry'+id+'" style="display: none;"><span class="light">['+entry.time+']</span>'+(entry.canDelete != 0 ? ' <a href="javascript:shoutbox.deleteEntry('+id+')" onclick="return confirm(\''+this.options.langDeleteEntrySure+'\')" title="'+this.options.langDeleteEntry+'"><img src="'+this.options.imgDeleteEntrySrc+'" alt="" /></a>' : '')+' '+(entry.userID != 0 ? '<a href="'+'index.php?page=User&userID='+entry.userID+SID_ARG_2ND+'">'+entry.username+'</a>' : entry.username)+': '+entry.message+'</p>';
				
					// insert new entry
					if (this.options.entrySortOrder == 'ASC') {
						shoutboxMessageDiv.insert({ bottom: newEntryString });
					}
					else {
						shoutboxMessageDiv.insert({ top: newEntryString });
					}
					
					var shoutboxEntryDiv = $(this.shoutboxID+'Entry'+id);
					if (shoutboxEntryDiv) {
						if (animate) {
							shoutboxEntryDiv.blindDown();
						}
						else {
							shoutboxEntryDiv.show();
						}
					}
				}
				
				// focus last entry
				if (this.options.entrySortOrder == 'ASC') {
					var scroller = function() {
						shoutboxMessageDiv.scrollTop = shoutboxMessageDiv.scrollHeight - shoutboxMessageDiv.offsetHeight + 100;
					};
					if (animate) {
						new PeriodicalExecuter(function() {
							scroller();
							this.stop();
						}, 1);
					}
					else {
						scroller();
					}
				}
			}
		}
	}
});
