function TSFlyouts()
{
	// Manages all public flyout snippets

	function TStorage()
	{
		// Holds the indivual flyout snippets
		this.namedItems = [];
		this.items = [];

		this.addItem = function (name, item)
		{
			this.namedItems[name] = item;
			this.items.push(item);
		}

		this.getItem = function (name)
		{
			if (typeof (name) == "string") return this.namedItems[name];
			else return this.items[name];
		}

		this.length = function ()
		{
			return this.items.length;
		}
	} // TSFlyouts.TStorage END

	function TSnippet()
	{
		// The implementation of a flyout snippet
		this.instanceName = ""; // Unique identifier
		this.triggerId = null;
		this.fadeOut = false;
		this.verticalPlacement = 0;
		this.horizontalPlacement = 0;
		this.flyoutId = "";
		this.imgSrcI = "";
		this.imgSrcA = "";
		this.imgSrcH = "";
		this.clickHandler = null;
		this.active = false;
		this.hiddenElements = []; // if IE6- then this array will hold all SELECTS that intersects with the flyouts bounding box  
		this.element2beFocused = null;

		this.show = function (o)
		{
			// Displays the snippet	 		
			var inst = null;
			for (var i = 0; i < tsFlyouts.storage.length(); i++)
			{
				inst = tsFlyouts.storage.getItem(i);
				if (inst.instanceName != this.instanceName) inst.hide(document.getElementById(inst.flyoutId));
			}
			this.active = true;
			var trigger = document.getElementById(this.triggerId);
			var point = this.getPos(trigger);
			var posX = point[0];
			var posY = point[1];

			if (this.verticalPlacement == 0) posY -= o.offsetHeight;
			else posY += trigger.offsetHeight;

			if (this.horizontalPlacement == 0)
			{
				posX += trigger.offsetWidth;
				posX -= o.offsetWidth;
			}
			o.style.top = posY;
			o.style.left = posX;

			if (document.all)
			{ // Expand check to IE6-
				// hide covered selects
				var point = this.getPos(o);
				var coveredArea = [point[0], point[1], o.clientWidth, o.clientHeight];
				var combolist = document.getElementsByTagName("SELECT");
				if (combolist.length > 0)
				{
					for (var i = 0; i < combolist.length; i++)
					{
						var cmb = combolist[i];
						point = this.getPos(cmb);
						var cArea = [point[0], point[1], cmb.clientWidth, cmb.clientHeight];
						if (this.intersects(coveredArea, cArea))
						{
							if ((cmb.style.display.toLowerCase() != "none") && (cmb.style.visibility.toLowerCase() != "hidden"))
							{
								this.hiddenElements.push(cmb);
								cmb.style.visibility = "hidden";
							}
						}
					}
				}
			}

			var img = trigger.childNodes[0];
			img.src = this.imgSrcA;
			img.onmouseover = function () { };
			img.onmouseout = function () { };

			if (this.clickHandler == null)
			{
				// Add popdown handlers
				this.clickHandler = "tsFlyouts.popDown('" + this.instanceName + "')";

				/*
				if (/Safari/.test(navigator.userAgent)) {
				tsCompat.addEvent(document.body, "onclick", function () {eval(clickHandler)});
				trigger.onclick = function () {};
				var tmp = "tsFlyouts.fly(\'trigger\',event); if(window.event) {window.event.cancelBubble=true;} else {e.stopPropagation();}";
				tsCompat.addEvent(trigger, "onclick", function () {eval(tmp)});
				} else 
				*/
				{
					if (/Mozilla\/5\.0/.test(navigator.userAgent)) tsCompat.addEvent(window, "onclick", function () { eval(clickHandler) });
					else tsCompat.addEvent(document.body, "onclick", function () { eval(clickHandler) });
				}

				tsCompat.addEvent(o, "onclick", function (e) { eval("if(window.event) {window.event.cancelBubble=true;} else {e.stopPropagation();}") });
				var clickHandler = this.clickHandler;
			}
			if (o.filters)
				if (o.filters[0])
				{
					o.filters[0].enabled = true;
					o.filters[0].apply();
				}
			o.style.visibility = "visible";
			if (o.filters)
				if (o.filters[0])
					o.filters[0].play();
			var coll = o.getElementsByTagName("INPUT");
			if (coll.length > 0)
			{
				if (o.filters)
				{
					if (o.filters[0])
					{
						for (var i = 0; i < coll.length; i++)
						{
							if (coll[i].type != 'hidden')
							{
								this.element2beFocused = coll[i];
								window.setTimeout("tsFlyouts.focusElement('" + this.instanceName + "')", 1000);
								break;
							}
						}
					} else
					{
						for (var i = 0; i < coll.length; i++)
						{
							if (coll[i].type != 'hidden')
							{
								coll[i].focus();
								break;
							}
						}
					}
				} else
				{
					for (var i = 0; i < coll.length; i++)
					{
						if (coll[i].type != 'hidden')
						{
							coll[i].focus();
							break;
						}
					}
				}
			}
		}

		this.hide = function (o)
		{
			// Hides the visible snippet				
			this.active = false;
			var img = document.getElementById(this.triggerId).childNodes[0];
			if (this.fadeOut && o.filters)
				if (o.filters[0])
					o.filters[0].apply();
			o.style.visibility = "hidden";
			if (this.fadeOut && o.filters)
				if (o.filters[0])
					o.filters[0].play();
			img.src = this.imgSrcI;
			var func1 = "this.src = \'" + this.imgSrcH + "\';";
			img.onmouseover = function () { eval(func1) };
			var func2 = "this.src = \'" + this.imgSrcI + "\';";
			img.onmouseout = function () { eval(func2) };
			if (this.hiddenElements.length > 0)
			{
				// Show previously hidden selects
				if (o.filters)
					if (o.filters[0])
						window.setTimeout("tsFlyouts.showSelects('" + this.instanceName + "')", o.filters[0].duration * 1000);
			}
		}

		this.getPos = function (elm)
		{
			// Gets the absolute position of the element as a point array [x,y]
			if (!elm) return [-1, -1];
			var l = elm.offsetLeft;
			var t = elm.offsetTop;
			var tmp = elm.offsetParent;
			//while (tmp != null && tmp != document.body) {
			while (tmp != null)
			{
				l += tmp.offsetLeft;
				t += tmp.offsetTop;
				tmp = tmp.offsetParent;
			}
			if (!document.all) l -= 2;
			return [l, t];
		}

		this.intersects = function (r1, r2)
		{
			// Test the rects for overlap

			// get the radi of each rect			
			var width1 = parseInt(r1[2] / 2);
			var height1 = parseInt(r1[3] / 2);
			var width2 = parseInt(r2[2] / 2);
			var height2 = parseInt(r2[3] / 2);

			// compute center of each rect
			var cx1 = r1[0] + width1;
			var cy1 = r1[1] + height1;
			var cx2 = r2[0] + width2;
			var cy2 = r2[1] + height2;

			// compute deltas
			var dx = Math.abs(cx2 - cx1);
			var dy = Math.abs(cy2 - cy1);

			// test if rects overlap
			if (dx < (width1 + width2) && dy < (height1 + height2)) return true;
			else return false;
		}
	} // TSFlyouts.TSnippet END 

	this.storage = new TStorage();

	this.getInstance = function (instanceName)
	{
		if (this.storage.getItem(instanceName) == null) this.storage.addItem(instanceName, new TSnippet());
		return this.storage.getItem(instanceName);
	}

	this.addInstance = function (instanceName, triggerId, fadeOut, verticalPlacement, horizontalPlacement, flyoutId, imgSrcI, imgSrcA, imgSrcH)
	{
		var instance = this.getInstance(instanceName);
		instance.instanceName = instanceName;
		instance.triggerId = triggerId;
		instance.fadeOut = (fadeOut == 1);
		instance.verticalPlacement = verticalPlacement;
		instance.horizontalPlacement = horizontalPlacement;
		instance.flyoutId = flyoutId;
		instance.imgSrcI = imgSrcI;
		instance.imgSrcA = imgSrcA;
		instance.imgSrcH = imgSrcH;
		return instance;
	}

	this.fly = function (instanceName, e)
	{
		// Generic flyhandler, either shows or hides the snippet
		if (!e && window.event)
			e = window.event;
		var instance = tsFlyouts.getInstance(instanceName);
		var flyout = document.getElementById(instance.flyoutId);
		if ((flyout.style.visibility == "visible") || (instance.active == true)) instance.hide(flyout);
		else instance.show(flyout);
		if (e.stopPropagation) e.stopPropagation();
		if (window.event) e.cancelBubble = true;
		return false;
	}

	this.popDown = function (instanceName)
	{
		var instance = tsFlyouts.getInstance(instanceName);
		var flyout = document.getElementById(instance.flyoutId);
		instance.hide(flyout);
	}

	this.showSelects = function (instanceName)
	{
		// Iterates the hidden selects and redisplays them
		var instance = tsFlyouts.getInstance(instanceName);
		var flyout = document.getElementById(instance.flyoutId);
		while (instance.hiddenElements.length > 0)
		{
			var e = instance.hiddenElements.pop();
			e.style.visibility = "visible";
		}
	}

	this.focusElement = function (instanceName)
	{
		var instance = tsFlyouts.getInstance(instanceName);
		if (instance.element2beFocused) instance.element2beFocused.focus();
	}

	this.getParentForm = function (elm)
	{
		var pN = elm.parentNode;
		while (pN != null && pN.tagName.toLowerCase() != "form")
		{
			pN = pN.parentNode;
		}
		return pN;
	}

} // TSFlyouts END

