/**
 * Classy.SelectInput
 *
 * @author		Charles Demers (charles.demers6@gmail.com)
 * @requires	[classy.js, jquery-1.4.2.js]
 * @provides 	[classy.SelectInput]
 *
 */

classy.SelectInput = function(selectElement, opts) {
	
	var realSelect = this.realSelect = $(selectElement);
	var realSelectHtml = this.realSelectHtml = realSelect.get(0);
	
	this.onCreation = opts.onCreation || false;
	this.onChange = opts.onChange || false;
	
	this.id = opts.id || false;
	this.optionsAreVisible = false;
	this.isAnimated = opts.isAnimated || false;
	this.hasOptGroups = false;
	
	var markup = {
		id:""
	};
	
	
	var mainUl = $("<ul class='classy-select-input-options'>");
	
	var markupOptions = [];
	
	var realOptGroups = realSelectHtml.getElementsByTagName("optgroup");
	
	if(realOptGroups.length > 0) {
		this.hasOptGroups = true;
		
		for(var i=0, l=realOptGroups.length; i<l; i++) {
			markupOptions.push("<li class='classy-select-input-optgroup'>"+realOptGroups[i].label+"<ul>");
			var realOpts = realOptGroups[i].getElementsByTagName("option");
			for(var ind=0, len=realOpts.length; ind<len; ind++) {
				markupOptions.push("<li><span class='classy-select-input-check'></span>"+realOpts[ind].text+"</li>");
			}
			markupOptions.push("</ul></li>");
		}
	} else {
		var realOptions = realSelectHtml.getElementsByTagName("option");
	
		for(var j=0,k=realOptions.length; j<k; j++) {
			markupOptions.push("<li><span class='classy-select-input-check'></span>"+realOptions[j].text+"</li>");
		}
	}
	mainUl.html(markupOptions.join(''));
	this.options = $(mainUl).appendTo("body");
	
	if(this.id) {
		markup.id = "id='"+this.id+"' ";
	}
	var html = "<div {id}class='classy-select-input'><p class='classy-select-input-selected'></p><div class='classy-select-input-arrow'></div></div>";
	
	this.select = select = $(classy.string.supplant(html, markup)).insertAfter(realSelect);
	
	realSelect.css('display','none');
	
	this.index(this.defaultIndex());
	
	if(!opts.isDelayedEnabled) {
		this.enable();
	}
	
	if(this.onCreation) {
		this.onCreation.call(this);
	}
};
classy.SelectInput.prototype = {
	add:function(opts) {
		var realOpt = "<option value='"+opts.value+"'>"+opts.text+"</option>",
			fakeOpt = "<li><span class='classy-select-input-check'></span>"+opts.text+"</li>";
		if(typeof opts.index == "undefined" || opts.index == this.length()) {
			this.realSelect.append(realOpt);
			this.options.append(fakeOpt);
		} else {
			var realIndex = this.realSelect.find("option:eq("+opts.index+")");
			var fakeIndex = this.options.find("li:not(.classy-select-input-optgroup)").filter("li:eq("+opts.index+")");
			realIndex.before(realOpt);
			fakeIndex.before(fakeOpt);
		}
	},
	remove:function(index) {
		this.realSelect.get(0).remove(index);
		this.options.find("li:eq("+index+")").remove();
	},
	enable:function() {
		var _this = this;
		var select = $(this.select);
		select.bind("click",function() {
			_this.toggleOptionsVisibility();
		});

		select.bind("mouseover",function() {
			$(this).css("cursor","pointer");
		});
		select.bind("mouseout",function() {
			$(this).css("cursor","default");
		});
		this.options.delegate("li:not(.classy-select-input-optgroup)", 'mouseover', function() {
			$(this).addClass('hover');
		});
		this.options.delegate("li:not(.classy-select-input-optgroup)", 'mouseout', function() {
			$(this).removeClass('hover');
		});
		this.options.delegate("li:not(.classy-select-input-optgroup)", 'click', function() {
			if(_this.hasOptGroups) {
				var options = _this.getOptions();
				for(var i=options.length; i--; ) {
					if($(options[i]).filter(this).length > 0) {
						_this.index(i);
					}
				}
			} else {
				_this.index($(this).index());
			}
			_this.hideOptions();
			return false;
		});
		
		$(window).bind('resize', $.proxy(this, "hideOptions"));
		
		// handle click outside
		$(document).bind('click', $.proxy(this, "manageClickOutside"));
	},
	manageClickOutside:function(e) {
		if(this.optionsAreVisible) {
			var parentElement = this.realSelect.next('.classy-select-input').get(0);
			if($.contains(parentElement,e.target) === false && parentElement !== e.target) {
				this.hideOptions();
			}
		}
	},
	disable:function() {
		var select = $(this.select);
		select.unbind("click");
		select.unbind("mouseover");
		select.unbind("mouseout");
		this.options.undelegate("li","mouseover");
		this.options.undelegate("li","mouseout");
		this.options.undelegate("li","click");
		$(document).unbind("click", this.manageClickOutside);
		$(window).unbind('resize', this.hideOptions);
	},
	length:function() {
		return this.realSelectHtml.length;
	},
	defaultIndex:function() {
		var defaultSelected;
		for(var i=0,l=this.realSelectHtml.options.length; i<l; i++) {
			if(this.realSelectHtml.options[i].defaultSelected) {
				return i;
			}
		}
		return 0;
	},
	defaultValue:function() {
		var index = this.defaultIndex;
		return this.realSelectHtml.options[index].value;
	},
	index:function(index) {
		if(typeof index == "undefined") {
			return this.realSelectHtml.selectedIndex;
		} else {
			this.realSelect.find("option:selected").removeAttr('selected');
			var selected = this.realSelect.find("option:eq("+index+")");
			
			var thisSelected = this.getOptions()[index];
			this.options.find("li.selected").removeClass("selected");
			$(thisSelected).addClass("selected");
			
			selected.attr('selected','selected');
			this.select.find(".classy-select-input-selected").text(selected.get(0).text);
			if(this.onChange) {
				this.onChange.call(this,this.value());
			}
		}
	},
	value:function(value) {
		if(typeof value == "undefined") {
			return this.realSelectHtml.value;
		} else {
			this.realSelect.find(":selected").removeAttr('selected');
			var selected = this.realSelect.find("option[value="+value+"]");

			var index = selected.get(0).index;
			
			var thisSelected = this.getOptions()[index];
			this.options.find("li.selected").removeClass("selected");
			$(thisSelected).addClass("selected");
			
			selected.attr('selected','selected');
			this.select.find(".classy-select-input-selected").text(selected.get(0).text);
			if(this.onChange) {
				this.onChange.call(this,this.value());
			}
		}
	},
	toggleOptionsVisibility:function() {
		if(this.optionsAreVisible) {
			this.hideOptions();
		} else {
			this.showOptions();
		}
	},
	showOptions:function() {
		
		var offset = this.select.offset(),
			height = this.select.outerHeight();
		
		this.options.css({
			top:offset.top + height,
			left:offset.left
		});
		
		this.optionsAreVisible = true;
		if(!this.isAnimated) {
			$(this.options).css('display','block');
		} else {
			$(this.options).slideDown(150);
		}
	},
	hideOptions:function() {
		this.optionsAreVisible = false;
		if(!this.isAnimated) {
			$(this.options).css('display','none');
		} else {
			$(this.options).slideUp(150);
		}
	},
	getOptions:function() {
		return this.options.find("li:not(.classy-select-input-optgroup)");
	}
};
