﻿/*======================================================================*\
|| #################################################################### ||
|| # vBulletin [#]version[#]
|| # ---------------------------------------------------------------- # ||
|| # Copyright ©2000-[#]year[#] Jelsoft Enterprises Ltd. All Rights Reserved. ||
|| # This file may not be redistributed in whole or significant part. # ||
|| # ---------------- VBULLETIN IS NOT FREE SOFTWARE ---------------- # ||
|| # http://www.vbulletin.com | http://www.vbulletin.com/license.html # ||
|| #################################################################### ||
\*======================================================================*/
var IMGDIR_MISC = "";
/**
* Handle Firebug calls when Firebug is not available (getfirebug.com)
*/
if (!window.console || !console.firebug)
{
	window.console = {};
	var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
	for (var i = 0; i < names.length; ++i) window.console[names[i]] = function() {};
}

/**
* Handle YUI custom event calls when YUI is not available (clientscript/yui/yahoo-dom-event.js)
*/
if (typeof YAHOO == "undefined")
{
	function null_event() { this.fire = function() {}; this.subscribe = function() {}; };
}


var pointer_cursor   = (is_ie ? 'hand' : 'pointer');


/**
* Define the browser loading the page
*
* @var	string	userAgent Useragent string
* @var	boolean	is_opera  Opera
* @var	boolean	is_saf    Safari
* @var	boolean	is_webtv  WebTV
* @var	boolean	is_ie     Internet Explorer
* @var	boolean	is_ie4    Internet Explorer 4
* @var	boolean	is_ie7    Internet Explorer 7
* @var	boolean	is_ps3    Playstation 3
* @var	boolean	is_moz    Mozilla / Firefox / Camino
* @var	boolean	is_kon    Konqueror
* @var	boolean	is_ns     Netscape
* @var	boolean	is_ns4    Netscape 4
* @var	boolean	is_mac    Client is running MacOS
*/
var userAgent = navigator.userAgent.toLowerCase();
var is_opera  = ((userAgent.indexOf('opera') != -1) || (typeof(window.opera) != 'undefined'));
var is_saf    = ((userAgent.indexOf('applewebkit') != -1) || (navigator.vendor == 'Apple Computer, Inc.'));
var is_webtv  = (userAgent.indexOf('webtv') != -1);
var is_ie     = ((userAgent.indexOf('msie') != -1) && (!is_opera) && (!is_saf) && (!is_webtv));
var is_ie4    = ((is_ie) && (userAgent.indexOf('msie 4.') != -1));
var is_ie7    = ((is_ie) && (userAgent.indexOf('msie 7.') != -1));
var is_ps3    = (userAgent.indexOf('playstation 3') != -1);
var is_moz    = ((navigator.product == 'Gecko') && (!is_saf));
var is_kon    = (userAgent.indexOf('konqueror') != -1);
var is_ns     = ((userAgent.indexOf('compatible') == -1) && (userAgent.indexOf('mozilla') != -1) && (!is_opera) && (!is_webtv) && (!is_saf));
var is_ns4    = ((is_ns) && (parseInt(navigator.appVersion) == 4));
var is_mac    = (userAgent.indexOf('mac') != -1);



/**
* Function to emulate document.getElementById
*
* @param	string	Object ID
*
* @return	mixed	null if not found, object if found
*/
function fetch_object(idname)
{
	if (document.getElementById)
	{
		return document.getElementById(idname);
	}
	else if (document.all)
	{
		return document.all[idname];
	}
	else if (document.layers)
	{
		return document.layers[idname];
	}
	else
	{
		return null;
	}
}

/**
* Function to emulate document.getElementsByTagName
*
* @param	object	Parent object (eg: document)
* @param	string	Tag type (eg: 'td')
*
* @return	array
*/
function fetch_tags(parentobj, tag)
{
	if (parentobj == null)
	{
		return new Array();
	}
	else if (typeof parentobj.getElementsByTagName != 'undefined')
	{
		return parentobj.getElementsByTagName(tag);
	}
	else if (parentobj.all && parentobj.all.tags)
	{
		return parentobj.all.tags(tag);
	}
	else
	{
		return new Array();
	}
}

