function ProperSelect(element, properties) {
	if(typeof element == "string")
		element = document.getElementById(element);

	if(element == null)
		throw new Error("Element does not exist.");
		
	if(properties == null)
		properties = {};
	
	this.onchange = properties.onchange;
	this.properties = {
		propertySeparator	:	properties.propertySeparator || "|",
		selectOnHover	:	properties.selectOnHover || false,
		zIndex	:	properties.zIndex || 666,
		defer	:	properties.defer || false,
		showFunction	:	properties.showFunction,
		hideFunction	:	properties.hideFunction,
		label			:	properties.label,
		containerClass	:	properties.containerClass || "proper-select-container",
			labelClass	:	properties.labelClass || "proper-select-label",
				labelClassOpen	:	properties.labelClassOpen || (properties.labelClass || "proper-select-label"),
				labelClassHover	:	properties.labelClassHover || (properties.labelClass || "proper-select-label"),
			contentClass	:	properties.contentClass || "proper-select-content",
				ulClass			:	properties.ulClass || "proper-select-ul",
					liClass		:	properties.liClass || "proper-select-li",
					selectedClass	:	properties.selectedClass || "proper-select-li-selected",
					hoverClass		:	properties.hoverClass || "proper-select-li-hover"
	}
	if(this.properties.defer == true) {
		var oldonload = window.onload;
			properties.defer = false;
		window.onload = function() {
			if(oldonload) oldonload();
			new ProperSelect(element,properties)
		}
		return;
	}
	if(element.tagName.toLowerCase() == "ul") {
		var lis = element.getElementsByTagName("li");
		var tOptions = new Array();
		element.name = element.id;
		element.selectedIndex = 0;
		for(var i = 0; i < lis.length; i++) {
			var contents = lis[i].innerHTML.match(/^<!--(.*?)-->(.*)/); //indexOf(this.properties.valueSeparator);
			var prop = (contents == null)? null : contents[1];
			if(prop != null) {
				prop = prop.split(this.properties.propertySeparator);
				if(prop.length > 1) {
					for(var j = 1; j < prop.length; j++) {
						if(prop[j].toLowerCase() == "selected") {
							lis[i].selected = true;
							element.selectedIndex = i;
						} else if(prop[j].toLowerCase() == "disabled") {
							lis[i].disabled = true;
						}
					}
				}
			}		
			lis[i]._value = (prop == null)? "" : prop[0];
			lis[i].innerHTML = (contents == null)? lis[i].innerHTML : contents[2];
		}
		if(element.selectedIndex == 0 && lis.length > 0)
			lis[0].selected = true;
		element.options = lis;
	}
	
	this.origin = element;
	
	if(this.origin.options.length == 0)
		return;
	
	var self = this;
	
	this.options = new Array();
	this.uniqueId = "properselect-" + Math.random().toString().replace(/\./,"-");
	
	this.container = document.createElement("div");
	this.container.setAttribute("id", (this.origin.id)? "properselect-" + this.origin.id : this.uniqueId);
	this.container._properSelect = this;
	
	this.valueField = document.createElement("input");
	this.valueField.setAttribute("type","hidden");
	this.valueField.name = this.origin.name;
		this.origin.name += "-properselect";
	this.valueField.id = this.origin.id;
		this.origin.id += "-properselect";
	this.container.appendChild(this.valueField);
	
	this.label = document.createElement("div");
	this.label.style.cursor = "pointer";
	var oldOnclick = document.onclick;
	//this.label.onclick = function(e) { if(document.onclick) document.onclick(e); if(!self.isOpen()) self.showContent(); if(self.origin.onclick) self.origin.onclick(e); };
	document.onclick = function(e) { if(oldOnclick) oldOnclick(e); self.blur(e); };
	this.label.onclick = function(e) {  if(self.origin.onclick) self.origin.onclick(e); };
	this.label.onmouseover = function(e) { this.className = self.properties.labelClassHover; if(self.origin.onmouseover) self.origin.onmouseover(e); };
	this.label.onmouseout = function(e) { if(!self.isOpen()) this.className = self.properties.labelClass; if(self.origin.onmouseout) self.origin.onmouseout(e); };
	this.container.appendChild(this.label);
	
	this.content = document.createElement("div");
	this.content.setAttribute("id",this.container.id+"-content");
	this.content.style.display = "none";
	this.content.style.position = "absolute";
	this.content.style.zIndex = this.properties.zIndex;
	this.container.appendChild(this.content);
	
	this.ul = document.createElement("ul");
	//this.ul.style.position = "absolute";
	this.content.appendChild(this.ul);
	
	for(var i = 0; i < this.origin.options.length; i++) {
		this.addNode(this.origin.options[i]);
	}
	
	if(this.properties.label) {
		this.setLabel(this.properties.label);
		this.selectedIndex = -1;
	}
		
	this.container.className = this.properties.containerClass;
	this.label.className = this.properties.labelClass;
	this.content.className = this.properties.contentClass;
	this.ul.className = this.properties.ulClass;
	
	var parentElement = this.origin.parentNode;
	if(parentElement != null) {
		var nextSibling = this.origin.nextSibling;
		if(nextSibling != null) {
			parentElement.insertBefore(this.container, nextSibling);
		} else {
			parentElement.appendChild(this.container);
		}
	} else {
		document.body.appendChild(this.container);
	}
	this.origin.style.display = "none";
	return this;
}

