/**
 * A base class for DOM-based position indicators.
 *
 * Subscriber interface:
 *	itsPosition: the name of the current selected position
 *	itsHoverPosition: the name of the current hover position
 *
 * Requires:
 *	Properties.js
 *	Publisher.js
 */
function AbstractPositionIndicator(self)
{
	var itsIDPrefix;
	var itsPositionNames;

	var itsPosition;
	var itsHoverPosition;
	var itsPositions = new Properties();


	self.initialize = function()
	{
		var i;

		itsPositions.clear();
		for (i = 0; i < itsPositionNames.length; i++)
			itsPositions.setProperty(itsPositionNames[i],document.getElementById(itsIDPrefix + itsPositionNames[i]));

		Publisher(self);
	};


	self.setPosition = function(inPosition,inIsNotNotifyingSubscribers)
	{
		var theOldElement;
		var theNewElement;

		if (inPosition != itsPosition)
		{
			theOldElement = itsPosition ? itsPositions.getProperty(itsPosition) : null;
			if (theOldElement === undefined)
{
				throw ("no such position '" + itsPosition);
}
			theNewElement = inPosition ? itsPositions.getProperty(inPosition) : null;
			if (theNewElement === undefined)
				throw ("no such position '" + inPosition);
			if (!theOldElement && !theNewElement)
				return;
			// Need to set the hover first, in case position and hover both manipulate the same elements.
			if (itsHoverPosition)
				self.setHoverPosition(null,true);
			self.changePosition(theOldElement,theNewElement);
			itsPosition = inPosition;
			if (!inIsNotNotifyingSubscribers)
				self.notifySubscribers(itsPosition,itsHoverPosition);
		}
	};


	self.setHoverPosition = function(inHoverPosition,inIsNotNotifyingSubscribers)
	{
		var theOldElement;
		var theNewElement;

		if (inHoverPosition != itsHoverPosition && (inHoverPosition != itsPosition || !itsPosition))
		{
			theOldElement = itsHoverPosition ? itsPositions.getProperty(itsHoverPosition) : null;
			if (theOldElement === undefined)
				throw ("no such position '" + itsHoverPosition);
			theNewElement = inHoverPosition ? itsPositions.getProperty(inHoverPosition) : null;
			if (theNewElement === undefined)
				throw ("no such position '" + inHoverPosition);
			if (!theOldElement && !theNewElement)
				return;
			self.changeHoverPosition(theOldElement,theNewElement);
			itsHoverPosition = inHoverPosition;
			if (!inIsNotNotifyingSubscribers)
				self.notifySubscribers(itsPosition,itsHoverPosition);
		}
	};


	self.setPositions = function(inPosition,inHoverPosition)
	{
		// It can only be one or the other that is changed, since position change clears hover
		if (inPosition != itsPosition)
			self.setPosition(inPosition);
		else
			self.setHoverPosition(inHoverPosition);
	};


	self.getIDPrefix = function()
	{
		return (itsIDPrefix);
	};


	self.setIDPrefix = function(inIDPrefix)
	{
		itsIDPrefix = inIDPrefix;
	};


	self.getPositionNames = function()
	{
		return (itsPositionNames);
	};


	self.setPositionNames = function(inPositionNames)
	{
		itsPositionNames = inPositionNames;
	};
}
