/* Usage: $('#mySelect').pseudoSelect(); */

(function($) {

	$.fn.pseudoSelect = function(settings) {
		
		var config = {};
		if (settings) {
			$.extend(config, settings);
		}
		
		this.each(function() {
		
			var HTMLSelect = $(this);
				className = 'pseudoSelect';
			
			if (config.psClass) {
				className = className + ' ' + config.psClass;
			}
			
			// Wrap select box so it is contained
			HTMLSelect.wrap('<div class="' + className + '" />').hide();
					
			var	parent = HTMLSelect.parents('.pseudoSelect'); // Get the new parent
				html = '';
				
			// Build HTML for options
			HTMLSelect.find('option').each(function() {
				
				var option = $(this);
				
				// The value of each option is stored in the ids of the new list items. This value is prefixed with the select boxes name attribute.
				if (HTMLSelect.val() == option.val()) {
						html += '<li class="ps_selected" id="' + HTMLSelect.attr('name') + '_' + option.attr('value') + '">' + option.text() + '</li>';
					} else {
						html += '<li id="' + HTMLSelect.attr('name') + '_' + option.attr('value') + '">' + option.text() + '</li>';
					}
			});
			
			// Wrap HTML
			html = '<div class="ps_select"><div class="ps_current"><span>' + HTMLSelect.find(':selected').text() + '</span></div><ul>' + html + '</ul></div>';
			// Append HTML
			$(html).appendTo(parent);
			
			var psSelectInput = $('.ps_select .ps_current');
				psSelectList = $('.ps_select ul');
			
			// Hide options (shown on click)
			psSelectList.hide();
			
			// Bind events
			parent.find('.ps_select').bind('click', showOptions);
			parent.find('li').bind('click', { select : HTMLSelect }, selectOption);
			
			/*
			if (config.width) {
				var width = config.width;
				if (width.toLowerCase() === 'auto') {
					autoWidth(parent);
				}
			}
			*/
		});
		
		return this;
	};
	
	function showOptions() {
	
		var select = $(this);		
			current = select.find('.ps_current');
			options = select.find('ul');
			otherSelects = $('.ps_select').not(select);
		
		// Stop more than one select being visible at a time	
		if (otherSelects.length > 0) {
			otherSelects.find('ul:visible').hide();
			otherSelects.find('.ps_active').removeClass('ps_active');
		}
		
		options.toggle();
		current.toggleClass('ps_active');
		
		$(document).click(function(e) {
			if ($(e.target).is(current) || $(e.target).parents('.ps_select').length > 0) {
				return;
			} 
			else {
				options.hide();
				$(current).removeClass('ps_active');
			}		
		});
	}
	
	function selectOption(event) {
				
		var HTMLSelect = event.data.select;
			option = $(this);		
			list = option.parents('ul');
			select = option.parents('.ps_select');
			current = select.find('.ps_current span');
			prefixLength = HTMLSelect.attr('name').length + 1;
		
		// Update current option
		current.text(option.text());
		list.find('li').removeClass('ps_selected');
		option.addClass('ps_selected');
		
		// Update the value of the real select box. Now the form submission will be correct.
		HTMLSelect.val(option.attr('id').substr(prefixLength));
	}
	
	function autoWidth(parent) {
		var width = parent.find('ul').outerWidth();
		return false;		
	}

})(jQuery);
