(function(jQuery) {
	
	jQuery.dropDownMenu = function(ele, o) {
		this.options = jQuery.extend({ 
			width: "auto",
			slideDownSpeed: 1000,
			slideUpSpeed: "fast",
			easeShow:"easeOutQuad",
			easeHide:"easeInQuad"
		},o);
		
		this.elem = ele;
		this.init();
	};
	
	jQuery.extend(jQuery.dropDownMenu, {
		prototype: {
			init: function() {
				var self = this;
				
				if (jQuery(this.elem).is("select")) {
					this.select = this.elem;
					
					jQuery(this.select).wrap("<div class='dropdown'></div>");
					this.control = jQuery(this.select).parent();
				} else {
					this.select = jQuery("select:eq(0)", this.elem);
					if (!this.select.length) return;
					this.select = this.select[0];
					
					jQuery(this.elem).addClass('dropdown');
					this.control = jQuery(this.elem);
				}
				
				var result = jQuery("<div class='dropdown-result-container'><span class='dropdown-result'></span><a class='dropdown-arrow'><span></span></a></div>");
				this.control.append( result );
				this.control.append( "<div class='dropdown-list-container'><ul class='dropdown-list'></ul></div>" );
				
				this.select_options = jQuery("option", this.select);
				this.itemsValue = [];
				for (var i=0,n=this.select_options.length; i < n; i++) {
					var option = jQuery(this.select_options[i]);					
					var h = option.html();
					var c = option.attr("disabled") == "disabled" ? "disabled" : "";
					var c2 = option.attr("selected") != "" ? "selected" : "";
					var v = option.attr("value") || "";
					this.itemsValue[i] = v;
					
					jQuery(".dropdown-list", this.control).append("<li>"+h+"</li>");
					
					if (c != "")
						jQuery(".dropdown-list li:last", this.control).addClass(c);
						
					if (c2 != "")
						jQuery(".dropdown-list li:last", this.control).addClass(c2);
						
					//jQuery(".dropdown-list li:last", this.control).data( "dropdown-optionvalue", v );
				}
				
				this.items = jQuery(".dropdown-list-container li", this.control);
				this.arrow = jQuery(".dropdown-arrow", this.control);
				this.result = jQuery(".dropdown-result", this.control);
				
				if (!this.items.length) {
					return;
				}
				
				if (!jQuery( ".selected", this.items ).length) {
					jQuery(this.items[0]).addClass("selected")
				}
				this.initial = jQuery(jQuery(this.items).filter(".selected")[0]);
				
				this.current = this.initial;
				this.value(this.itemsValue[this.items.index(this.current)]);
				
				//the result size
				if (this.options.width != "auto") {
					jQuery(".dropdown-result-container", this.control).css("width", this.options.width);
				} else {
					var w = jQuery(this.select).outerWidth();
					w -= this.arrow.outerWidth(true);
					w -= parseInt(this.result.css("margin-left")) || 0;
					w -= parseInt(this.result.css("margin-right")) || 0;
					w -= parseInt(this.result.css("padding-left")) || 0;
					w -= parseInt(this.result.css("padding-right")) || 0;
					w -= parseInt(jQuery(".dropdown-result-container", this.control).css("padding-left")) || 0;
					w -= parseInt(jQuery(".dropdown-result-container", this.control).css("padding-right")) || 0;
					
					jQuery(".dropdown-result", this.control).css("width", w+"px");
				}
				
				//the dropdown size
				w1 = jQuery(".dropdown-result-container", this.control).outerWidth();
				w2 = jQuery(".dropdown-list-container", this.control).outerWidth();
				pl = parseInt(jQuery(".dropdown-list-container", this.control).css("padding-left")) || 0;
				pr = parseInt(jQuery(".dropdown-list-container", this.control).css("padding-right")) || 0;
				if ((w2-pr-pl) < w1) {
					jQuery(".dropdown-list-container", this.control).css("width", (w1-pr-pl)+"px");
				}
				
				w1 = jQuery(".dropdown-list-container", this.control).innerWidth();
				w1 -= parseInt(jQuery(".dropdown-list-container", this.control).css("padding-left")) || 0;
				w1 -= parseInt(jQuery(".dropdown-list-container", this.control).css("padding-right")) || 0;
				
				
				w1 -= parseInt(jQuery(".dropdown-list-container .dropdown-list", this.control).css("padding-left")) || 0;
				w1 -= parseInt(jQuery(".dropdown-list-container .dropdown-list", this.control).css("padding-right")) || 0;
				
				jQuery(".dropdown-list-container .dropdown-list", this.control).css({width:w1+"px"});
				
				//the result position
				t = jQuery(".dropdown-result-container", this.control).outerHeight(true);
				t += parseInt(this.control.css("padding-top")) || 0;
				t += parseInt(this.control.css("padding-bottom")) || 0;
				
				jQuery(".dropdown-list-container", this.control).css("top", t+"px");
				
				//events
				this.arrow.bind("click", function() {
					if (self.showed) {
						self.hideMenu.apply(self,[]);
					} else {
						self.showMenu.apply(self,[]);
					}
					return false;
				});
				this.result.bind("click", function() {
					if (self.showed) {
						self.hideMenu.apply(self,[]);
					} else {
						self.showMenu.apply(self,[]);
					}
					return false;
				});
				this.items.each(function() {
					jQuery(this).bind("mouseover", function() {
						if (!jQuery(this).is(".disabled")) {
							jQuery(this).addClass("hover");
						}
					});
					jQuery(this).bind("click", function() {
						self.selectItem.apply(self, [this]);
						self.hideMenu.apply(self,[]);
						return false;
					});
					jQuery(this).bind("mouseout", function() {
						jQuery(this).removeClass("hover");
					});
				});
				jQuery(document).bind("click", function(event){
					self.onDocClick.apply(self,[event]);
				});
				
				//hide original control
				jQuery(this.select).hide();
			},
			
			value: function( val ) {
				if (val == undefined) {
					return this.itemsValue[this.items.index(this.current)];
				} else {
					for (var i=0, n=this.items.length; i < n; i++) {
						v = this.itemsValue[this.items.index(this.items[i])];
						//v = jQuery(this.items[i]).data("dropdown-optionvalue") || "";
						if ( v == val ) {
							this.items.removeClass("selected");
							jQuery(this.items[i]).addClass("selected");
							
							this.current = jQuery(this.items[i]);
							jQuery(".dropdown-result", this.control).html( "<span>"+this.current.html()+"</span>" );
							this.elem.value = val;
							jQuery(this.elem).trigger("change");
							break;
						}
					}
				}
			},
			
			showMenu: function() {
				jQuery(".dropdown-list-container", this.control).show();
				
				this.showed = true;
				
			},
			
			hideMenu: function() {
				jQuery(".dropdown-list-container", this.control).hide();
				
				this.showed = false;
			},
			
			selectItem: function(item) {
				if (jQuery(item).is(".selected") || jQuery(item).is(".disabled")) return false;
				//this.value( jQuery(item).data("dropdown-optionvalue") );
				this.value( this.itemsValue[this.items.index(item)] );
				return true;
			},
			
			onDocClick: function(event) {
				var o = this.control.offset();
				var l = o.left;
				var t = o.top;
				
				var h = this.control.outerHeight();
				h += this.result.outerHeight();
				h += jQuery(".dropdown-list-container", this.control).outerHeight();
				
				var w = jQuery(".dropdown-list-container", this.control).outerWidth();
				
				if (event.clientX < l || event.clientX > l + w || event.clientY < t || event.clientY > (t + h)) {
					this.hideMenu();
				}
			}
		}
	});
	
	
	jQuery.fn.dropDownMenu = function(o) {
		this.each(function() {
			var dropDown = jQuery(this).data("dropDown");
			if (!dropDown) {
				dropDown = new jQuery.dropDownMenu(this, o);
			}
			
			return dropDown;
		});
		
		return this;
	}
	
})(jQuery);