/**
* Function to count the number of tags in an object
*
* @param	object	Parent object (eg: document)
* @param	string	Tag type (eg: 'td')
*
* @return	integer
*/
function fetch_tag_count(parentobj, tag)
{
	return fetch_tags(parentobj, tag).length;
}

// #############################################################################
// Event handlers

/**
* Handles the different event models of different browsers and prevents event bubbling
*
* @param	event	Event object
*
* @return	event
*/
function do_an_e(eventobj)
{
	if (!eventobj || is_ie)
	{
		window.event.returnValue = false;
		window.event.cancelBubble = true;
		return window.event;
	}
	else
	{
		eventobj.stopPropagation();
		eventobj.preventDefault();
		return eventobj;
	}
}

/**
* Handles the different event models of different browsers and prevents event bubbling in a lesser way than do_an_e()
*
* @param	event	Event object
*
* @return	event
*/
function e_by_gum(eventobj)
{
	if (!eventobj || is_ie)
	{
		window.event.cancelBubble = true;
		return window.event;
	}
	else
	{
		if (eventobj.target.type == 'submit')
		{
			// naughty safari
			eventobj.target.form.submit();
		}
		eventobj.stopPropagation();
		return eventobj;
	}
}





// #############################################################################
// vB_Select_Overlay_Handler
// #############################################################################

/**
* Handler for <select> tags that are overlayed with another element
* Fixes a problem in IE versions older than IE7.
*
* @param	mixed	Object or ID string that is the overlayed object
*/
function vB_Select_Overlay_Handler(overlay)
{
	this.browser_affected = (is_ie && !is_ie7);
	
	if (this.browser_affected)
	{	
		this.overlay = YAHOO.util.Dom.get(overlay);
		this.hidden_selects = new Array();
		console.log("Initializing <select> overlay handler for '%s'.", this.overlay.id);
	}
}


/**
* Hides any selects that intersect the overlayed object
*/
vB_Select_Overlay_Handler.prototype.hide = function()
{
	if (this.browser_affected)
	{
		var overlay_region = YAHOO.util.Dom.getRegion(this.overlay);
		
		var selects = document.getElementsByTagName("select");
		for (var i = 0; i < selects.length; i++)
		{
			if (region_intersects(selects[i], overlay_region))
			{
				if (YAHOO.util.Dom.isAncestor(this.overlay, selects[i]))
				{
					continue;
				}
				else
				{
					YAHOO.util.Dom.setStyle(selects[i], "visibility", "hidden");
					this.hidden_selects.push(YAHOO.util.Dom.generateId(selects[i]));
				}
			}
		}
	}
};

/**
* Un-hides any hidden selects
*/
vB_Select_Overlay_Handler.prototype.show = function()
{
	if (this.browser_affected)
	{
		var selectid;
		while (selectid = this.hidden_selects.pop())
		{
			YAHOO.util.Dom.setStyle(selectid, "visibility", "visible");
		}
	}
};






// #############################################################################
// DHTML Popup Menu Handling (complements vbulletin_menu.js)

/**
* Wrapper for vBmenu.register
*
* @param	string	Control ID
* @param	boolean	No image (true)
* @param	boolean	Does nothing any more
*/
function vbmenu_register(controlid, noimage, datefield)
{
	if (typeof(vBmenu) == "object")
	{
		return vBmenu.register(controlid, noimage);
	}
	else
	{
		return false;
	}
}





/**
* Takes the 'alt' attribute for an image and attaches it to the 'title' attribute
*
* @param	object	Image object
*/
function img_alt_2_title(img)
{
	if (!img.title && img.alt != '')
	{
		img.title = img.alt;
	}
}


// #############################################################################
// Main vBulletin Javascript Initialization

