/*
 * @fileoverview JQuery plugin to replace select menu's with
 * nice looking alternatives.
 *
 * @author humjay jason@humjay.com
 * @version 0.1
 */

(function($){
	
	$.humjay = $.humjay || {};
	$.humjay.dropdown = {
		conf: {
			optionWrapperClass: 'options-wrapper',
			optionClass: 'options'
		}
	}
	function Dropdown(el, conf) {
		el = $(el);

		// check if this is a select element
		if(el.attr('tagName').toUpperCase() != "SELECT") { return false; }
		
		// Grab all the attributes and values from the select menu
		var self	= this;
		var rand	= "el-" + new Date().getTime();
		var id		= el.attr("id") || rand;
		var name	= el.attr("name") || rand;
		var options = el.children("option").map(
			function() {
				var child = $(this);
				return {
					option: 	child.text() || "", 
					val: 		child.attr("value") || "",
					selected:	child.attr("selected") || ""
				};
			}
		);

		// Create a new hidden field to hold the value of our replaced select.
		// and insert the new field right before the old menu
		var input = $("<input type='hidden' />").attr({id: id, name: name, value: ""});
		el.before(input);

		// Remove the old select menu
		el.remove();

		// Create the replacement
		// This long chain creates the following html:
		// -------------------------------------------
		/* <div class="select-replacement">
			<div class="active-text"><span>afternoon</span></div>
			<div class="options" style="display: none">
				<ul>
					<li class="selected">erf</li>
					<li>erf</li>
					<li>erf</li>
				</ul>
			</div>
		</div> */
		// -------------------------------------------
		

		var replacement = $("<div/>").css("zIndex", conf.zIndex);
		var optionList = $("<ul/>");

		options.each(function(i){
			var li = $("<li/>")
				.data("value", this.val)
				.data("input", input)
				.data("replacement", replacement)
				.text(this.option)
				.click(function(e){
					e.stopPropagation();
					self.setValue(this);
				})
				.mouseover(function(e){
					e.stopPropagation();
					$(this).addClass("hover");
				})
				.mouseout(function(e){
					e.stopPropagation();
					$(this).removeClass("hover");
				});

			if(this.selected != "") { li.addClass("selected"); }
			li.appendTo(optionList);
		});

		optionList = optionList
			.wrap("<div/>")
			.parent()
			.addClass(conf.optionClass)
			.wrap("<div/>")
			.parent()
			.addClass(conf.optionWrapperClass).css({ display: "none"});

		replacement
			.addClass("select-replacement")
			.append("<div/>")
			.children()
			.addClass("active-text")
			.append("<span/>")
			.end()
			.append(optionList)
			.click(function(e){ 
				self.toggle();
				e.stopPropagation();
				});

		input.after(replacement);
		
		var _open = false;
		
		var hydrateInput = function(sel) {
			$(sel).data("input").val($(sel).data("value"));
		};

		// Add a class of "active" to the list item
		// that was just chosen, and clear any old classes
		var toggleActiveClass = function(sel) {
			$(sel).siblings()
				.removeClass("selected")
				.end()
				.addClass("selected");
		};

		// Change the text so the selected text appears
		// after the select menu is closed
		var changeActiveText = function(dropdown, opt) {
			dropdown.find(".active-text span")
				.text(opt.text());
		};

		this.open = function() {
			optionList.slideDown();
			_open = true;
		};

		this.close = function() {
			optionList.slideUp();
			_open = false;
		};
		
		this.isOpen = function() {
			return _open;
		}
		
		this.toggle = function() {
			if(this.isOpen()) {
				 this.close();
				} else {
				 this.open();
				}
		}

		this.setValue = function(opt) {	
			opt = $(opt);
			hydrateInput(opt);
			toggleActiveClass(opt);
			changeActiveText(replacement, opt);

			this.close();
		};
		
		// Default selected value, find a selected class
		// or default to the first option
		this.setValue(optionList.find(".selected").eq(0) || optionList.find("li").eq(0));
		
		
	}
	
	// jQuery plugin implementation
	$.fn.dropdown = function(conf) { 
			
		conf = $.extend({}, $.humjay.dropdown.conf, conf); 
		
		conf.zIndex = conf.zIndex || 10000;
		this.each(function(i) {		
			conf.zIndex = conf.zIndex - 1;

			var el = new Dropdown($(this), conf);
			$(this).data("dropdown", el);	
		});
		
		return this;
		
	};
	
})(jQuery);

 
