;(function($) {

	$.fn.dropdown = function(options) {

		return this.each(function() {
			var settings = jQuery.extend(true, {}, $.fn.dropdown.defaults, options);

			var $this = $(this);
			var $header = $("span:first", $this);
			var $list = $("ul", $this);
			var $listItems = $("li", $list);
			$list.wrap("<div class='pane'></div>");
			var $pane = $(".pane", $this).corners(settings.corners);

			$this.bind("show", function() {
				$this.showDropdown();
			});

			$this.bind("hide", function() {
				$this.hideDropdown();
			});

			$this.bind("toggle", function() {
				$this.toggleDropdown();
			});

			$header.data("defaultValue", settings.defaultText || $header.text());

			var dimensions = $this.trueDimensions({
				onCreate: function(o) {
					return $(".pane", o); // we need lists height, not dropdowns
				}
			});
			if (settings.scrollEnabled && dimensions.height > settings.maximumHeight) {
				$list.width(dimensions.width-20);
				// get height again, in case changing width bumped some text to multiple lines
				dimensions = $this.trueDimensions({
					onCreate: function(o) {
						return $(".pane", o); // we need lists height, not dropdowns
					}
				});

				$list.jScrollPane({
					paneWidth:dimensions.width,
					paneHeight:settings.maximumHeight,
					contentHeight:dimensions.height
				});
				$(".jScrollPaneContainer", $pane).width(dimensions.width).height(settings.maximumHeight);
				$list.height(dimensions.height);
				$pane.height(settings.maximumHeight);
				dimensions.height = settings.maximumHeight;
			}

			$pane.css(settings.deactivateCSS).hide();
			settings.activateCSS = $.extend(settings.activateCSS, {height:dimensions.height});

			$header.click(function() {
				$this.trigger("toggle");
				$("html,body").bind("mousedown", function() {
					$this.trigger("hide");
				});
				$this.bind("mousedown", function(e) {
					e.stopPropagation();
				});
			});
			/*
			$header.hover(function() {
				$this.clearHideDropdown();
				$this.showDropdown();
			}, function() {
				$this.hideDropdown();
			});

			$pane.hover(function() {
				$this.clearHideDropdown();
			}, function() {
				$this.hideDropdown();
			});

			$listItems.hover(function() {
				$this.clearHideDropdown();
				// $(this).children("a").addClass("hover");
			}, function() {
				$this.hideDropdown();
				// $(this).children("a").removeClass("hover");
			});
			*/
			$("li a", $list).click(function() {
				var result = settings.onChange($(this), $(this).text());
				if (settings.save) $this.setHeader($(this).text());
				$this.trigger("hide");
				return result;
			});
			$(this).data('settings', settings);
			$this.setHeader($header.data("defaultValue"));
		});
	};

	$.fn.showDropdown = function(options) {
		return this.each(function() {
			var $this = $(this);
			var $header = $("span:first", $this);
			var $pane = $(".pane", $this);
			var $list = $("ul", $this);

			var defaults = $this.data('settings');
			var settings = $.extend(true, {}, defaults, options);

			settings.onOpen($this);
			$this.css({position:"relative", "z-index":70});
			if (!$pane.is(":visible")) $pane.show();
			$pane.stop().animate(settings.activateCSS, settings.speed, settings.easing, function() {
				$pane.css({'filter': ''});
			});
		});
	};

	$.fn.hideDropdown = function(options) {
		return this.each(function() {
			var $this = $(this);
			var $header = $("span:first", $this);
			var $pane = $(".pane", $this);
			var $list = $("ul", $this);

			var defaults = $this.data('settings');
			var settings = $.extend(true, {}, defaults, options);
			$("html,body").unbind("mousedown");
			$(".dropdown").unbind("mousedown");
			var hidePane = function() {
				$this.clearHideDropdown();
				$this.css({"z-index":69});
				$pane.stop().animate(settings.deactivateCSS, settings.speed, settings.easing, function() {
					$this.css({position:"static", "z-index":1});
					$pane.hide();
					settings.onClose($this);
				});
			};

			$this.data('dropdownHideTimer', setTimeout(function() {
				hidePane();
			}, settings.mouseOffDelay));
		});
	};

	$.fn.hideOthers = function() {
		return this.each(function() {
			var $this = $(this);
		});
	};

	$.fn.toggleDropdown = function() {
		return this.each(function() {
			var $this = $(this);
			var $pane = $(".pane", $this);
			if ($pane.is(":visible")) $this.hideDropdown();
			else $this.showDropdown();
		});
	};

	$.fn.setHeader = function(s) {
		return this.each(function() {
			var $this = $(this);
			if ($this.data("settings").preventLongHeader) {
				var limit = ($this.hasClass("small")) ? 16 : 24;
				var $header = $("span:first", $this).data("value", s); // save the value
				// var width = $header.innerWidth() - 20;
				$header.text(s);
				if (s.length > limit) $header.text(s.substring(0, limit - 3) + "...");
			}
		});
	};

	$.fn.clearHideDropdown = function() {
		return this.each(function() {
			var $this = $(this);
			if ($this.data('dropdownHideTimer')) clearTimeout($this.data('dropdownHideTimer'));
		});
	};

	$.fn.resetDropdown = function() {
		return this.each(function() {
			var $header = $("span:first", $(this));
			$header.text($header.data("defaultValue"));
		});
	};

	$.fn.dropdown.defaults = {
		activateCSS: {opacity:1},
		corners: "5px",
		deactivateCSS: {height:0, opacity:0},
		easing: "swing",
		maximumHeight: 300,
		mouseOffDelay: 100,
		onChange: function(o, value){ return true; },
		onClose: function(o){ return false; },
		onOpen: function(o){ return false; },
		preventLongHeader: true,
		save: false,
		scrollEnabled: true,
		speed: 300
	};

})(jQuery);