/**
* This function runs (almost) at the end of script loading on most vBulletin pages
*
* It sets up things like image alt->title tags, turns on the popup menu system etc.
*
* @return	boolean
*/
function vBulletin_init()
{
	// don't bother doing any exciting stuff for WebTV
	if (is_webtv)
	{
		return false;
	}

	// set 'title' tags for image elements
	var imgs = fetch_tags(document, 'img');
	for (var i = 0; i < imgs.length; i++)
	{
		img_alt_2_title(imgs[i]);
	}

	// finalize popup menus
	if (typeof vBmenu == 'object')
	{
		// close all menus on document click or resize
		if (typeof(YAHOO) != "undefined")
		{
			YAHOO.util.Event.on(document, "click", vbmenu_hide);
			YAHOO.util.Event.on(window, "resize", vbmenu_hide);
		}
		else if (window.attachEvent && !is_saf)
		{
			document.attachEvent('onclick', vbmenu_hide);
			window.attachEvent('onresize', vbmenu_hide);
		}
		else if (document.addEventListener && !is_saf)
		{
			document.addEventListener('click', vbmenu_hide, false);
			window.addEventListener('resize', vbmenu_hide, false);
		}
		else
		{
			window.onclick = vbmenu_hide;
			window.onresize = vbmenu_hide;
		}

		// add popups to pagenav elements
		var pagenavs = fetch_tags(document, 'td');
		for (var n = 0; n < pagenavs.length; n++)
		{
			if (pagenavs[n].hasChildNodes() && pagenavs[n].firstChild.name && pagenavs[n].firstChild.name.indexOf('PageNav') != -1)
			{
				var addr = pagenavs[n].title;
				pagenavs[n].title = '';
				pagenavs[n].innerHTML = '';
				pagenavs[n].id = 'pagenav.' + n;
				var pn = vBmenu.register(pagenavs[n].id);
				pn.addr = addr;

				if (is_saf)
				{
					pn.controlobj._onclick = pn.controlobj.onclick;
					pn.controlobj.onclick = vBpagenav.prototype.controlobj_onclick;
				}
			}
		}

		// process the pagenavs popup form
		if (typeof addr != 'undefined')
		{
			fetch_object('pagenav_form').gotopage = vBpagenav.prototype.form_gotopage;
			fetch_object('pagenav_ibtn').onclick = vBpagenav.prototype.ibtn_onclick;
			fetch_object('pagenav_itxt').onkeypress = vBpagenav.prototype.itxt_onkeypress;
		}

		// activate the menu system
		vBmenu.activate(true);
	}

	// the new init system
	vBulletin.init();

	return true;
}

// #############################################################################
// vBulletin Javascript Framework

/**
* General class for handling custom events and custom controls
*/
function vBulletin_Framework()
{
	/**
	* @var	array	Array of elements to be passed to control init functions
	* @var	array	Array of AJAX load/save URLs
	* @var	array	Array of YUI custom events
	* @var	date	Current time
	*/
	this.elements = new Array();
	this.ajaxurls = new Array();
	this.events = new Array();
	this.time = new Date();

	// custom event to fire during class init
	this.add_event("systemInit");
}

/**
* Initializes the object - usually called at end of footer template
*/
vBulletin_Framework.prototype.init = function()
{
	console.info("Firing System Init");
	this.events.systemInit.fire();
}

/**
* Emulates OOP class extension
*
* @param	object	Extended class
* @param	object	Base class
*/
vBulletin_Framework.prototype.extend = function(subClass, baseClass)
{
   function inheritance() {}
   inheritance.prototype = baseClass.prototype;

   subClass.prototype = new inheritance();
   subClass.prototype.constructor = subClass;
   subClass.baseConstructor = baseClass;
   subClass.superClass = baseClass.prototype;
}

/**
* Registers a custom control for later initialization
* Arguments 1-n are stored for later use
*
* @param	string	Control type (vB_DatePicker etc.)
* @param	string	HTML element ID
*/
vBulletin_Framework.prototype.register_control = function(controltype, element)
{
	var args = new Array();
	for (var i = 1; i < arguments.length; i++)
	{
		args.push(arguments[i]);
	}
	if (!this.elements[controltype])
	{
		console.info("Creating array vBulletin.elements[\"%s\"]", controltype);
		this.elements[controltype] = new Array();
	}
	var x = this.elements[controltype].push(args);
	console.log("vBulletin.elements[\"%s\"][%d] = %s", controltype, x-1, args.join(", "));
}


