
jQuery(function($) {
$.fn.customSelect = function(settings) {

	settings = $.extend({
		speed: 'normal'
	}, settings);

	return this.each(function() {
		$this = $(this);

		if($this.context.nodeName == 'SELECT') {
			customizeSelect($this);
		}
		else {
			$('select', $this).each(function() {
				customizeSelect($(this));
			});
		}
	});
	
	
	function changeTo($el) {
		var v = $el.html();
		var $holder = $el.closest('.cs-holder');
		$('.cs-option', $holder).removeClass('cs-selected');
		$el.addClass('cs-selected');

		$('.cs-val', $holder).html(v);
		$holder.prev('input').val(v);
	}
	
	
	function hideSelect(selector) {
		$(selector).unbind('keypress').hide(settings.speed);
	}


	function customizeSelect($sel) {
		// ----------  CREATION  ----------
		var id = $sel.attr('id');
		var csId = 'cs-'+id;
		var csVal = $(':selected', $sel).attr("value");
		
		var listOpts = '';
		$sel.children('option').each(function(){
			var v = $(this).attr("value");
			var selectedClass = (v == csVal) ? ' cs-selected' : '';
			listOpts += '<p id="'+csId+'-option'+v+'" class="cs-option'+selectedClass+'">'+v+'</p>';
		});
		
		var name = $sel.attr('name');
		var csHidden = '<input type="hidden" id="'+id+'" name="'+name+'" value="'+csVal+'" />';
		var csHtml = '<div class="cs-val" id="'+csId+'-val" tabindex="0">'+csVal+'</div>';
		var csOpts = '<div class="cs-options" id="'+csId+'-options">'+listOpts+'</div>';
		$sel.replaceWith(csHidden+'<div id="'+csId+'" class="cs-holder">'+csHtml+csOpts+'</div>');
		
		
		// ----------  HOVER  ----------
		$('#'+csId+'-val').hover(
			function() { $(this).toggleClass('cs-hover'); }
		);
		
		
		// ----------  ANIMATION  ----------
		var $cs = $('#'+csId);
		$cs.click(function() {
			var selector = '#'+csId+'-options';
			$(selector).toggle(settings.speed);
			hideSelect('.cs-options:not('+selector+')');
		});
		
		$('.cs-option', $cs).hover(
			function() { $(this).toggleClass('cs-opt-hover'); }
		).click(function() {
			changeTo($(this));
		});
		
		
		// ----------  KEYBOARD ----------
		$cs.keydown(function(e) {
			var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;
			switch(key){
				case 32: $('#'+csId+'-options').toggle(settings.speed);
					break;
				case 38: changeTo($('.cs-selected', this).prev());
					break;
				case 40: changeTo($('.cs-selected', this).next());
					break;
				case 13: $('.cs-selected', this).click();
					break;
				case 9: $('.cs-options', this).hide(settings.speed);
					return true;
					break;
				case 116: return true;
					break;
			}
			return false;
		});

		
		// ----------  OUTSIDE CLICK DETECTION  ----------
		$cs.hover(
			function() {
				$(document).unbind('click');
			},
			function() {
				$(document).bind('click', function(){
					hideSelect('.cs-options');
				});
			}
		);
	}

};
});
