var Classy = {
	String: {
		supplant:function(str,o,regexp){
			regexp = regexp || new RegExp(/{([^{}]*)}/g);
			return str.replace(regexp,
				function (a, b) {
					var r = o[b];
					return typeof r === 'string' || typeof r === 'number' ? r : a;
				}
			);
		}
	}
};

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;
	
	var realOptions = realSelectHtml.options;
	
	realSelectHtml.selectedIndex = realSelectHtml.selectedIndex != null ? realSelectHtml.selectedIndex : 0;
	
	var markup = {
		selected:"<p class='classy-select-input-selected'>"+realOptions[realSelectHtml.selectedIndex].text+"</p>"
	};
	
	var markupOptions = ["<ul class='classy-select-input-options'>"];
	for(var i=0,l=realOptions.length; i<l; i++){
		var realOpt = realOptions[i];
		markupOptions.push("<li>"+realOpt.text+"</li>");
	}
	markupOptions.push("</ul>");
	markup.options = markupOptions.join('');
	
	var id;
	if(this.id){
		id = "id='"+this.id+"' ";
	} else {
		id = "";
	}
	var html = "<div "+id+"class='classy-select-input'><div>{selected}<div class='classy-select-input-arrow'></div></div>{options}</div>";
	
	this.select = $(Classy.String.supplant(html, markup)).insertAfter(realSelect);
	realSelect.css('display','none');
	
	if(!opts.isDelayedEnabled){
		this.enable();
	}
	
	if(this.onCreation){
		this.onCreation.call(this);
	}
};
Classy.SelectInput.prototype = {
	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");
		});
		select.delegate("ul.classy-select-input-options li", 'mouseover', function(){
			$(this).addClass('hover');
		});
		select.delegate("ul.classy-select-input-options li", 'mouseout', function(){
			$(this).removeClass('hover');
		});
		select.delegate("ul.classy-select-input-options li", 'click', function(){
			_this.changeSelected($(this).index());
			return false;
		});

		// handle click outside
		$(document).bind('click',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");
		select.undelegate("ul.classy-select-input-options li","mouseover");
		select.undelegate("ul.classy-select-input-options li","mouseout");
		select.undelegate("ul.classy-select-input-options li","click");
		$(document).unbind("click");
	},
	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;
	},
	selectedIndex:function(){
		return this.realSelectHtml.selectedIndex;
	},
	value:function(){
		return this.realSelectHtml.value;
	},
	toggleOptionsVisibility:function(){
		if(this.optionsAreVisible){
			this.hideOptions();
		} else {
			this.showOptions();
		}
	},
	showOptions:function(){
		this.optionsAreVisible = true;
		if(!this.isAnimated){
			$(this.select).find('ul.classy-select-input-options').css('display','block');
		} else {
			$(this.select).find('ul.classy-select-input-options').slideDown('fast');
		}
	},
	hideOptions:function(){
		this.optionsAreVisible = false;
		if(!this.isAnimated){
			$(this.select).find('ul.classy-select-input-options').css('display','none');
		} else {
			$(this.select).find('ul.classy-select-input-options').slideUp('fast');
		}
	},
	changeSelected:function(index){
		this.realSelect.find(":selected").removeAttr('selected');
		var selected = this.realSelect.find("option:eq("+index+")");
		selected.attr('selected','selected');
		this.select.find("div:first p").text(selected.get(0).text);
		if(this.onChange){
			this.onChange.call(this,this.value());
		}
	}
};

/*
	Radio Input,
*/

Classy.RadioInput = function(radiosElement, opts){
	var _this = this;
	
	this.radiosName = radiosElement;
	
	var realRadios = this.realRadios = $('input[name='+radiosElement+']');
	var realRadiosHtml = this.realRadiosHtml = [];
	realRadios.each(function(i, el) {
		if(this.checked) { _this.defaultIndex = i; }
		_this.realRadiosHtml[i] = this;
	});
	
	this.onCreation = opts.onCreation || false;
	this.onChange = opts.onChange || false;
	
	this.cssClass = opts.cssClass || "";
	
	var html = "";
	
	this.radios = [];
	var checkedClass = '';
	for(var i=0;i<realRadios.length;i++) {
		if(i == _this.defaultIndex) { checkedClass = ' classy-radio-input-checked'; }
		else { checkedClass = '' }
		this.radios[i] = $("<div id='classy-radio-input-"+i+"' class='classy-radio-input"+checkedClass+" "+this.cssClass+"' rel='"+realRadios[i].value+"'></div>").insertAfter(realRadios[i]);
	}
	
	realRadios.css('display','none');
	
	if(!opts.isDelayedEnabled){
		this.enable();
	}
	
	if(this.onCreation){
		this.onCreation.call(this);
	}
};
Classy.RadioInput.prototype = {
	enable:function(){
		var _this = this;
		var radios = $(this.radios);
		
		radios.each(function(i) {
			this.bind('click', function() {
				var radio = _this.realRadios[i];
				if(!radio.checked) {
					_this.setValue(radio.value);
				}
			});
		});
		
		_this.realRadios.bind('change', function() {
			_this.setValue(this.value);
		});
		
	},
	disable:function(){ // TO DO
		var radios = $(this.radios);
		radios.unbind("click");
	},
	defaultValue:function(){ // TO DO
		var index = this.defaultIndex;
		var defaultValue = false;
		if(index) { this.setValue(index, true); }
		
		return defaultValue;
	},
	value:function(){
		return this.realRadiosHtml.filter(':checked').value;
	},
	setValue:function(val, isIndex) {
		var radios = $(this.radios);
		
		if(isIndex && this.realRadios[val]) {
			radios.removeClass('classy-radio-input-checked');
			
			this.realRadios[val].checked = true;
			radios[val].addClass('classy-radio-input-checked');
			
			rtn = true;
		}
		else {
			var rtn = false;
			var valRadio = $('input[name='+this.radiosName+'][value='+val+']');
			if(valRadio.length > 0) {
				
				valRadio.attr('checked', 'checked');
				radios.each(function() {
					var r = $(this);
					if(r.attr('rel') == val) { r.addClass('classy-radio-input-checked'); }
					else { r.removeClass('classy-radio-input-checked'); }
				});
				
				rtn = true;
			}
		}
		
		return rtn;
	}
};