/**
* Register a custom event
*
* @param	string	Event name
*/
vBulletin_Framework.prototype.add_event = function(eventname)
{
	this.events[eventname] = (typeof YAHOO != 'undefined' ? new YAHOO.util.CustomEvent(eventname) : new null_event());
}

/**
* BC: Pass console calls to Firebug if it's available
*/
vBulletin_Framework.prototype.console = console.log;

// #############################################################################

// initialize the PHP function emulator
//var PHP = new vB_PHP_Emulator();

// Create an instance of the vBulletin Framework object
var vBulletin = new vBulletin_Framework();


/*======================================================================*\
|| ####################################################################
|| # Downloaded: [#]zipbuilddate[#]
|| # CVS: $RCSfile$ - $Revision: 25235 $
|| ####################################################################
\*======================================================================*/





/*======================================================================*\
|| #################################################################### ||
|| # vBulletin [#]version[#]
|| # ---------------------------------------------------------------- # ||
|| # Copyright ©2000-[#]year[#] Jelsoft Enterprises Ltd. All Rights Reserved. ||
|| # This file may not be redistributed in whole or significant part. # ||
|| # ---------------- VBULLETIN IS NOT FREE SOFTWARE ---------------- # ||
|| # http://www.vbulletin.com | http://www.vbulletin.com/license.html # ||
|| #################################################################### ||
\*======================================================================*/

vBulletin.add_event("vBmenuShow");
vBulletin.add_event("vBmenuHide");


/**
* vBulletin popup menu example usage:
*
* To create a new popup menu:
* 	<element id="x">Click me <script type="text/javascript"> vbmenu_register('x'); </script></element>
* The menu class expects an element with the id of x_menu that contains the menu.
*	<div id="x_menu" class="vbmenu_popup"> ... </div>
*/

// #############################################################################
// vB_Popup_Handler
// #############################################################################

/**
* vBulletin popup menu registry
*
* @package	vBulletin
* @version	$Revision: 25239 $
* @date		$Date: 2007-12-19 08:32:21 -0600 (Wed, 19 Dec 2007) $
* @author	Kier Darby, vBulletin Development Team
*/
function vB_Popup_Handler()
{
	/**
	* Options:
	*
	* @var	integer	Number of steps to use in sliding menus open
	* @var	boolean	Use opacity face in menu open?
	*/
	this.open_steps = 10;
	this.open_fade = false;

	this.active = false;

	this.menus = new Array();
	this.activemenu = null;
};

// =============================================================================
// vB_Popup_Handler methods

/**
* Activate / Deactivate the menu system
*
* @param	boolean	Active state for menus
*/
vB_Popup_Handler.prototype.activate = function(active)
{
	this.active = active;
	console.log("vBmenu :: System Activated");
};

/**
* Register a control object as a menu control
*
* @param	string	ID of the control object
* @param	boolean	Disable menu pop image addition
* @param	boolean	Disable menu slide open
*
* @return	vB_Popup_Menu
*/
vB_Popup_Handler.prototype.register = function(controlkey, noimage, noslide)
{
	//console.log("vBmenu :: registering '%s'", controlkey);
	this.menus[controlkey] = new vB_Popup_Menu(controlkey, noimage, noslide);
	
	// deal with usercss
	var usercss = YAHOO.util.Dom.get("usercss"); 
	if (usercss && YAHOO.util.Dom.isAncestor(usercss, controlkey))
	{
		this.menus[controlkey].imgsrc = IMGDIR_MISC + "/menu_open_usercss.gif";
	}
	
	this.menus[controlkey].startup();

	return this.menus[controlkey];
};

