function ServerPopulatedPopupMenu (varName, contextMenuName, inactiveButtonCssClass, activeButtonCssClass, cacheMenu, enableCallback, prefix)
{
	this.VariableName = varName;
	this.ContextMenuName = contextMenuName;
	this.InactiveButtonCssClass = inactiveButtonCssClass;
	this.ActiveButtonCssClass = activeButtonCssClass;
	this.LastParameterData;
	this.MenuLoaded = false;
	this.Element = null;
	this.CacheMenu = cacheMenu;
	this.AnimatedButtons = new Array();
	this.EnableCallback = enableCallback;

	// [thumbtack] added "prefix" parameter to allow multiple menus on single page
	this.Prefix = prefix;

	this.LoadMenu = function(element, event, serverParameterData)
	{
		if (this.Element == element && this.MenuLoaded)
		{
			eval('window.' + this.ContextMenuName + '.Close();');
			this.Element = null;
		}
		else if (!this.EnableCallback || (this.LastParameterData == serverParameterData && this.MenuLoaded && this.CacheMenu))
		{
			this.Element = element;
			this.ShowContextMenu();
			this.Element.className = this.ActiveButtonCssClass;
		}
		else
		{
			if (this.MenuLoaded)
			{
				eval('window.' + this.ContextMenuName + '.Close();');
			}	
			
			this.Element = element;
			
			window.document.body.style.cursor = 'progress';
	
			this.MenuLoaded = false;
			this.LastParameterData = serverParameterData;
			this.LoadAnimationHandle = window.setTimeout('window.' + this.VariableName + '.LoadAnimation(true);', 49);
			// [thumbtack] 
			//ServerPopulatedPopupMenuAJAX.ProcessPopulateMenuCallback(this.VariableName, serverParameterData, new Function('result', 'window.' + this.VariableName + '.PopulateMenu(result);'));	
			eval(this.Prefix + ".ProcessPopulateMenuCallback(this.VariableName, serverParameterData, new Function('result', 'window.' + this.VariableName + '.PopulateMenu(result);'))");
			// [/thumbtack] 
		}

		return false;
	}
	
	this.PopulateMenu = function(result)
	{
		if (result.error)
		{
			alert('The following error occured while processing the AJAX request: ' + result.error);
			return;
		}
		
		eval('window.' + this.ContextMenuName + '.ParseMenuItems(' + result.value + ');');
		eval('window.' + this.ContextMenuName + '.Refresh();');
		this.ShowContextMenu();
	}
	
	this.StartAnimation = function(element)
	{
		var index = 0;
		for (index = 0; index < this.AnimatedButtons.length; index++)
		{
			if (!this.AnimatedButtons[index])
				break;
		}
		
		window.document.body.style.cursor = 'progress';
		
		this.AnimatedButtons[index] = new Array(element, window.setTimeout('window.' + this.VariableName + '.ProcessAnimation(' + index + ', true);', 249), -1);
		
		return index;
	}
	
	this.ProcessAnimation = function(index, highlight)
	{
		var ad = this.AnimatedButtons[index];
		if (ad)
		{
			window.clearTimeout(ad[1]);
			
			if (ad[2] == 0)
			{
				this.AnimatedButtons[index] = null;
				window.clearTimeout(ad[1]);
				
				window.document.body.style.cursor = 'auto';
				
				if (ad[0])
				{
					if (this.Element == ad[0])
						ad[0].className = this.ActiveButtonCssClass;
					else
						ad[0].className = this.InactiveButtonCssClass;
				}
					
				this.AnimatedButtons[index] = null;
				
				return;
			}
			else
			{
				if (ad[2] > 0)
					ad[2] -= 1;
					
				if (highlight)
				{
					if (ad[0])
						ad[0].className = this.ActiveButtonCssClass;
						
					window.document.body.style.cursor = 'progress';
					ad[1] = window.setTimeout('window.' + this.VariableName + '.ProcessAnimation(' + index + ', false);', 249);
				}
				else
				{
					if (ad[0])
						ad[0].className = this.InactiveButtonCssClass;
						
					window.document.body.style.cursor = 'progress';
					ad[1] = window.setTimeout('window.' + this.VariableName + '.ProcessAnimation(' + index + ', true);', 249);
				}
			}
		}
	}
	
	this.StopAnimation = function(index)
	{
		var ad = this.AnimatedButtons[index];
		
		if (ad)
		{
			ad[2] = 6;
		}
	}
	
	this.LoadAnimation = function(highlight)
	{
		window.clearTimeout(this.LoadAnimationHandle);
	
		if (this.Element)
		{
			if (this.MenuLoaded)
			{
				window.document.body.style.cursor = 'auto';
				this.Element.className = this.ActiveButtonCssClass;
				return;
			}
		
			if (highlight)
			{
				this.Element.className = this.ActiveButtonCssClass;
				window.document.body.style.cursor = 'progress';
				this.LoadAnimationHandle = window.setTimeout('window.' + this.VariableName + '.LoadAnimation(false);', 249);
			}
			else
			{
				this.Element.className = this.InactiveButtonCssClass;
				window.document.body.style.cursor = 'progress';
				this.LoadAnimationHandle = window.setTimeout('window.' + this.VariableName + '.LoadAnimation(true);', 249);
			}
		}
	}
	
	this.ContextMenuClosed = function()
	{
		if (this.Element)
		{
			this.LastElement = this.Element;
			
			if (this.LastElement)
				this.LastElement.className = this.InactiveButtonCssClass;
				
			this.Element = null;
		}
	}

	this.ShowContextMenu = function()
	{
		this.MenuLoaded = true;
		var menu = eval('window.' + this.ContextMenuName);
		menu.OpenAtElement(this.Element);
	}
}