ProperSelect.prototype.blur = function(e) {
	var target = (e && e.target) || (event && event.srcElement);
	var isTarget = false;

	while(target) {
		if(target == this.label) {
			isTarget = true;
			break;
		}
		target = target.parentNode;
	}
	if(this.content.style.display == "none" && isTarget)
		this.showContent();
	else if(this.content.style.display != "none")
		this.hideContent();
}

ProperSelect.prototype.selectValue = function(i, init) {
	if(this.selectedIndex != null && this.selectedIndex > -1)
		this.options[this.selectedIndex].className = this.options[this.selectedIndex].className.replace(" " + this.properties.selectedClass,"");
	
	var previosSelected = this.selectedIndex;
	this.origin.selectedIndex = i;
	this.selectedIndex = i;
	if(init == false && previosSelected != i) {
		if(this.origin.onchange)
			this.origin.onchange();
		if(this.onchange)
			this.onchange();
	}
	this.options[this.selectedIndex].className += " " + this.properties.selectedClass;
	this.setLabel(this.options[this.selectedIndex].innerHTML);
	this.valueField.value = this.options[this.selectedIndex]._value;
};

ProperSelect.prototype.hoverValue = function(element, event) {
	if(event == "over")
		element.className += " " + this.properties.hoverClass;
	else
		element.className = element.className.replace(" " + this.properties.hoverClass, "");
}
	
ProperSelect.prototype.setLabel = function(str) {
	this.label.innerHTML = str;
}

ProperSelect.prototype.getLabel = function() {
	return this.label.innerHTML;
}

ProperSelect.prototype.addNode = function(origin) {
	var node = document.createElement("li");
	var i = this.options.length;
	var self = this;
		
	node.innerHTML = origin.innerHTML;
	node._value = origin._value || origin.value;
	node._index = i;
	node._properSelect = this;
	node.disabled = origin.disabled || false;
	if(node.disabled == false)
		node.style.cursor = "pointer";
	node.onclick = function(e) { if(origin.onclick) origin.onclick(e); if(self.options[this._index].disabled != true) self.selectValue(this._index, false); };
	node.onmouseover = function(e) {
		if(self.options[this._index].disabled != true)
			this._properSelect.hoverValue(this, "over");
		if(this._properSelect.properties.selectOnHover)
			this._properSelect.setLabel(this.innerHTML);
		if(origin.onmouseover)
			origin.onmouseover(e);
	};
	node.onmouseout = function(e) { if(self.options[this._index].disabled != true) self.hoverValue(this, "out"); if(origin.onmouseout) origin.onmouseout(e); };
	node.setAttribute("class", this.properties.liClass + ((origin.disabled == true)? " disabled" : ""));
	
	this.options.push(node);
	if(i >= this.origin.options.length)
		this.origin.options[i] = new Option(node.innerHTML, node._value);
	if(origin.selected == true)
		this.selectValue(i, true);
	
	this.ul.appendChild(node);
	
	return node;
}

ProperSelect.prototype.toggleContent = function() {
	if(this.content.style.display == "")
		this.hideContent();
	else
		this.showContent();
}
ProperSelect.prototype.showContent = function() {
	var self = this;
	var oldonclick = document.onclick;
	// if(typeof oldonclick == "function")
		// oldonclick({ target: this.label });
	//window.setTimeout(document.onclick = function() { self.hideContent(); document.onclick = null; },500);
	// document.onclick = function(e) {
		// self.hideContent();
		// // var target = (e && e.target) || (event && event.srcElement);
		// // while(target) {
			// // if(target == self.label) {
				// // return hideProperSelect(self);
			// // }
			// // target = target.parentNode;
		// // }
		// // hideProperSelect();
		// // // // if(!isTarget && self.isOpen()) {
			// // // // self.hideContent();
		// // // //document.onclick = oldonclick;
		// // // // } 
		 // // // //if(typeof oldonclick == "function")
		// // // //	 oldonclick((e || event));
	// }

	if(this.properties.showFunction != null)
		this.properties.showFunction(this.content);
	else
		if(this.content.style.display == "")
			this.content.style.display = "none";
		else
			this.content.style.display = "";
		//this.content.style.display = "";
		
	this.label.className = this.properties.labelClassOpen;
}

ProperSelect.prototype.hideContent = function(oldonclick, e) {
	if(this.properties.hideFunction != null)
		this.properties.hideFunction(this.content);
	else
		if(this.content.style.display == "")
			this.content.style.display = "none";
		else
			this.content.style.display = "";

	this.label.className = this.properties.labelClass;
	if(this.properties.selectOnHover)
		this.setLabel(this.options[this.selectedIndex].innerHTML);
}

ProperSelect.prototype.isOpen = function() {
	return (this.content.style.display == "");
}