/**
* Hide active menu
*/
vB_Popup_Handler.prototype.hide = function()
{
	if (this.activemenu != null)
	{
		this.menus[this.activemenu].hide();
	}
};


// #############################################################################
// initialize menu registry

var vBmenu = new vB_Popup_Handler();

/**
* Function to allow anything to hide all menus
*
* @param	event	Event object
*
* @return	mixed
*/
function vbmenu_hide(e)
{
	if (e && e.button && e.button != 1 && e.type == 'click')
	{
		return true;
	}
	else
	{
		vBmenu.hide();
	}
};

// #############################################################################
// vB_Popup_Menu
// #############################################################################

/**
* vBulletin popup menu class constructor
*
* Manages a single menu and control object
* Initializes control object
*
* @package	vBulletin
* @version	$Revision: 25239 $
* @date		$Date: 2007-12-19 08:32:21 -0600 (Wed, 19 Dec 2007) $
* @author	Kier Darby, vBulletin Development Team
*
* @param	string	ID of the control object
* @param	boolean	Disable menu pop image addition
* @param	boolean	Disable menu slide open
*/
function vB_Popup_Menu(controlkey, noimage, noslide)
{
	this.controlkey = controlkey;
	this.noimage = noimage;
	this.noslide = noslide;
	
	this.menuname = this.controlkey.split('.')[0] + '_menu';
	this.imgsrc = IMGDIR_MISC + '/menu_open.gif';
};

// =============================================================================
// vB_Popup_Menu methods

/**
* Startup routine for a popup menu
*/
vB_Popup_Menu.prototype.startup = function()
{
	this.init_control(this.noimage);

	if (fetch_object(this.menuname))
	{
		this.init_menu();
	}

	this.slide_open = (this.noslide ? false : true);
	this.open_steps = vBmenu.open_steps;

	vBulletin.add_event("vBmenuShow_" + this.controlkey);
	vBulletin.add_event("vBmenuHide_" + this.controlkey);
}

/**
* Initialize the control object
*/
vB_Popup_Menu.prototype.init_control = function(noimage)
{
	this.controlobj = fetch_object(this.controlkey);
	this.controlobj.state = false;

	if (this.controlobj.firstChild && (this.controlobj.firstChild.tagName == 'TEXTAREA' || this.controlobj.firstChild.tagName == 'INPUT'))
	{
		// do nothing
	}
	else
	{
		if (!noimage && !(is_mac && is_ie))
		{
			var space = document.createTextNode(' ');
			this.controlobj.appendChild(space);

			var img = document.createElement('img');
			img.src = this.imgsrc;
			img.border = 0;
			img.title = '';
			img.alt = '';
			this.img = this.controlobj.appendChild(img);
		}

		this.controlobj.unselectable = true;
		if (!noimage)
		{
			this.controlobj.style.cursor = pointer_cursor;
		}
		this.controlobj.onclick = vB_Popup_Events.prototype.controlobj_onclick;
		this.controlobj.onmouseover = vB_Popup_Events.prototype.controlobj_onmouseover;
	}
};

/**
* Init the popup menu object
*/
vB_Popup_Menu.prototype.init_menu = function()
{
	this.menuobj = fetch_object(this.menuname);
	this.select_handler = new vB_Select_Overlay_Handler(this.menuobj);

	if (this.menuobj && !this.menuobj.initialized)
	{		
		this.menuobj.initialized = true;
		this.menuobj.onclick = e_by_gum;
		this.menuobj.style.position = 'absolute';
		this.menuobj.style.zIndex = 50;

		// workaround border disappearing issues in IE
		if (is_ie && !is_mac)
		{
			if (!is_ie7)
			{
				// this seems to fix it in < IE7, but IE7 disables ClearType with filters...
				this.menuobj.style.filter += "alpha(enabled=1,opacity=100)";
			}
			else
			{
				// ...so use this trick for IE7. It seems to work, but I don't know why. :)
				this.menuobj.style.minHeight = '1%';
			}
		}

		this.init_menu_contents();
	}
};

