/*======================================================================*\

|| #################################################################### ||

|| # ---------------------------------------------------------------- # ||

|| # Copyright ©2007-2009 Fillip Hannisdal AKA Revan/NeoRevan/Belazor # ||

|| # All Rights Reserved. 											  # ||

|| # This file may not be redistributed in whole or significant part. # ||

|| # ---------------------------------------------------------------- # ||

|| # You are not allowed to use this on your server unless the files  # ||

|| # you downloaded were done so with permission.					  # ||

|| # ---------------------------------------------------------------- # ||

|| #################################################################### ||

\*======================================================================*/



// #######################################################################

// ######################## START MAIN SCRIPT ############################

// #######################################################################



// #############################################################################

// Setup the main object

vBShout_Obj = function()

{

	// Object variables

	this.ajax			= new Array();	// Array of AJAX objects

	this.frames			= new Array();	// A list of all the frames we interact with

	this.timers			= new Array();	// A list of all the timers we keep track of

	this.lookup			= new Array();	// A list of all the users we have PMed at some point (userid - username)

	this.lookup2		= new Array();	// A list of all the chat rooms we have talked in at some point (chatroomid - roomname)

	this.aoptime		= new Array();	// Set this to when we last fetched from the database	

	this.editor 		= {				// A list of all editor styling we may apply

		'bold' 		: '',

		'italic'	: '',

		'underline'	: '',

		'color'		: '',

		'font'		: 'Tahoma',

		'size'		: '11px'

	};

	this.tabs			= {				// A list of all the tabs we are playing with

		'shouts'		: true,

		'activeusers'	: true

	};

	this.smilies;						// Captain Placeholder of the Smiley Popup Functions Brigade

	this.fonts;							// Captain Placeholder of the Font Dropdown Functions Brigade

	this.colors;						// Captain Placeholder of the Color Dropdown Functions Brigade

	this.fontstyles;					// Captain Placeholder of the Bold/Italic/Underline Button Functions Brigade	

	

	// Integer variables

	this.instanceid		= 1;			// What instance we are working with

	this.floodcheck		= 3;			// How big a delay (in seconds) between shouts

	this.refreshtime	= 5;			// How often (in seconds) to auto-refresh

	this.refreshtime2	= 0;			// How often (in seconds) to auto-refresh

	this.idlerefreshtime= 0;			// How often (in minutes) to auto-refresh

	this.idlelimit		= 180;			// A counter for how long we've been idle

	this.idletime		= 0;			// A counter for how long we've been idle

	this.scrollpos		= 0;			// Helper to determine whether the scrollbar has moved

	this.maxlength		= 256;			// The maximum length of a shout

	this.shoutid		= 0;			// Set this to > 0 when editing a shout

	this.lastshout		= 0;			// Set this to when we last shouted

	this.pmuserid		= 0;			// Userid of the person we are PMing

	this.menuid			= 0;			// Open username dropdown menu

	this.pmtime			= 0;			// PM Time

	

	// Boolean variables

	this.aop			= false;		// Whether we're using the optimisation protocol

	this.detached		= false;		// Whether we're viewing the shoutbox in detached mode

	this.idle			= false;		// Whether we're idle at all

	

	// String variables

	this.shoutorder		= 'ASC';		// The direction in which we're shouting (DESC = Newest First - ASC = Oldest First)

	this.editorid		= 'dbtech_shoutbox_editor';		// ID of the editor

	this.tab			= 'shouts';		// Where we are by default

	this.shoutstore		= '';





	// #########################################################################

	// Initialise the Shoutbox

	this.init = function()

	{

		if (!AJAX_Compatible)

		{

			// AJAX won't work, this is foar srs.

			this.set_message('Either your browser does not support AJAX, or the forum administrator has chosen to disable AJAX. vBShout cannot run under these conditions.', 'error');

			// REPLACESTRING

			

			return false;

		}

		

		// Ensure we have this in minutes

		this.idlerefreshtime 	= this.idlerefreshtime * 60;

		

		// Backup

		this.refreshtime2 		= this.refreshtime;

		

		eval("this.vbshout = vBShout" + this.instanceid + ";");

		

		// Set our frames

		this.frames['shoutframe'] 	= YAHOO.util.Dom.get('dbtech_shoutbox_frame' + this.instanceid);			// The surrounding master frame

		this.frames['content'] 		= YAHOO.util.Dom.get('dbtech_shoutbox_content' + this.instanceid);			// The main shoutbox area

		this.frames['editor'] 		= YAHOO.util.Dom.get(this.editorid + this.instanceid);						// The shoutbox editor

		this.frames['tabs'] 		= YAHOO.util.Dom.get('dbtech_shoutbox_tabs' + this.instanceid);				// The shoutbox tabs

		this.frames['activeusers']	= YAHOO.util.Dom.get('dbtech_shoutbox_activeusers' + this.instanceid);		// The Active Users count

		this.frames['charcount']	= YAHOO.util.Dom.get('dbtech_shoutbox_remainingchars' + this.instanceid);	// The Remaining Characters count

		

		// Initialise any enabled editor tools

		this.init_editor_tools();

		

		if (this.frames['editor'])

		{

			// Check the input length

			this.check_length();

		}

		

		// Finally fetch the shouts

		this.fetch(this.tab, true);

		

		if (this.idle)

		{

			// We should be flagged as idle

			this.flag_idle();

		}

		else

		{

			// Schedule idle check

			this.check_idle();

			

			// Schedule fetching shouts 

			this.schedule_refresh();

		}

		

		// Store the phrased variable

		var everyone 	= YAHOO.util.Dom.get('dbtech_shoutbox_everyone' + this.instanceid);

		if (everyone)

		{

			this.everyone 	= everyone.innerHTML;

		}

	}

	

	// #########################################################################	

	// Shorthand to schedule a refresh of the shouts

	this.schedule_refresh = function()

	{

		// Log a debug message to the console

		console.log(this.timestamp() + "Scheduling fetching current tab every %s seconds", this.refreshtime);

		

		// Clear the shout refresh interval

		clearInterval(this.timers['tab']);

		

		// Setup the schedule

		this.timers['tab'] = setInterval("vBShout" + this.instanceid + ".fetch();", (this.refreshtime * 1000));		

	}

	

	// #########################################################################	

	// Initialises various editor tools

	this.init_editor_tools = function()

	{

		if (typeof vBShout_Smilies_Obj != 'undefined')

		{

			// Initialise the smilies reference

			this.smilies = new vBShout_Smilies_Obj();

			

			// Set the editor id

			this.smilies.init(this.editorid, this.instanceid);

		}

		

		if (typeof vBShout_Fonts_Obj != 'undefined')

		{

			// Intialise the fonts reference

			this.fonts = new vBShout_Fonts_Obj();

			

			// Begin hacking the fonts dropdown

			this.fonts.init('dbtech_shoutbox_editor_wrapper', this.editor['font'], this.instanceid);

		}

		else

		{

			if (YAHOO.util.Dom.get('dbtech_shoutbox_editor_wrapper_fontfield' + this.instanceid))

			{

				var fontssel = YAHOO.util.Dom.get('dbtech_shoutbox_editor_wrapper_fontfield' + this.instanceid);

				if (this.editor['font'] != '')

				{

					for (var i = 0; i < fontssel.options.length; i++)

					{

						if (fontssel.options[i].value == this.editor['font'])

						{

							fontssel.selectedIndex = i;

							break;

						}

					}

				}

			}			

		}

		

		if (typeof vBShout_Sizes_Obj != 'undefined')

		{

			// Intialise the fonts reference

			this.sizes = new vBShout_Sizes_Obj();

			

			// Begin hacking the sizes dropdown

			this.sizes.init('dbtech_shoutbox_editor_wrapper', this.editor['size'], this.instanceid);

		}

		else

		{

			if (YAHOO.util.Dom.get('dbtech_shoutbox_editor_wrapper_size_bar' + this.instanceid))

			{

				var sizessel = YAHOO.util.Dom.get('dbtech_shoutbox_editor_wrapper_size_bar' + this.instanceid);

				if (this.editor['size'] != '')

				{

					for (var i = 0; i < sizessel.options.length; i++)

					{

						if (sizessel.options[i].value == this.editor['size'])

						{

							sizessel.selectedIndex = i;

							break;

						}

					}

				}

			}

		}

		

		if (typeof vBShout_Colors_Obj != 'undefined')

		{

			// Intialise the colors reference

			this.colors = new vBShout_Colors_Obj();

			

			// Begin hacking the colors dropdown

			this.colors.init('dbtech_shoutbox_editor_wrapper', this.editor['color'], this.instanceid);

		}

		else

		{

			if (YAHOO.util.Dom.get('dbtech_shoutbox_editor_wrapper_color_bar' + this.instanceid))

			{			

				var colorssel = YAHOO.util.Dom.get('dbtech_shoutbox_editor_wrapper_color_bar' + this.instanceid);

				if (this.editor['color'] != '')

				{

					for (var i = 0; i < colorssel.options.length; i++)

					{

						if (colorssel.options[i].value == this.editor['color'])

						{

							colorssel.selectedIndex = i;

							break;

						}

					}

				}

			}

		}

		

		if (typeof vBShout_FontStyle_Obj != 'undefined')

		{

			// Intialise the font styles reference

			this.fontstyles = new vBShout_FontStyle_Obj();

			

			// Begin hacking the font styles buttons

			this.fontstyles.init('dbtech_shoutbox_editor_wrapper', this.editor['bold'], this.editor['italic'], this.editor['underline'], this.instanceid);

		}

		else

		{

			if (YAHOO.util.Dom.get('dbtech_shoutbox_editor_wrapper_cmd_bold' + this.instanceid))

			{

				var boldbtn = YAHOO.util.Dom.get('dbtech_shoutbox_editor_wrapper_cmd_bold' + this.instanceid);

				if (this.editor['bold'] != '')

				{

					boldbtn.value = 'B [*]';

				}

			}			

			if (YAHOO.util.Dom.get('dbtech_shoutbox_editor_wrapper_cmd_italic' + this.instanceid))

			{

				var italicbtn = YAHOO.util.Dom.get('dbtech_shoutbox_editor_wrapper_cmd_italic' + this.instanceid);

				if (this.editor['italic'] != '')

				{

					italicbtn.value = 'I [*]';

				}

			}			

			if (YAHOO.util.Dom.get('dbtech_shoutbox_editor_wrapper_cmd_underline' + this.instanceid))

			{

				var underlinebtn = YAHOO.util.Dom.get('dbtech_shoutbox_editor_wrapper_cmd_underline' + this.instanceid);

				if (this.editor['underline'] != '')

				{

					underlinebtn.value = 'U [*]';

				}

			}			

		}

		

		if (typeof vBShout_Sounds_Obj != 'undefined')

		{

			// Intialise the sounds reference

			this.sounds = new vBShout_Sounds_Obj();

			

			// Init the sounds

			this.sounds.init(this.instanceid);

		}

	}

	

	// #########################################################################	

	// Toggles the bold button (3.8 onry)

	this.toggle_bold = function()

	{

		var boldbtn = YAHOO.util.Dom.get('dbtech_shoutbox_editor_wrapper_cmd_bold' + this.instanceid);

		if (this.editor['bold'] == '')

		{

			this.update_style_property('bold', 'bold');			

			boldbtn.value = 'B [*]';

		}

		else

		{

			this.update_style_property('bold', '');			

			boldbtn.value = 'B';

		}

	}

	

	// #########################################################################	

	// Toggles the italic button (3.8 onry)

	this.toggle_italic = function()

	{

		var italicbtn = YAHOO.util.Dom.get('dbtech_shoutbox_editor_wrapper_cmd_italic' + this.instanceid);

		if (this.editor['italic'] == '')

		{

			this.update_style_property('italic', 'italic');			

			italicbtn.value = 'I [*]';

		}

		else

		{

			this.update_style_property('italic', '');			

			italicbtn.value = 'I';

		}

	}

	

	// #########################################################################	

	// Toggles the underline button (3.8 onry)

	this.toggle_underline = function()

	{

		var underlinebtn = YAHOO.util.Dom.get('dbtech_shoutbox_editor_wrapper_cmd_underline' + this.instanceid);

		if (this.editor['underline'] == '')

		{

			this.update_style_property('underline', 'underline');			

			underlinebtn.value = 'U [*]';

		}

		else

		{

			this.update_style_property('underline', '');			

			underlinebtn.value = 'U';

		}

	}

	

	// #########################################################################	

	// Toggles the fontstyle (3.8 onry)

	this.toggle_fontstyle = function()

	{

		var fontssel = YAHOO.util.Dom.get('dbtech_shoutbox_editor_wrapper_fontfield' + this.instanceid);

		

		this.update_style_property('font', fontssel.value);			

	}

	

	// #########################################################################	

	// Toggles the fontcolor (3.8 onry)

	this.toggle_fontcolor = function()

	{

		var colorssel = YAHOO.util.Dom.get('dbtech_shoutbox_editor_wrapper_color_bar' + this.instanceid);

		

		this.update_style_property('color', colorssel.value);			

	}

	

	// #########################################################################	

	// Toggles the size (3.8 onry)

	this.toggle_size = function()

	{

		var sizessel = YAHOO.util.Dom.get('dbtech_shoutbox_editor_wrapper_size_bar' + this.instanceid);

		

		this.update_style_property('size', sizessel.value);			

	}

	

	// #########################################################################	

	// Updates the style properties based on the Editor Tools selections

	this.update_style_property = function(type, value, noupdate)

	{

		// Default to the same property as the style type

		var property 	= type;

		var setValue	= value;

		switch (type)

		{

			case 'bold':

				property 	= 'fontWeight';

				setValue = (value ? type : '');

				break;

				

			case 'italic':

				property 	= 'fontStyle';

				setValue = (value ? type : '');

				break;

				

			case 'underline':

				property 	= 'textDecoration';

				setValue = (value ? type : '');

				break;

				

			case 'font':

				property 	= 'fontFamily';

				break;

				

			case 'size':

				property 	= 'fontSize';

				break;

		}

		

		// Log a debug message to the console

		console.log(this.timestamp() + "Style property %s set. Value: %s.", type, setValue);

		

		if (type == 'size')

		{

			// Set the editor style

			eval("this.frames['shoutframe'].style." + property + " = '" + setValue + "';");

		}

		else

		{

			// Set the editor style

			eval("this.frames['editor'].style." + property + " = '" + setValue + "';");

		}

		

		if (this.editor[type] != value && !noupdate)

		{

			// Log a debug message to the console

			console.log(this.timestamp() + "Style property %s changed. Old value: %s - New value: %s", type, this.editor[type], value);

			

			// Change the editor type

			this.editor[type] = value;

			

			// Save the style properties

			this.save_editor_styles();

		}

	}

	

	// #########################################################################	

	// Clear the contents of the editor

	this.clear = function()

	{

		// Log a debug message to the console

		console.log(this.timestamp() + "Removing contents of the editor.");

		

		// Clear the contents of the editor

		this.frames['editor'].value = '';

		this.check_length();

	}

	

	// #########################################################################	

	// Inserts a command

	this.set_command = function(cmd)

	{

		// Clear the contents of the editor

		this.frames['editor'].value = cmd + ' ';

		this.frames['editor'].focus();

		this.check_length();

		

		return false;

	}

	

	// #########################################################################	

	// Shorthand for command

	this.chat_invite = function()

	{

		// Set the invite command

		this.set_command('/invite');

		

		return false;

	}



	// #########################################################################	

	// Cancels editing a shout

	this.cancel_shout_editing = function()

	{

		// Remove all evidence of editing a shout

		this.shoutid = 0;

		YAHOO.util.Dom.get('dbtech_shoutbox_deletebutton' + this.instanceid).style.display = 'none';

		
		// Help text change

		YAHOO.util.Dom.get('dbtech_shoutbox_target' + this.instanceid).style.display = 'inline';

		YAHOO.util.Dom.get('dbtech_shoutbox_editing' + this.instanceid).style.display = 'none';

		

		// Clear the editor

		this.clear();

	}

	

	// #########################################################################	

	// Function to begin PMing an user

	this.create_pm = function(userid, username)

	{

		if (!this.lookup[userid])

		{

			// Add the username to the lookup

			this.lookup[userid] = username;

		}

		

		// Creates a new PM to a given user

		this.add_tab('pm_' + userid + '_', username, true, "show_pm_tab('" + userid + "')", "close_pm_tab(this, '" + userid + "')");

		

		// Shows the PM tab

		this.show_pm_tab(userid);

		

		// Close any open menus we have

		this.toggle_menu(this.menuid);

		

		return false;

	}

	

	// #########################################################################	

	// Function to display a PM tab

	this.show_pm_tab = function(userid)

	{

		if (this.tab == 'pm_' + userid + '_' + this.instanceid)

		{

			// We're already viewing this PM tab.

			return false;

		}

		

		// Blank this out just in case we have no PMs

		this.frames['content'].innerHTML = '';

		

		// Show the tab

		this.show_tab('pm_' + userid + '_', true);

		

		// Set new PM User

		this.pmuserid = userid;

		

		// Update who we're shouting to

		this.set_shout_target(this.lookup[userid]);

		

		return false;

	}

	

	// #########################################################################	

	// Function to close a PM tab	

	this.close_pm_tab = function(tabobj, userid)

	{

		if (this.tab == 'pm_' + userid + '_')

		{

			// We were viewing this PM tab.

			this.pmuserid = 0;

			this.set_shout_target(false);

		}

		

		// Close the tab

		this.close_tab(tabobj, 'pm_' + userid + '_');

		

		return false;

	}

	

	// #########################################################################	

	// Function to create a chat room tab

	this.create_chatroom_tab = function(chatroomid, roomname, canclose)

	{

		// Creates a new PM to a given user

		this.add_tab('chatroom_' + chatroomid + '_', roomname, canclose, "show_chatroom_tab('" + chatroomid + "')", "close_chatroom_tab(this, '" + chatroomid + "')");

		

		// Close any open menus we have

		this.toggle_menu(this.menuid);

		

		return false;

	}

	

	// #########################################################################	

	// Function to display a PM tab

	this.show_chatroom_tab = function(chatroomid)

	{

		if (this.tab == 'chatroom_' + chatroomid + '_' + this.instanceid)

		{

			// We're already viewing this chatroom tab.

			return false;

		}

		

		// Blank this out just in case we have no PMs

		this.frames['content'].innerHTML = '';

		

		// Show the tab

		this.show_tab('chatroom_' + chatroomid + '_', true);

		

		// Set new PM User

		this.chatroomid = chatroomid;

		

		// Update who we're shouting to

		//this.set_shout_target(this.lookup[userid]);

		

		return false;

	}

	

	// #########################################################################	

	// Function to close a chatroom tab	

	this.close_chatroom_tab = function(tabobj, chatroomid)

	{

		if (this.tab == 'chatroom_' + chatroomid + '_')

		{

			// We were viewing this PM tab.

			this.chatroomid = 0;

			//this.set_shout_target(false);

		}

		

		if (confirm('Are you sure you wish to leave this chat room?'))

		{

			// Leave the chatroom with shit and stuff

			this.leave_chatroom(chatroomid);

		

			// Close the tab

			this.close_tab(tabobj, 'chatroom_' + chatroomid + '_');

		}

		

		return false;

	}

	

	// #########################################################################	

	// Adds a tab

	this.add_tab = function(tabid, text, canclose, showfunc, closefunc)

	{

		// Ensure these are not nil

		showfunc 	= showfunc 	? showfunc 	: "show_tab('" + tabid + "')";

		closefunc 	= closefunc ? closefunc : "close_tab(this, '" + tabid + "')";

		

		if (this.tabs[tabid])

		{

			// Show this tab instead

			eval('this.' + showfunc + ';');

			return false;

		}

		

		// This tab now exists

		this.tabs[tabid] = true;

		

		var html = '';

		if (canclose)

		{

			// We can close the tab

			html += ' [<a href="javascript://" onclick="return vBShout' + this.instanceid + '.' + closefunc + ';">X</a>]';

		}

		

		// Create the tab

		cellposition = this.frames['tabs'].rows[0].cells.length - 1;

		newtab = this.frames['tabs'].rows[0].insertCell(cellposition);

		newtab.className = 'dbtech_vbshout_tabcontainer';

		newtab.innerHTML = '<div id="' + tabid + this.instanceid + '" class="dbtech_vbshout_tabs alt2"><a href="javascript://" onclick="return vBShout' + this.instanceid + '.' + showfunc + ';" id="tabobj_' + tabid + this.instanceid + '">' + text + '</a>' + html + '</div>';

	}

	

	// #########################################################################	

	// Displays the contents of a tab

	this.show_tab = function(tabid, force)

	{

		if (this.tab != tabid)

		{

			// Log a debug message to the console

			console.log(this.timestamp() + "Switching from %s to %s.", this.tab, tabid);		

		

			if (this.tab.indexOf('pm', 0) > -1)

			{

				// Reset PM info

				this.pmuserid = 0;

				this.set_shout_target(false);

			}

			

			if (this.tab.indexOf('chatroom', 0) > -1)

			{

				// Reset chatroom info

				this.chatroomid = 0;

			}

			

			// Set tab styles

			YAHOO.util.Dom.get(this.tab + this.instanceid).className = 'dbtech_vbshout_tabs alt2';

			YAHOO.util.Dom.get(tabid + this.instanceid).className = 'dbtech_vbshout_tabs alt';

			YAHOO.util.Dom.removeClass(YAHOO.util.Dom.get(tabid + this.instanceid), 'dbtech_vbshout_highlight');

			

			// Set the new content

			this.tab = tabid;

			

			// We're changing shit, so force

			force = true;

		}

		

		//if (force)

		//{

			// We're needing new content

			this.fetch(tabid, true);

		//6}

		

		return false;

	}

	

	// #########################################################################	

	// Closes a tab

	this.close_tab = function(tabobj, tabid)

	{

		// This tab no longer exists

		this.tabs[tabid] = false;

		

		// Removes the tab object

		tabobj.parentNode.parentNode.parentNode.removeChild(tabobj.parentNode.parentNode);

		

		if (this.tab == tabid)

		{

			// We revert to fetching shouts

			this.tab = 'shouts';

			

			// Set tab styles

			YAHOO.util.Dom.get(this.tab + this.instanceid).className = 'dbtech_vbshout_tabs alt';

			

			 // Re-fetches shouts

			this.fetch('shouts', true);

		}

		

		// Log a debug message to the console

		console.log(this.timestamp() + "Switching from %s to %s.", tabid + this.instanceid, this.tab + this.instanceid);		

		

		return false;

	}

	

	// #########################################################################	

	// Sets the shout target

	this.set_shout_target = function(username)

	{

		// Fetch the two objects

		var everyone 	= YAHOO.util.Dom.get('dbtech_shoutbox_everyone' + this.instanceid);

		var user 		= YAHOO.util.Dom.get('dbtech_shoutbox_pmuser' + this.instanceid);

		

		if (everyone)

		{

			if (!username)

			{

				// Reverting to everyone

				everyone.innerHTML		= this.everyone;

			}

			else

			{

				// Setting an username

				everyone.innerHTML 		= PHP.trim(username);

			}

		}

	}

	

	// #########################################################################	

	// Resets the shout target

	this.reset_shout_target = function()

	{

		// Clear out this shit

		this.pmuserid = 0;

		this.set_shout_target(false);

		this.show_tab('shouts');

		

		return false;

	}

	

	// #########################################################################	

	// Repeating function to check if we're idle

	this.check_idle = function()

	{

		if (this.idlelimit == 0 || this.idle)

		{

			// We're not even checking for idle or we're already idle

			return false;

		}

		

		// Log the error to the console

		//console.log(this.timestamp() + "Checking for idle... Have been idle for %s seconds. Limit: %s seconds.", this.idletime, this.idlelimit);		

		

		if (this.idletime >= this.idlelimit)

		{

			// Yep, we're idle

			this.idle = true;

			

			if (this.idlerefreshtime)

			{

				// We're refreshing while idle

				this.refreshtime = this.idlerefreshtime;

			}

			else

			{

				// Clear the shout refresh interval

				clearInterval(this.timers['tab']);			

			}

			

			// We're idle

			this.flag_idle();

			

			// No need to increment it further

			return false;

		}

		

		// Check again in 1 sec

		setTimeout("vBShout" + this.instanceid + ".check_idle()", 1000);

				

		// Increment the time we've been idle

		this.idletime++;

	}

	

	// #########################################################################	

	// Shorthand function to flag as idle

	this.flag_idle = function()

	{

		this.set_message('You are currently showing up as idle. Click <a href="javascript://" onclick="return vBShout' + this.instanceid + '.unidle();">here</a> to resume activity.', 'notice');

		// REPLACESTRING		

	}

	

	// #########################################################################

	// We're no longer idle

	this.unidle = function()

	{

		// Log the error to the console

		console.log(this.timestamp() + 'Removing idle...');		

		

		if (this.idlerefreshtime)

		{

			// We're refreshing while idle

			this.refreshtime = this.refreshtime2;

		}

		

		// We're no longer idle

		this.idletime 	= 1;

		this.idle 		= false;

		

		// Hide the error message

		this.hide_message('notice');

		

		// Begin the timer again

		setTimeout("vBShout" + this.instanceid + ".check_idle()", 1000);

		

		// We're no longer idle, instantly fetch shouts unless we're posting

		this.fetch(this.tab);

		

		// Begin scheduling refreshes of the current tab

		this.schedule_refresh();

	}

	

	

	// #######################################################################

	// ######################## AJAX FUNCTIONS ###############################

	// #######################################################################

	

	// #########################################################################

	// Fetches a given type of content

	this.fetch = function(type, force)

	{

		if (!type)

		{

			// Avoid refreshing problem

			type = this.tab;

		}

		

		if ((!YAHOO.util.Connect.isCallInProgress(this.ajax['posting']) && !this.idle) || force == true)

		{

			// Initialise this

			var extraparams = '';

			

			if (this.idle)

			{

				// We're in idle

				extraparams += '&idle=1';

				force = false;

			}

			

			if (type == 'shouts' && !force && this.aop)

			{

				// Override type since we're not forcing shouts

				type = 'aop';

			}

			

			// Log a debug message to the console

			console.log(this.timestamp() + 'Fetching ' + type + this.instanceid + '...');			

			

			if (this.aop && !force)

			{

				extraparams += '&aoptime=' + this.aoptime[this.tab];

				console.log(this.timestamp() + 'AOP Time ' + this.aoptime[this.tab] + '...');

			}

			

			switch (type)

			{

				case 'shout':

					extraparams += '&shoutid=' + this.shoutid;

					break;

			}

			

			if (this.detached)

			{

				// We're in detached mode

				extraparams += '&detached=1';

			}

			

			for (var i in this.tabs)

			{

				if (this.tabs[i])

				{

					// This is an active tab

					extraparams += '&tabs[' + i + ']=1';

				}

			}

			

			// Set shout order

			extraparams += '&shoutorder=' + this.shoutorder;

			

			// Set instance id

			extraparams += '&instanceid=' + this.instanceid;

			

			// Set tab id

			extraparams += '&pmtime=' + this.pmtime;		

			

			// Set tab id

			extraparams += '&tabid=' + this.tab;		

			

			// Execute AJAX

			YAHOO.util.Connect.asyncRequest('POST', 'ajax.php?do=dbtech_vbshout_fetch', {

				success: this.ajax_completed,

				failure: this.handle_ajax_error,

				timeout: vB_Default_Timeout,

				scope: this

			}, SESSIONURL + 'securitytoken=' + SECURITYTOKEN + '&do=dbtech_vbshout_fetch&type=' + PHP.urlencode(type) + extraparams);

		}

	}

	

	// #########################################################################	

	// Function to create a chat room

	this.create_chatroom = function()

	{

		// Initialise this

		var extraparams = '';

		var roomname = YAHOO.util.Dom.get('roomname' + this.instanceid).value;



		// Set instance id

		extraparams += '&instanceid=' + this.instanceid;

		

		// Execute AJAX

		YAHOO.util.Connect.asyncRequest('POST', 'ajax.php?do=dbtech_vbshout_createchat', {

			success: this.ajax_completed,

			failure: this.handle_ajax_error,

			timeout: vB_Default_Timeout,

			scope: this

		}, SESSIONURL + 'securitytoken=' + SECURITYTOKEN + '&do=dbtech_vbshout_createchat&title=' + roomname + extraparams);

		

		return false;

	}

	

	// #########################################################################	

	// Leaving a chat room

	this.leave_chatroom = function(chatroomid, is_popup)

	{

		if (YAHOO.util.Connect.isCallInProgress(this.ajax['leavechat']) || YAHOO.util.Connect.isCallInProgress(this.ajax['joinchat']))

		{

			// We're not doing anything else yet

			return false;

		}

		

		// Initialise this

		var extraparams = '';

		

		// Set instance id

		extraparams += '&instanceid=' + this.instanceid;

		

		if (is_popup)

		{

			// Set status id

			extraparams += '&status=1';

		}

		

		// Execute AJAX

		this.ajax['leavechat'] = YAHOO.util.Connect.asyncRequest('POST', 'ajax.php?do=dbtech_vbshout_leavechat', {

			success: this.ajax_completed,

			failure: this.handle_ajax_error,

			timeout: vB_Default_Timeout,

			scope: this

		}, SESSIONURL + 'securitytoken=' + SECURITYTOKEN + '&do=dbtech_vbshout_leavechat&chatroomid=' + chatroomid + extraparams);

	}

	

	// #########################################################################	

	// Joining a chat room

	this.join_chatroom = function(chatroomid)

	{

		if (YAHOO.util.Connect.isCallInProgress(this.ajax['leavechat']) || YAHOO.util.Connect.isCallInProgress(this.ajax['joinchat']))

		{

			// We're not doing anything else yet

			return false;

		}

		

		// Initialise this

		var extraparams = '';

		

		// Set instance id

		extraparams += '&instanceid=' + this.instanceid;

		

		// Execute AJAX

		this.ajax['joinchat'] = YAHOO.util.Connect.asyncRequest('POST', 'ajax.php?do=dbtech_vbshout_joinchat', {

			success: this.ajax_completed,

			failure: this.handle_ajax_error,

			timeout: vB_Default_Timeout,

			scope: this

		}, SESSIONURL + 'securitytoken=' + SECURITYTOKEN + '&do=dbtech_vbshout_joinchat&chatroomid=' + chatroomid + extraparams);

	}

		

	// #########################################################################	

	// User Management actions

	this.usermanage = function(action, userid)

	{

		// Initialise this

		var extraparams = '';

		

		var message = '';

		switch (action)

		{

			case 'banunban':

				message = 'Are you sure you wish to ban / unban this user?';

				break;

			

			case 'silenceunsilence':

				message = 'Are you sure you wish to silence / unsilence this user?';

				break;

			

			case 'ignoreunignore':

				message = 'Are you sure you wish to ignore / unignore this user?';

				break;

			

			case 'pruneshouts':

				message = 'Are you sure you wish to prune all shouts from this user?';

				break;

			

			case 'chatremove':

				message = 'Are you sure you wish to remove this user from this Chat Room?';

				break;

		}

		

		if (confirm(message))

		{

			// We're editing a shout

			console.log(this.timestamp() + 'Attempting to perform action %s on userid %s...', action, userid);			

			

			// Set instance id

			extraparams += '&instanceid=' + this.instanceid;

			

			if (this.chatroomid)

			{

				// Set who we're PMing

				extraparams += '&type=chatroom&chatroomid=' + this.chatroomid;

			}

			

			if (this.pmuserid)

			{

				// Set who we're PMing

				extraparams += '&type=pm&pmuserid=' + this.pmuserid;

			}			

			

			// Execute AJAX

			YAHOO.util.Connect.asyncRequest('POST', 'ajax.php?do=dbtech_vbshout_usermanage', {

				success: this.ajax_completed,

				failure: this.handle_ajax_error,

				timeout: vB_Default_Timeout,

				scope: this

			}, SESSIONURL + 'securitytoken=' + SECURITYTOKEN + '&do=dbtech_vbshout_usermanage&action=' + action + '&userid=' + userid + extraparams);

		}

		

		// close whatever open menu we have

		this.toggle_menu(this.menuid);

		

		return false;

	}

		

	// #########################################################################	

	// Submit a new shout or save the editing shout

	this.save = function()

	{

		if (this.frames['editor'].value.length == 0)

		{

			// We don't care about empty shouts

			return false;

		}

		

		// Initialise this

		var extraparams = '';

		

		// Set the current time

		var timenow = new Date().getTime();

		

		if ((timenow - this.lastshout) < (this.floodcheck * 1000) && this.lastshout > 0)

		{

			// Flood check

			this.set_message('You must wait at least ' + this.floodcheck + ' seconds between shouts. It has been ' + parseInt((timenow - this.lastshout) / 1000)  + ' seconds since your last shout.', 'error');

			return false;

		}

		

		// Set our last shout time

		this.lastshout = timenow;

		

 		if (this.shoutid > 0)

		{

			// We're editing a shout

			console.log(this.timestamp() + 'Attempting to save shout: %s...', this.shoutid);			

			

			// Add some extra parameters

			extraparams += '&shoutid=' + parseInt(this.shoutid);

			

			if (this.pmuserid)

			{

				// Set who we're PMing

				extraparams += '&type=pm&userid=' + this.pmuserid;

			}			

			

			if (this.chatroomid)

			{

				// Set who we're PMing

				extraparams += '&type=chatroom&chatroomid=' + this.chatroomid;

			}			

		}

		else

		{

			// We're submitting a new shout

			console.log(this.timestamp() + 'Attempting to insert shout...');				

			

			if (this.pmuserid)

			{

				// We're submitting a new PM

				console.log(this.timestamp() + 'Attempting to PM user: %s', this.lookup[this.pmuserid]);				

				

				// Set who we're PMing

				extraparams += '&type=pm&userid=' + this.pmuserid;

			}

			

			if (this.chatroomid)

			{

				// We're submitting a new PM

				console.log(this.timestamp() + 'Attempting to chat in room: %s', this.chatroomid);				

				

				// Set who we're PMing

				extraparams += '&type=chatroom&chatroomid=' + this.chatroomid;

			}

		}

		

		if (this.detached)

		{

			// We're in detached mode

			extraparams += '&detached=1';

		}

		

		// Set instance id

		extraparams += '&instanceid=' + this.instanceid;		

		

		// Set tab id

		extraparams += '&tabid=' + this.tab;		

	

		// Execute AJAX

		this.ajax['posting'] = YAHOO.util.Connect.asyncRequest('POST', 'ajax.php?do=dbtech_vbshout_save', {

			success: this.ajax_completed,

			failure: this.handle_ajax_error,

			timeout: vB_Default_Timeout,

			scope: this

		}, SESSIONURL + 'securitytoken=' + SECURITYTOKEN + '&do=dbtech_vbshout_save&message=' + PHP.urlencode(PHP.trim(this.frames['editor'].value)) + extraparams);

		

		// Temporary storage

		this.frames['editor'].value = '';

		

		if (this.idle)

		{

			// We're obviously no longer idle, but init AJAX first so that we don't double fetch shouts

			this.unidle();

		}

		

		// Reset idle time

		this.idletime = 0;

		

		if (this.shoutid)

		{

			// We're no longer editing a shout

			this.cancel_shout_editing();			

		}

		

		return false;

	}

	

	// #########################################################################	

	// Begins editing a shout

	this.edit_shout = function(shoutid)

	{

		// Set the shout id

		this.shoutid = shoutid;			

		YAHOO.util.Dom.get('dbtech_shoutbox_deletebutton' + this.instanceid).style.display = 'inline';

		

		// Help text change

		YAHOO.util.Dom.get('dbtech_shoutbox_target' + this.instanceid).style.display = 'none';

		YAHOO.util.Dom.get('dbtech_shoutbox_editing' + this.instanceid).style.display = 'inline';

		

		// Set the editor contents

		this.frames['editor'].value = PHP.unhtmlspecialchars(YAHOO.util.Dom.get('dbtech_shoutbox_shout' + shoutid + '_message' + this.instanceid).value);			

		

		// Fetch the shout

		//this.fetch('shout', true);		

		

		// Just to be safe

		this.check_length();

	}	

	

	// #########################################################################	

	// Begins editing a shout

	this.edit_archive_shout = function(shoutid)

	{

		// We're editing a shout

		console.log(this.timestamp() + 'Attempting to edit Archive shout: %s...', shoutid);			

			

		var editor 	= YAHOO.util.Dom.get('dbtech_shoutbox_editor_' + shoutid + '_' + this.instanceid);

		var message = YAHOO.util.Dom.get('dbtech_shoutbox_message_' + shoutid + '_' + this.instanceid);

		

		editor.style.display 	= 'block';

		message.style.display 	= 'none';

		

		YAHOO.util.Dom.get('dbtech_shoutbox_editor_text_' + shoutid + '_' + this.instanceid).value = PHP.unhtmlspecialchars(YAHOO.util.Dom.get('dbtech_shoutbox_message_raw_' + shoutid + '_' + this.instanceid).innerHTML);

	}

	

	// #########################################################################	

	// Begins editing a shout

	this.cancel_editing_archive_shout = function(shoutid)

	{

		// We're editing a shout

		console.log(this.timestamp() + 'Cancelling editing Archive shout: %s...', shoutid);			

				

		var editor 	= YAHOO.util.Dom.get('dbtech_shoutbox_editor_' + shoutid + '_' + this.instanceid);

		var message = YAHOO.util.Dom.get('dbtech_shoutbox_message_' + shoutid + '_' + this.instanceid);

		

		editor.style.display 	= 'none';

		message.style.display 	= 'block';

		

		YAHOO.util.Dom.get('dbtech_shoutbox_editor_text_' + shoutid + '_' + this.instanceid).value = PHP.unhtmlspecialchars(YAHOO.util.Dom.get('dbtech_shoutbox_message_raw_' + shoutid + '_' + this.instanceid).innerHTML);

	}

	

	// #########################################################################

	// Save the editor styles

	this.delete_archive_shout = function(shoutid)

	{

		var extraparams = '';

		

		if (confirm('Are you sure you wish to delete this shout?'))

		{

			// Remove the shout

			YAHOO.util.Dom.get('dbtech_shoutbox_shout' + shoutid + '_' + this.instanceid).style.display = 'none';

			

			// We're editing a shout

			console.log(this.timestamp() + 'Attempting to delete Archive shout: %s...', shoutid);			

			

			// Set instance id

			extraparams += '&instanceid=' + this.instanceid;

			

			// Set tab id

			extraparams += '&tabid=' + this.tab;		

			

			// Execute AJAX

			YAHOO.util.Connect.asyncRequest('POST', 'ajax.php?do=dbtech_vbshout_delete', {

				success: this.ajax_completed,

				failure: this.handle_ajax_error,

				timeout: vB_Default_Timeout,

				scope: this

			}, SESSIONURL + 'securitytoken=' + SECURITYTOKEN + '&do=dbtech_vbshout_delete&shoutid=' + shoutid + '&source=archive' + extraparams);

		}

		

		return false;

	}	

	

	// #########################################################################

	// Save the editor styles

	this.save_archive_shout = function(shoutid)

	{

		var extraparams = '';

		

		// We're editing a shout

		console.log(this.timestamp() + 'Attempting to save Archive shout: %s...', shoutid);			

		

		// Set the raw text

		YAHOO.util.Dom.get('dbtech_shoutbox_message_raw_' + shoutid + '_' + this.instanceid).innerHTML = YAHOO.util.Dom.get('dbtech_shoutbox_editor_text_' + shoutid + '_' + this.instanceid).value;

		

		var editor 	= YAHOO.util.Dom.get('dbtech_shoutbox_editor_' + shoutid + '_' + this.instanceid);

		var message = YAHOO.util.Dom.get('dbtech_shoutbox_message_' + shoutid + '_' + this.instanceid);

		

		editor.style.display 	= 'none';

		message.style.display 	= 'block';

		

		// Set instance id

		extraparams += '&instanceid=' + this.instanceid;

		

		// Set tab id

		extraparams += '&tabid=' + this.tab;		

		

		// Execute AJAX

		YAHOO.util.Connect.asyncRequest('POST', 'ajax.php?do=dbtech_vbshout_save', {

			success: this.ajax_completed,

			failure: this.handle_ajax_error,

			timeout: vB_Default_Timeout,

			scope: this

		}, SESSIONURL + 'securitytoken=' + SECURITYTOKEN + '&do=dbtech_vbshout_save&shoutid=' + shoutid + '&message=' + PHP.urlencode(PHP.trim(YAHOO.util.Dom.get('dbtech_shoutbox_editor_text_' + shoutid + '_' + this.instanceid).value)) + '&source=archive' + extraparams);

	}	

	

	// #########################################################################

	// Save the editor styles

	this.save_editor_styles = function()

	{

		var styleproperties = new Array(

			'editor[bold]=' + (this.editor['bold'] ? 1 : 0),

			'editor[italic]=' + (this.editor['italic'] ? 1 : 0),

			'editor[underline]=' + (this.editor['underline'] ? 1 : 0),

			'editor[color]=' + this.editor['color'],

			'editor[font]=' + this.editor['font'],

			'editor[size]=' + this.editor['size']

		);

		

		var extraparams = '';

		

		if (this.detached)

		{

			// We're in detached mode

			extraparams += '&detached=1';

		}		

		

		// Set instance id

		extraparams += '&instanceid=' + this.instanceid;

		

		// Set tab id

		extraparams += '&tabid=' + this.tab;		

		

		// Execute AJAX

		YAHOO.util.Connect.asyncRequest('POST', 'ajax.php?do=dbtech_vbshout_styleprops', {

			success: this.ajax_completed,

			failure: this.handle_ajax_error,

			timeout: vB_Default_Timeout,

			scope: this

		}, SESSIONURL + 'securitytoken=' + SECURITYTOKEN + '&do=dbtech_vbshout_styleprops&' + styleproperties.join('&') + extraparams);

		

		if (this.idle)

		{

			// We're obviously no longer idle, but init AJAX first so that we don't double fetch shouts

			this.unidle();

		}		

	}

	

	// #########################################################################

	// Save the editor styles

	this.delete_shout = function()

	{

		// Initialise this

		var extraparams = '';

		

 		if (this.shoutid == 0)

		{

			// This should never happen but just in case

			return false;

		}

		

		// We're editing a shout

		console.log(this.timestamp() + 'Attempting to delete shout: %s...', this.shoutid);			

		

		if (this.pmuserid)

		{

			// Set who we're PMing

			extraparams += '&type=pm&userid=' + this.pmuserid;

		}	

		

		if (this.detached)

		{

			// We're in detached mode

			extraparams += '&detached=1';

		}		

		

		// Set instance id

		extraparams += '&instanceid=' + this.instanceid;

		

		// Set tab id

		extraparams += '&tabid=' + this.tab;		

		

		// Execute AJAX

		YAHOO.util.Connect.asyncRequest('POST', 'ajax.php?do=dbtech_vbshout_delete', {

			success: this.ajax_completed,

			failure: this.handle_ajax_error,

			timeout: vB_Default_Timeout,

			scope: this

		}, SESSIONURL + 'securitytoken=' + SECURITYTOKEN + '&do=dbtech_vbshout_delete&shoutid=' + this.shoutid + extraparams);

		

		// We're no longer editing a shout

		this.cancel_shout_editing();

		

		if (this.idle)

		{

			// We're obviously no longer idle, but init AJAX first so that we don't double fetch shouts

			this.unidle();

		}		

	}

	

	// #########################################################################

	// Fetches the userid for a specific username

	this.lookup_username = function()

	{

		// Initialise this

		var extraparams = '';

		var username = YAHOO.util.Dom.get('username' + this.instanceid).value;

		

 		if (username == '')

		{

			// This should never happen but just in case

			return false;

		}

		

		// We're editing a shout

		console.log(this.timestamp() + 'Attempting to lookup username: %s...', username);			

		

		if (this.detached)

		{

			// We're in detached mode

			extraparams += '&detached=1';

		}		

		

		// Set instance id

		extraparams += '&instanceid=' + this.instanceid;

		

		// Execute AJAX

		YAHOO.util.Connect.asyncRequest('POST', 'ajax.php?do=dbtech_vbshout_lookup', {

			success: this.ajax_completed,

			failure: this.handle_ajax_error,

			timeout: vB_Default_Timeout,

			scope: this

		}, SESSIONURL + 'securitytoken=' + SECURITYTOKEN + '&do=dbtech_vbshout_lookup&username=' + username + extraparams);

		

		if (this.idle)

		{

			// We're obviously no longer idle, but init AJAX first so that we don't double fetch shouts

			this.unidle();

		}		

	}

	

	// #########################################################################

	// Finalise fetching of content

	this.ajax_completed = function(ajax)

	{

		if (!ajax.responseXML)

		{

			// Empty response

			this.set_message('Invalid response from server: ' + ajax.responseText, 'error');

			this.restore_shout_message();			

			return false;

		}

		

		// check for error first

		var error = ajax.responseXML.getElementsByTagName('error');

		var clear = ajax.responseXML.getElementsByTagName('clear');

			

		if (clear.length)

		{

			// We need to clear an editor

			this.frames[clear[0].firstChild.nodeValue].value = '';

			this.check_length(); // Just to be safe

		}

			

		if (error.length)

		{

			var err = error[0].firstChild.nodeValue;

			var chatroomid = parseInt(err.split('_')[1]);

			

			if (chatroomid)

			{

				// Close the tab

				this.close_tab(YAHOO.util.Dom.get('tabobj_chatroom_' + chatroomid + '_' + this.instanceid), 'chatroom_' + chatroomid + '_');

				return false;

			}

			

			// Throw the error returned

			this.throw_ajax_error(err);

			this.restore_shout_message();

		}

		else

		{

			// All possible tags

			var tags = [

				'activeusers', 'activeusers2', 'aoptime', 'shout', 'success', 'sticky', 'editor', 'content', 'shoutid',

				'archive', 'menucode', 'pmuserid', 'chatroomid', 'roomname', 'chatroomid2', 'roomname2', 'username2',

				'aoptime2', 'tabid2', 'pmtime'

			];

			for (var t = 0; t < tags.length; t++)

			{

				eval('var ' + tags[t] + ' = ajax.responseXML.getElementsByTagName("' + tags[t] + '");');

			}

			

			if (success.length)

			{

				// Print success message

				this.set_message(success[0].firstChild.nodeValue, 'success');

			}

			

			if (sticky.length)

			{

				if (!sticky[0].firstChild)

				{

					// We're removing the sticky note

					this.hide_message('sticky');

				}

				else

				{

					// Print sticky message

					this.set_message(sticky[0].firstChild.nodeValue, 'sticky');

				}

			}

			

			if (activeusers.length)

			{

				// Set the active users

				this.frames['activeusers'].innerHTML = activeusers[0].firstChild.nodeValue;

			}

			

			if (activeusers2.length)

			{

				// Set the active users

				YAHOO.util.Dom.get('dbtech_shoutbox_activeusers_sidebar' + this.instanceid).innerHTML = activeusers2[0].firstChild.nodeValue;

			}

			

			if (aoptime2.length)

			{

				for (var i = 0; i < aoptime2.length; i++)

				{

					// Shorthand

					var aoptimes 	= aoptime2[i];

					var aoptime3 	= aoptimes.firstChild.nodeValue;

					var tabids 		= tabid2[i];

					var tabid 		= tabids.firstChild.nodeValue;

					

					if (tabid == this.tab)

					{

						// We're not alerting our own tab

						//continue;

					}					

					

					if (!this.aoptime[tabid])

					{

						// This is an unvisited tab

						this.aoptime[tabid] = aoptime3;

						continue;

					}

					

					if (this.aoptime[tabid] >= aoptime3)

					{

						// The AOP time is higher or equal, already seen it

						continue;

					}

					

					// Set the new AOP time

					this.aoptime[tabid] = aoptime3;

					

					if (this.sounds)

					{

						// Ensure we only try this if we can

						this.sounds.play('shout');

					}

					

					if (tabid != this.tab)

					{					

						// Get the object

						YAHOO.util.Dom.addClass(YAHOO.util.Dom.get(tabid + this.instanceid), 'dbtech_vbshout_highlight');

					}

				}

			}

			

			if (aoptime.length)

			{

				// We had an AOP tag

				if (this.aoptime[this.tab] < aoptime[0].firstChild.nodeValue || !this.aoptime[this.tab])

				{

					// Overwrite the AOP time

					this.aoptime[this.tab] = aoptime[0].firstChild.nodeValue;

				}

			}

			

			if (pmtime.length)

			{

				var newpm = pmtime[0].firstChild.nodeValue;

				

				if (!this.pmtime || this.pmtime < newpm)

				{

					if (this.pmtime < newpm)

					{

						if (this.sounds)

						{

							// Ensure we only try this if we can

							this.sounds.play('pm');

						}

					}

					

					// Set PM time

					this.pmtime = newpm;

				}

			}

			

			if (editor.length)

			{

				// We're setting the editor contents

				this.frames['editor'].value = editor[0].firstChild.nodeValue;

				this.check_length();				

			}

			

			if (content.length)

			{

				// We're setting shout frame contents

				this.frames['content'].innerHTML = content[0].firstChild.nodeValue;

			}

			

			if (archive.length && shoutid.length)

			{

				// We're setting shout frame contents

				YAHOO.util.Dom.get('dbtech_shoutbox_message_' + shoutid[0].firstChild.nodeValue + '_' + this.instanceid).innerHTML = archive[0].firstChild.nodeValue;

			}

			

			if (menucode.length && menucode[0].firstChild)

			{

				// Set the active users

				YAHOO.util.Dom.get('dbtech_shoutbox_menucode' + this.instanceid).innerHTML = menucode[0].firstChild.nodeValue;

				this.menuid = 0;

			}

			

			if (pmuserid.length)

			{

				// Create PM for this user

				this.create_pm(pmuserid[0].firstChild.nodeValue, YAHOO.util.Dom.get('username' + this.instanceid).value);

			}

			

			if (chatroomid.length && roomname.length)

			{

				// Create chat room tab

				this.create_chatroom_tab(chatroomid[0].firstChild.nodeValue, roomname[0].firstChild.nodeValue, true);

				this.show_chatroom_tab(chatroomid[0].firstChild.nodeValue);

			}

			

			if (chatroomid2.length)

			{

				for (var i = 0; i < chatroomid2.length; i++)

				{

					// Shorthand

					var chatroomids = chatroomid2[i];

					var chatroomid 	= chatroomids.firstChild.nodeValue;

					var roomnames 	= roomname2[i];

					var roomname 	= roomnames.firstChild.nodeValue;

					var usernames 	= username2[i];

					var username 	= usernames.firstChild.nodeValue;

					

					if (!this.tabs['chatroom_' + chatroomid + '_'])

					{

						if (this.sounds)

						{

							// Ensure we only try this if we can

							this.sounds.play('invite');

						}

						

						if (confirm('Do you want to join the Chat Room: ' + roomname + '? You were invited by ' + username + '.'))

						{

							// Ensure we only create uncreated tabs

							this.create_chatroom_tab(chatroomid, roomname, true);

							this.join_chatroom(chatroomid);

							this.show_chatroom_tab(chatroomid);

						}

						else

						{

							// Nah, fuck this shit

							this.leave_chatroom(chatroomid, true);

						}

					}

				}

			}

			

			if (shout.length)

			{

				// Begin storing the output

				var html = new Array();

				

				for (var i = 0; i < shout.length; i++)

				{

					// Shorthand

					var _shout 		= shout[i];

					var message 	= PHP.trim(_shout.firstChild.nodeValue);

					

					// Set the shout message

					html[i] = message;

				}

				

				if (html.length)

				{

					// Set the content if we had any

					this.frames['content'].innerHTML = html.join('');

				}

				

				if (this.shoutorder == 'ASC' && this.frames['shoutframe'].scrollTop < this.frames['shoutframe'].scrollHeight)

				{

					// Make it snap the scrollbar to the bottom

					if (typeof(HTMLElement) != 'undefined')

					{

						this.frames['shoutframe'].scrollBottom();

					}

					else

					{

						this.frames['shoutframe'].scrollTop = this.frames['shoutframe'].scrollHeight;

					}

				}

			}

		}

	}

	

	

	// #######################################################################

	// ######################## ERROR HANDLING ###############################

	// #######################################################################

	

	// #########################################################################

	// Function for manually throwing an AJAX error

	this.throw_ajax_error = function(errormsg)

	{

		if (YAHOO.util.Dom.get('dbtech_shoutbox_error_message' + this.instanceid))

		{

			// Throw the error returned

			this.set_message(errormsg, 'error');

		}

		else

		{

			alert(errormsg);

		}

		

		// Log the error to the console

		console.error(this.timestamp() + "AJAX Error: %s", errormsg);		

	}

	

	// #########################################################################

	// This should never happen.

	this.handle_ajax_error = function(ajax)

	{

		if (YAHOO.util.Dom.get('dbtech_shoutbox_error_message' + this.instanceid))

		{

			if (ajax.statusText == 'communication failure' || ajax.statusText == 'transaction aborted')

			{

				// Ignore this error

				return false;

			}

			

			// Restore shout message

			this.restore_shout_message();

			

			// Throw the error returned

			this.set_message(ajax.statusText, 'error');

			

			// Log the error to the console

			console.error(this.timestamp() + "AJAX Error: Status = %s: %s", ajax.status, ajax.statusText);

		}

		else

		{

			// Just pop it up

			alert(ajax.statusText);

		}

	}

	

	// #########################################################################

	// Function for displaying a thrown error

	this.set_message = function(msg, type)

	{

		// Log the error to the console

		console.log(this.timestamp() + "Setting %s: %s", type.charAt(0).toUpperCase() + '' + type.substr(1), msg);

		

		if (type != 'sticky' && type != 'notice')

		{

			// Clear any timeouts we may have already

			clearTimeout(this.timers[type]);

			

			// Create a new timer for hiding the frame

			this.timers[type] = setTimeout("vBShout" + this.instanceid + ".hide_message('" + type + "')", 5000);

		}

		

		// Display the message

		YAHOO.util.Dom.get('dbtech_shoutbox_' + type + '_message' + this.instanceid).innerHTML 	= msg;

		YAHOO.util.Dom.get('dbtech_shoutbox_' + type + '_frame' + this.instanceid).style.display 	= 'block';

		

		if (this.shoutorder == 'ASC' && this.frames['shoutframe'].scrollTop == this.scrollpos)

		{

			if (typeof(HTMLElement) != 'undefined')

			{

				// Scroller hasn't moved, snap to bottom

				this.frames['shoutframe'].scrollBottom();

			}

		}

	}

	

	// #########################################################################

	// Function for displaying a thrown error

	this.hide_message = function(type)

	{

		// Log the error to the console

		console.log(this.timestamp() + "Hiding %s...", type.charAt(0).toUpperCase() + '' + type.substr(1));

		

		// Hide the frame

		YAHOO.util.Dom.get('dbtech_shoutbox_' + type + '_message' + this.instanceid).innerHTML 	= 'N/A';

		YAHOO.util.Dom.get('dbtech_shoutbox_' + type + '_frame' + this.instanceid).style.display 	= 'none';

		

		if (this.shoutorder == 'ASC')

		{

			// Store the position of the scroller

			this.scrollpos = this.frames['shoutframe'].scrollTop;

		}

	}

	

	// #########################################################################

	// Restores our attempted shout post

	this.restore_shout_message = function()

	{

		// There was an error of some description

		this.frames['editor'].value = this.shoutstore;

	}

	

	// #########################################################################

	// Toggles the menu

	this.toggle_menu = function(menuid)

	{

		var divObj = YAHOO.util.Dom.get('menu' + menuid + '_' + this.instanceid);

		var aObj = YAHOO.util.Dom.get('click' + menuid + '_' + this.instanceid);

		

		if (!divObj)

		{

			// Just to prevent errors

			return false;

		}

		

		if (divObj.style.display == 'none' && menuid != this.menuid)

		{

			if (this.menuid)

			{

				// Turn off the previous menu

				this.toggle_menu(this.menuid);

			}

			

			// Set the new menu id

			this.menuid = menuid;

			

			// Hack the menu to show			

			divObj.style.display = 'inline';

			divObj.style.position = 'absolute';

			divObj.style.top = (YAHOO.util.Dom.getY(aObj) + parseInt(aObj.offsetHeight)) + 'px';

			divObj.style.left = YAHOO.util.Dom.getX(aObj) + 'px';



			right = (parseInt(divObj.style.left) + divObj.offsetWidth);



			if (right >= YAHOO.util.Dom.getViewportWidth())

			{

				divObj.style.left = (YAHOO.util.Dom.getViewportWidth() - divObj.offsetWidth) + 'px';

			}

		}

		else

		{

			// Hide the open menu

			divObj.style.display = 'none';

			this.menuid = 0;

		}

		

		return false;		

	}

	

	

	// #######################################################################

	// ######################## GENERIC FUNCTIONALITY ########################

	// #######################################################################



	// #########################################################################

	// Process keystroke

	this.keystroke = function(e)

	{

		// What key we pressed

		var keynum = 0;

		

		if (window.event)

		{

			// IE

			keynum = e.keyCode;

		}

		else if (e.which)

		{

			// Netscape / Firefox / Opera

			keynum = e.which;

		}

		

		if (keynum == 27 && this.shoutid)

		{

			// We're editing a shout, cancel editing

			this.cancel_shout_editing();

		}

		

		if (keynum == 13)

		{

			// This was saving the form

			return this.save();

		}

	}

	

	// #########################################################################

	// Check the length of the input

	this.check_length = function()

	{

		if (this.maxlength == 0)

		{

			// We're not checking length

		

			if (this.frames['editor'].value != '')

			{

				// Store this

				this.shoutstore = this.frames['editor'].value;

			}

			return true;

		}

		

		if (this.frames['editor'].value.length > this.maxlength)

		{

			// Strip characters that go beyond the limit

			this.frames['editor'].value = this.frames['editor'].value.substring(0, this.maxlength);

		}

		

		if (this.frames['editor'].value != '')

		{

			// Store this

			this.shoutstore = this.frames['editor'].value;

		}

		

		// Set the Remaining Characters count

		this.frames['charcount'].innerHTML = (this.maxlength - this.frames['editor'].value.length);		

	}	

	

	// #########################################################################

	// Debugging function, generates a timestamp of when something occurred

	this.timestamp = function()

	{

		var d = new Date();

		

		return '[' + d.getHours() + ':' + d.getMinutes() + ':' + d.getSeconds() + '] ';

	}

};





// #######################################################################

// ######################## LANGUAGE EXTENSIONS ##########################

// #######################################################################



// #############################################################################

// Code to snap a scrollbar to the bottom



if (typeof(HTMLElement) != 'undefined')

{

	HTMLElement.prototype.scrollBottom = function()

	{

		// Finally set the scrollTop attribute

		this.scrollTop = this.scrollHeight;

	}

}

/*======================================================================*\

|| #################################################################### ||

|| # Created: 23:33, Mon Dec 28th 2009								  # ||

|| # SVN: $Rev$							 							  # ||

|| #################################################################### ||

\*======================================================================*/