﻿StyledSelects = function()
{

	var fnClick;
	var selectItems = [];
	var activePicker = null;
	var hideEnabled = false;

	var m_fnSetStateOfOthers = function(pos, show)
	{
		var i;
		var elActivePicker;

		for(i = 0; i < selectItems.length; i++)
		{
			elActivePicker = selectItems[i].root;

			if(show)
			{
				if(pos != i)
				{
					elActivePicker.className = StyledSelects.className + "Active";
				}
			}
			else
			{
				if(pos != i)
				{
					elActivePicker.className = StyledSelects.className;
				}
			}

		}

	};
	
	var insertOption = function(container, select, selectPos, optionPos, option, isGrouped)
	{
		var li;
		var cls = option.className;

		if(cls != "")
		{
			cls = " " + cls;
		}

		li = document.createElement("li");
		if (isGrouped)
		{
			li.className = (li.className ? li.className + " " : "") + "grouped";
		}
		if (option.selected)
		{
			li.className = (li.className ? li.className + " " : "") + "active";
		}
		li.className += cls;
		li.appendChild(document.createTextNode(option.text));
		li.selectPos = selectPos;
		li.pos = optionPos;
		li.onclick = function()
		{
			StyledSelects.select(this.selectPos, this.pos);
		}
		li.onmouseover = function()
		{
			StyledSelects.mouseOver(select, this);
		}
		li.onmouseout = function()
		{
			StyledSelects.mouseOut(select, this);
		}
		container.appendChild(li);
	};

	return {
		init : function(el)
		{
			var selects;
			var select;
			var root;
			var i;
			var m_elContainer;

			if (typeof el == "undefined")
			{
				el = document;
			}

			selects = el.getElementsByTagName("select");
			m_elContainer = document.createElement("div");


			for(i = 0; i < selects.length; i++)
			{
				select = selects[i];

				var add = true;
				var p = select.parentNode;

				while(p != null)
				{
					add = !cls(p.className, "no-styling");
					if(!add)
					{
						break;
					}
					p = p.parentNode;
				}

				if(add)
				{
					selectItems[selectItems.length] = this.insert(select, selectItems.length);
//			a	}
				}
			}

		},
		insert : function(select, pos)
		{
			var obj;
			var div;
			var over;
			var span;
			var ul, li;
			var i, iActive;

			over = document.createElement("div");
			div = document.createElement("div");
			span = document.createElement("span");
			ul = document.createElement("ul");
			div.className = this.className;
			iActive = 0;
			for(i = 0; i < select.options.length; i++)
			{
				if (select.options[i].selected)
				{
					iActive = i;
					break;
				}
			}
			if(select.options[iActive])
			{
				span.appendChild(document.createTextNode(select.options[iActive].text));
			}
			span.StyledSelects = StyledSelects;
			span.position = pos;
			div.appendChild(span);
			over.appendChild(ul);
			div.appendChild(over);
			div.position = pos;
			div.StyledSelects = StyledSelects;
			div.id = StyledSelects.className + select.id;
			div.onclick = function()
			{
				this.StyledSelects.toggle(this.position);
			}

			if (select.nextSibling)
			{
				select.parentNode.insertBefore(div, select.nextSibling);
			}
			else
			{
				select.parentNode.appendChild(div);
			}

			select.style.visibility = "hidden";
			select.style.position = "absolute";
			select.style.top = "0px";
			select.style.left = "0px";

			obj = {select:select, root:div, span:span, ul:ul, pos:iActive};

			return obj;

		},
		insertOptions : function(selectPos)
		{
			var select;
			var ul;
			var i;
			var node;
			var nodeOption;

			select = selectItems[selectPos].select;
			ul = selectItems[selectPos].ul;

			while(ul.firstChild)
			{
				ul.removeChild(ul.firstChild);
			}
			
			i = 0;
			for (node = select.firstChild; node != null; node = node.nextSibling)
			{
				if (node.nodeType !== 1)
				{
					continue;
				}
			
				switch (node.nodeName.toLowerCase())
				{
					case "optgroup":
						li = document.createElement("li");
						li.className = "optgroup";
						li.appendChild(document.createTextNode(node.getAttribute("label")));
						ul.appendChild(li);
					
						for (nodeOption = node.firstChild; nodeOption != null; nodeOption = nodeOption.nextSibling)
						{
							if (nodeOption.nodeType !== 1)
							{
								continue;
							}
							
							if (nodeOption.nodeName.toLowerCase() === "option")
							{
								insertOption(ul, select, selectPos, i, nodeOption, true);
								i++;
							}
						}
						break;
					
					case "option":
						insertOption(ul, select, selectPos, i, node, false);
						i++;
						break;
				}
			}
		},
		draw : function(pos)
		{
			var h;
			var el;
			var root;

			if (selectItems[pos])
			{
				root = selectItems[pos].root;
				selectItems[pos].root.onmouseover = function()
				{
					StyledSelects.disableHide();
				}
				selectItems[pos].root.onmouseout = function()
				{
					StyledSelects.enableHide();
				}
				selectItems[pos].span.onclick = function()
				{
					StyledSelects.enableHide();
				}
				el = selectItems[pos].root.getElementsByTagName("div")[0];
				el.style.top = "";

				// show the select
				selectItems[pos].root.className = this.className + "Active";

				var elPos = findPos(el);

				if(elPos != null)
				{

					var elBottom = elPos.y + el.scrollHeight;

					// may indicate the expanded area is off the bottom of the screen
					if(elBottom > getBodyDimensions().h + getScrollXY().y)
					{
						el = selectItems[pos].root.getElementsByTagName("div")[0];
						el.style.top = (-1 * (el.offsetHeight - 2)) + "px";
					}

					// final check to see if the item is above the top of the page. better down and off than up and off
					var elPos = findPos(el);
					if(elPos.y < getScrollXY().y)
					{
						el.style.top = "";
					}
				}

				StyledSelects.disableHide();

			}
		},
		reload : function()
		{
			var i;
			var objStyledSelect;

			for(i = 0; i < selectItems.length; i++)
			{
				objStyledSelect = selectItems[i];
				objStyledSelect.root.parentNode.removeChild(objStyledSelect.root);
				selectItems[i] = this.insert(objStyledSelect.select, i)
			}

		},
		toggle : function(pos)
		{
			if (!selectItems[pos])
			{
				return;
			}
			if(selectItems[pos].root.className == this.className + "Active")
			{
				this.hide(false);
			}
			else
			{
				this.insertOptions(pos);
				this.show(pos);
				if(typeof EventDispatcher != "undefined")
				{
					EventDispatcher.dispatch("StyledSelects.Expand", selectItems[pos]);
				}
			}
		},
		show : function(pos)
		{
			m_fnSetStateOfOthers(pos, false);
			fnClick = document.onclick;
			document.onclick = function()
			{
				StyledSelects.hide(false);
			}
			this.draw(pos);
			activePicker = pos;

		},
		enableHide : function()
		{
			hideEnabled = true;
		},
		disableHide : function()
		{
			hideEnabled = false;
		},
		hide : function(force)
		{
			var elActivePicker;
			if (hideEnabled || force)
			{
				if (!selectItems[activePicker])
				{
					return;
				}

				elActivePicker = selectItems[activePicker].root;
				elActivePicker.className = StyledSelects.className;
				document.onclick = fnClick;
				activePicker = null;

			}

		},
		select : function(selectPos, pos)
		{
			var select;
			var root;
			var span;
			var posLast;
			var fnClick;
			var elExt;

			if (!selectItems[selectPos])
			{
				return;
			}

			select = selectItems[selectPos].select;
			root = selectItems[selectPos].root;
			span = selectItems[selectPos].span;
			posLast = selectItems[selectPos].pos;

			selectItems[selectPos].select.value = selectItems[selectPos].select.options[pos].value;

			while(span.firstChild)
			{
				span.removeChild(span.firstChild);
			}
			span.appendChild(document.createTextNode(selectItems[selectPos].select.options[pos].text));
			selectItems[selectPos].root.style.display = "none";
			this.show(selectPos);
			selectItems[selectPos].root.style.display = "";
			this.enableHide();

			selectItems[selectPos].pos = pos;

			if (posLast != pos)
			{
				if (select.onchange)
				{
					if(typeof select.onchange == "function")
					{
						select.onchange();
					}
				}
			}

		},
		mouseOver : function(select, callee)
		{
			if(callee.className != "")
			{
				callee.className += " over";
			}
			else
			{
				callee.className = "over";
			}
		},
		mouseOut : function(select, callee)
		{
			var attClass;
		
			callee.className = callee.className.replace("over", "");
			if(callee.className == "")
			{
				// todo: remove class attribute when empty
			}
		}
	}
}();