/**
* Init the popup menu contents
*/
vB_Popup_Menu.prototype.init_menu_contents = function()
{
	var tags = new Array("td", "li");
	for (var j = 0; j < tags.length; j++)
	{
		var blocks = fetch_tags(this.menuobj, tags[j]);
		for (var i = 0; i < blocks.length; i++)
		{
			if (blocks[i].className == 'vbmenu_option')
			{
				if (blocks[i].title && blocks[i].title == 'nohilite')
				{
					// not an active cell
					blocks[i].title = '';
				}
				else
				{
					// create a reference back to the menu class
					blocks[i].controlkey = this.controlkey;

					// handle mouseover / mouseout highlighting events
					blocks[i].onmouseover = vB_Popup_Events.prototype.menuoption_onmouseover;
					blocks[i].onmouseout = vB_Popup_Events.prototype.menuoption_onmouseout;

					var links = fetch_tags(blocks[i], 'a');
					if (links.length == 1)
					{
						/* Ok we have a link, we should use this if
						1. There is no onclick event in the link
						2. There is no onclick event on the cell
						3. The onclick event for the cell should equal the link if the above are true

						If we find a browser thats gets confused we may need to set remove_link to true for it.
						*/

						blocks[i].className = blocks[i].className + ' vbmenu_option_alink';
						blocks[i].islink = true;

						var linkobj = links[0];
						var remove_link = false;

						blocks[i].target = linkobj.getAttribute('target');

						if (typeof linkobj.onclick == 'function')
						{
							blocks[i].ofunc = linkobj.onclick;
							blocks[i].onclick = vB_Popup_Events.prototype.menuoption_onclick_function;
							remove_link = true;
						}
						else if (typeof blocks[i].onclick == 'function')
						{
							blocks[i].ofunc = blocks[i].onclick;
							blocks[i].onclick = vB_Popup_Events.prototype.menuoption_onclick_function;
							remove_link = true;
						}
						else
						{
							blocks[i].href = linkobj.href;
							blocks[i].onclick = vB_Popup_Events.prototype.menuoption_onclick_link;
						}

						if (remove_link)
						{
							var newlink = document.createElement('a');
							newlink.innerHTML = linkobj.innerHTML;
							newlink.href = '#';
							newlink.onclick = function(e) { e = e ? e : window.event; e.returnValue = false; return false; };
							blocks[i].insertBefore(newlink, linkobj);
							blocks[i].removeChild(linkobj);
						}
					}
					else if (typeof blocks[i].onclick == 'function')
					{
						blocks[i].ofunc = blocks[i].onclick;
						blocks[i].onclick = vB_Popup_Events.prototype.menuoption_onclick_function;
					}
				}
			}
		}
	}
};

/**
* Show the menu
*
* @param	object	The control object calling the menu
* @param	boolean	Use slide (false) or open instantly? (true)
*/
vB_Popup_Menu.prototype.show = function(obj, instant)
{
	if (!vBmenu.active)
	{
		return false;
	}
	else if (!this.menuobj)
	{
		this.init_menu();
	}

	if (!this.menuobj || vBmenu.activemenu == this.controlkey)
	{
		return false;
	}

	console.log("vBmenu :: Show '%s'", this.controlkey);

	if (vBmenu.activemenu != null && vBmenu.activemenu != this.controlkey)
	{
		vBmenu.menus[vBmenu.activemenu].hide();
	}

	vBmenu.activemenu = this.controlkey;

	this.menuobj.style.display = '';
	if (this.slide_open)
	{
		this.menuobj.style.clip = 'rect(auto, 0px, 0px, auto)';
	}

	this.set_menu_position(obj);

	if (!instant && this.slide_open)
	{
		this.intervalX = Math.ceil(this.menuobj.offsetWidth / this.open_steps);
		this.intervalY = Math.ceil(this.menuobj.offsetHeight / this.open_steps);
		this.slide((this.direction == 'left' ? 0 : this.menuobj.offsetWidth), 0, 0);
	}
	else if (this.menuobj.style.clip && this.slide_open)
	{
		this.menuobj.style.clip = 'rect(auto, auto, auto, auto)';
	}

	// deal with IE putting <select> elements on top of everything
	this.select_handler.hide();

	if (this.controlobj.editorid)
	{
		this.controlobj.state = true;
		//this.controlobj.editor.menu_context(this.controlobj, 'mousedown');
		vB_Editor[this.controlobj.editorid].menu_context(this.controlobj, 'mousedown');
	}

	vBulletin.events["vBmenuShow_" + this.controlkey].fire(this.controlkey);
	vBulletin.events.vBmenuShow.fire(this.controlkey);
};