function TSSlideShows()
{

	function TStorage()
	{
		this.namedItems = [];
		this.items = [];

		this.addItem = function (name, item)
		{
			this.namedItems[name] = item;
			this.items.push(item);
		}

		this.getItem = function (name)
		{
			if (typeof (name) == "string") return this.namedItems[name];
			else return this.items[name];
		}

		this.length = function ()
		{
			return this.items.length;
		}
	} // TSSlideShows.TStorage END

	function TSlideShow()
	{
		this.position = 1;
		this.timeout = 1000;
		this.fadeOut = false;
		this.instanceName = "";
		this.init = function ()
		{
			var s = "slideShows_nextSlide('" + this.instanceName + "')";
			window.setTimeout(s, this.timeout);
		}

		this.nextSlide = function ()
		{
			var curI = document.getElementById(this.instanceName + this.position);
			if (this.fadeOut && curI.filters)
				if (curI.filters[0])
					curI.filters[0].apply();
			curI.style.visibility = "hidden";
			if (this.fadeOut && curI.filters)
				if (curI.filters[0])
					curI.filters[0].play();

			var nextI = document.getElementById(this.instanceName + (this.position + 1));
			if (nextI == null)
			{
				this.position = 1;
				nextI = document.getElementById(this.instanceName + this.position);
			} else this.position += 1;
			if (nextI.filters)
				if (nextI.filters[0])
					nextI.filters[0].apply();
			nextI.style.visibility = "visible";
			if (nextI.filters)
				if (nextI.filters[0])
					nextI.filters[0].play();
			var s = "slideShows_nextSlide('" + this.instanceName + "')";
			window.setTimeout(s, this.timeout);
		}

	} // TSSlideShows.TSlideShow END

	this.storage = new TStorage();

	this.getInstance = function (instanceName)
	{
		if (this.storage.getItem(instanceName) == null) this.storage.addItem(instanceName, new TSlideShow());
		return this.storage.getItem(instanceName);
	}

	this.addInstance = function (instanceName, timeout, fadeOut)
	{
		var instance = this.getInstance(instanceName);
		instance.instanceName = instanceName;
		instance.timeout = timeout;
		instance.fadeOut = fadeOut;
		instance.init();
		return instance;
	}

} // TSSlideShows END

function slideShows_nextSlide(instanceName)
{
	tsSlideShows.getInstance(instanceName).nextSlide();
}

tsFlyouts = new TSFlyouts();
tsSlideShows = new TSSlideShows();
