ReplaceSelector = function(id)
{
	if(!id) return;
	
	this._tid = id;
	this._selector;
	this._selected;
	this._layer;
	this._collection = [];
	
	EventHandler.addListener(window, "load", "initialize", this);
}
ReplaceSelector.prototype = {
	initialize: function(e)
	{
		var selector = document.getElementById(this._tid);
		var wrapper = selector.parentNode;
		var selected = document.createElement("p");
		selected.setAttribute("class", "trigger");
		var ul = document.createElement("ul");
		ul.setAttribute("class", "layer");
		
		var createProxy = (function(_context, _collection)
		{
			return function(_container)
			{
				var proxy = new ReplaceSelector.Item(node, _context);
				if(node.getAttribute("selected"))
				{
					var text = document.createTextNode(node.firstChild.nodeValue);
					selected.appendChild(text);
					proxy.selectedStatus(true);
				}
				_container.appendChild(proxy.getProxy());
				_collection.push(proxy);
			}
		})(this, this._collection);
		
		for(var i=0; i<selector.childNodes.length; i++)
		{
			var node = selector.childNodes[i];
			
			if(node.nodeType==1)
			{
				if(node.nodeName=="optgroup"||node.nodeName=="OPTGROUP")
				{
					var group = document.createElement("li");
					var label = document.createTextNode(node.getAttribute("label"));
					group.appendChild(label);
					group.setAttribute("class", "group");
					
					for(var j=0; j<node.childNodes.length; j++)
					{
						var node = node.childNodes[j]
						if(node.nodeType==1)
						{
							createProxy(group);
						}
					}
					ul.appendChild(group);
					
				} else if(node.nodeName=="option"||node.nodeName=="OPTION") {
					
					createProxy(ul);
					//
				} else {
					return;
				}
			}
		}
		
		wrapper.style.display = "block";
		wrapper.style.position = "relative";
		wrapper.insertBefore(selected, selector);
		wrapper.insertBefore(ul, selector);
		
		selected.style.display = "block";
		//selected.style.border = "1px solid #333";
		//selected.style.cursor = "pointer";
		
		//ul.style.backgroundColor = "#FFF";
		//ul.style.border = "1px solid #FFF";
		//ul.style.color = "#333";
		ul.style.display = "none";
		ul.style.position = "absolute";
		ul.style.width = selected.offsetWidth +"px";
		ul.style.top = 0 +"px";
		ul.style.left = 0 +"px";
		//ul.style.fontSize = 116 +"%";
		//ul.style.lineHeight = 140 +"%";
		
		selector.style.display = "none";
		this._selector = selector;
		this._selected = selected;
		this._layer = ul;
		
		EventHandler.addListener(selected, "click", "openLayer", this);
	},
	changeSelection: function(uid)
	{
		var selected = this._selected;
		var selector = this._selector;
		for(var i=0; i<this._collection.length; i++)
		{
			var proxy = this._collection[i];
			
			if(uid==proxy.getUID())
			{
				proxy.selectedStatus(true);
				selected.removeChild(this._selected.firstChild);
				selected.appendChild(proxy.getLabel());
				//
				if(selector.fireEvent)
				{
					selector.fireEvent("onchange");
					//
				} else {
					var e = document.createEvent("HTMLEvents");
					e.initEvent("change", false, true);
					selector.dispatchEvent(e);
				}
			} else {
				proxy.selectedStatus(false);
			}
		}
	},
	openLayer: function(e)
	{
		if(window.event) window.event.returnValue = false;
		else e.preventDefault();
		this._layer.style.display = "block";
		var _callback = this.closeLayer
		EventHandler.addListener(window, "mousemove", "extendLayer", this);
	},
	extendLayer: function(e)
	{
		var pos = this.getMousePosition(e);
		var bounds = this.getBounds(this._layer);
		if(pos.x<bounds.left||bounds.right<pos.x
		 ||pos.y<bounds.top||bounds.bottom<pos.y) this.closeLayer();
	},
	closeLayer: function()
	{
		this._layer.style.display = "none";
		EventHandler.removeListener(window, "mousemove", "extendLayer", this);
	},
	getBounds: function(element)
	{
		var width = element.offsetWidth;
		var height = element.offsetHeight;
		var left = element.offsetLeft;
		var top = element.offsetTop;
		while(element.offsetParent)
		{
			element = element.offsetParent;
			left += element.offsetLeft;
			top += element.offsetTop;
		}
		var right = left + width;
		var bottom = top + height;
		return { left:left, top:top, right:right, bottom:bottom, width:width, height:height };
	},
	getMousePosition: function(e)
	{
		var obj = {};
		 
		if(window.event) {
			obj.x = event.x + document.body.scrollLeft;
			obj.y = event.y + document.body.scrollTop;
			
		} else {
			obj.x = e.pageX;
			obj.y = e.pageY;
		}
		return obj;
	}
}

ReplaceSelector.Item = function(node, replaceSelector)
{
	this._uid = ReplaceSelector.Item._counter++;
	var li = document.createElement("li");
	var text = document.createTextNode(node.firstChild.nodeValue);
	li.appendChild(text);
	//li.style.cursor = "pointer";
	this._proxy = li;
	this._proxy.setAttribute("class", "out");
	this._node = node;
	this._label = document.createTextNode(node.firstChild.nodeValue);
	this._replaceSelector = replaceSelector;
	
	EventHandler.addListener(this._proxy, "click", "onClick", this);
	EventHandler.addListener(this._proxy, "mouseover", "onMouseOver", this);
	EventHandler.addListener(this._proxy, "mouseout", "onMouseOut", this);
}
ReplaceSelector.Item._counter = 0;

ReplaceSelector.Item.prototype = {
	getUID: function()
	{
		return this._uid;
	},
	getProxy: function()
	{
		return this._proxy;
	},
	getNode: function()
	{
		return this._node;
	},
	getLabel: function()
	{
		return this._label;
	},
	selectedStatus: function(b)
	{
		var li = this._proxy;
		if(b) {
			li.className += " selected";
			this._node.setAttribute("selected", "selected");
			//
		} else {
			li.className = li.className.replace(/selected/g, "");
			this._node.removeAttribute("selected");
		}
	},
	onClick: function(e)
	{
		this._replaceSelector.closeLayer();
		this._replaceSelector.changeSelection(this._uid);
	},
	onMouseOver: function(e)
	{
		var li = this._proxy;
		li.className = li.className.replace(/out/g, "over");
	},
	onMouseOut: function(e)
	{
		var li = this._proxy;
		li.className = li.className.replace(/over/g, "out");
	}
}