/**
* Position the menu relative to a reference element
*
* @param	object	Reference HTML element
*/
vB_Popup_Menu.prototype.set_menu_position = function(obj)
{
	this.pos = this.fetch_offset(obj);
	this.leftpx = this.pos['left'];
	this.toppx = this.pos['top'] + obj.offsetHeight;

	if ((this.leftpx + this.menuobj.offsetWidth) >= document.body.clientWidth && (this.leftpx + obj.offsetWidth - this.menuobj.offsetWidth) > 0)
	{
		this.leftpx = this.leftpx + obj.offsetWidth - this.menuobj.offsetWidth;
		this.direction = 'right';
	}
	else
	{
		this.direction = 'left'
	}

	// move the pagenav menu to the calling object, so it appears to be styled like where it's displayed
	if (this.controlkey.match(/^pagenav\.\d+$/))
	{
		obj.appendChild(this.menuobj);
	}

	this.menuobj.style.left = this.leftpx + 'px';
	this.menuobj.style.top  = this.toppx + 'px';
};

/**
* Hide the menu
*/
vB_Popup_Menu.prototype.hide = function(e)
{
	if (e && e.button && e.button != 1)
	{
		// get around some context menu issues etc.
		return true;
	}

	console.log("vBmenu :: Hide '%s'", this.controlkey);

	this.stop_slide();

	this.menuobj.style.display = 'none';

	this.select_handler.show();

	if (this.controlobj.editorid)
	{
		this.controlobj.state = false;
		vB_Editor[this.controlobj.editorid].menu_context(this.controlobj, 'mouseout');
	}

	vBmenu.activemenu = null;

	vBulletin.events["vBmenuHide_" + this.controlkey].fire(this.controlkey);
	vBulletin.events.vBmenuHide.fire(this.controlkey);
};

/**
* Hover behaviour for control object
*/
vB_Popup_Menu.prototype.hover = function(obj)
{
	if (vBmenu.activemenu != null)
	{
		if (vBmenu.menus[vBmenu.activemenu].controlkey != this.id)
		{
			this.show(obj, true);
		}
	}
};

/**
* Slides menu open
*
* @param	integer	Clip X
* @param	integer	Clip Y
* @param	integer	Opacity (0-100)
*/
vB_Popup_Menu.prototype.slide = function(clipX, clipY, opacity)
{
	if (this.direction == 'left' && (clipX < this.menuobj.offsetWidth || clipY < this.menuobj.offsetHeight))
	{
		clipX += this.intervalX;
		clipY += this.intervalY;

		this.menuobj.style.clip = "rect(auto, " + clipX + "px, " + clipY + "px, auto)";
		this.slidetimer = setTimeout("vBmenu.menus[vBmenu.activemenu].slide(" + clipX + ", " + clipY + ", " + opacity + ");", 0);
	}
	else if (this.direction == 'right' && (clipX > 0 || clipY < this.menuobj.offsetHeight))
	{
		clipX -= this.intervalX;
		clipY += this.intervalY;

		this.menuobj.style.clip = "rect(auto, " + this.menuobj.offsetWidth + "px, " + clipY + "px, " + clipX + "px)";
		this.slidetimer = setTimeout("vBmenu.menus[vBmenu.activemenu].slide(" + clipX + ", " + clipY + ", " + opacity + ");", 0);
	}
	else
	{
		this.stop_slide();
	}
};