StyledSelects.maxHeight = 100;

//
// Default localisation settings for en-GB.
// Other locales should overwrite these settings in a separate file.
//

StyledSelects.className = "styledSelect";

function getScrollXY()
{
	var scrOfX = 0, scrOfY = 0;

	if( typeof( window.pageYOffset ) == 'number' )
	{
		//Netscape compliant
		scrOfY = window.pageYOffset;
		scrOfX = window.pageXOffset;
	}
	else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) )
	{
		//DOM compliant
		scrOfY = document.body.scrollTop;
		scrOfX = document.body.scrollLeft;
	}
	else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) )
	{
		//IE6 standards compliant mode
		scrOfY = document.documentElement.scrollTop;
		scrOfX = document.documentElement.scrollLeft;
	}
	return {x:scrOfX, y:scrOfY};
}

function findPos(obj)
{
	var curleft = curtop = 0;

	if (!obj.offsetParent)
	{
		return null;
	}

	do
	{
		curleft += obj.offsetLeft;
		curtop += obj.offsetTop;
	} while (obj = obj.offsetParent);

	return {x:curleft, y:curtop};

}

function getBodyDimensions()
{
	var myWidth = 0, myHeight = 0;

	if( typeof( window.innerWidth ) == 'number' )
	{
		//Non-IE
		myWidth = window.innerWidth;
		myHeight = window.innerHeight;
	}
	else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) )
	{
		//IE 6+ in 'standards compliant mode'
		myWidth = document.documentElement.clientWidth;
		myHeight = document.documentElement.clientHeight;
	}
	else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) )
	{
		//IE 4 compatible
		myWidth = document.body.clientWidth;
		myHeight = document.body.clientHeight;
	}

	return {w:myWidth, h:myHeight};

}