/**
* Abort menu slider
*/
vB_Popup_Menu.prototype.stop_slide = function()
{
	clearTimeout(this.slidetimer);

	this.menuobj.style.clip = 'rect(auto, auto, auto, auto)';
};

/**
* Fetch offset of an object
*
* @param	object	The object to be measured
*
* @return	array	The measured offsets left/top
*/
vB_Popup_Menu.prototype.fetch_offset = function(obj)
{
	if (obj.getBoundingClientRect)
	{
		// better, more accurate function for IE
		var rect = obj.getBoundingClientRect();

		var scrollTop = Math.max(document.documentElement.scrollTop, document.body.scrollTop);
		var scrollLeft = Math.max(document.documentElement.scrollLeft, document.body.scrollLeft);

		if (document.documentElement.dir == 'rtl')
		{
			// IE returns a positive scrollLeft, but we need a negative value to actually do proper calculations.
			// This actually flips the scolloing to be relative to the distance scrolled from the default.
			scrollLeft = scrollLeft + document.documentElement.clientWidth - document.documentElement.scrollWidth;
		}

		return { 'left' : rect.left + scrollLeft, 'top' : rect.top + scrollTop };
	}

	var left_offset = obj.offsetLeft;
	var top_offset = obj.offsetTop;

	while ((obj = obj.offsetParent) != null)
	{
		left_offset += obj.offsetLeft;
		top_offset += obj.offsetTop;
	}

	return { 'left' : left_offset, 'top' : top_offset };
};

// #############################################################################
// Menu event handler functions

/**
* Class containing menu popup event handlers
*/
function vB_Popup_Events()
{
};

/**
* Handles control object click events
*/
vB_Popup_Events.prototype.controlobj_onclick = function(e)
{
	if (typeof do_an_e == 'function')
	{
		do_an_e(e);
		if (vBmenu.activemenu == null || vBmenu.menus[vBmenu.activemenu].controlkey != this.id)
		{
			vBmenu.menus[this.id].show(this);
		}
		else
		{
			vBmenu.menus[this.id].hide();
		}
	}
};

/**
* Handles control object mouseover events
*/
vB_Popup_Events.prototype.controlobj_onmouseover = function(e)
{
	if (typeof do_an_e == 'function')
	{
		do_an_e(e);
		vBmenu.menus[this.id].hover(this);
	}
};

/**
* Handles menu option click events for options with onclick events
*/
vB_Popup_Events.prototype.menuoption_onclick_function = function(e)
{
	this.ofunc(e);
	vBmenu.menus[this.controlkey].hide();
};

/**
* Handles menu option click events for options containing links
*/
vB_Popup_Events.prototype.menuoption_onclick_link = function(e)
{
	e = e ? e : window.event;

	if (e.shiftKey || (this.target != null && this.target != '' && this.target.toLowerCase() != '_self'))
	{
		if (this.target != null && this.target.charAt(0) != '_')
		{
			window.open(this.href, this.target);
		}
		else
		{
			window.open(this.href);
		}
	}
	else
	{
		window.location = this.href;
	}

	// Safari has "issues" with resetting what was clicked on, super minor and I dont care
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
	if (e.preventDefault) e.preventDefault();

	vBmenu.menus[this.controlkey].hide();
	return false;
};

/**
* Handles menu option mouseover events
*/
vB_Popup_Events.prototype.menuoption_onmouseover = function(e)
{
	this.className = 'vbmenu_hilite' + (this.islink ? ' vbmenu_hilite_alink' : '');
	this.style.cursor = pointer_cursor;
};

/**
* Handles menu option mouseout events
*/
vB_Popup_Events.prototype.menuoption_onmouseout = function(e)
{
	this.className = 'vbmenu_option' + (this.islink ? ' vbmenu_option_alink' : '');
	this.style.cursor = 'default';
};

/*======================================================================*\
|| ####################################################################
|| # Downloaded: [#]zipbuilddate[#]
|| # CVS: $RCSfile$ - $Revision: 25239 $
|| ####################################################################
\*======================================================================*/