/* 
----------------------------------
jQuery select box expander:
----------------------------------
Expand a select box into a clickable set of radio buttons, to allow all options to be visible at once.
Author:Ben Hull
This Version: 0.1, Feb 25, 2010

*/

(function($) {
		
    $.fn.expandSelect = function(options) {
        debug(this);
        // build main options before element iteration
        $.fn.expandSelect.options = $.extend({}, $.fn.expandSelect.defaults, options);
        // iterate and reformat each matched element

		  //Store the master
		$.fn.expandSelect.master = this;
		
        return this.each(function(j) {
            var $this = $(this);
            // build element specific options
            var o = $.meta ? $.extend({}, $.fn.expandSelect.options, $this.data()) : $.fn.expandSelect.options;
					
				//Dig into the selector if required:
				if (this.nodeName != 'SELECT') $this = $this.find('select');
				if ($this.length) {
					
					$this.hide();
					
					$.fn.expandSelect.selects = $this;
					
					var constructedGroup = $.fn.expandSelect.expand($this, o, j);

					constructedGroup.insertBefore($this);
					
					$.fn.expandSelect.groups.push(constructedGroup);
					
					$this.bind(
						'refresh', 
						function(e){$.fn.expandSelect.refresh($(e.target))}
					);
					
				}

        });
    };
	 
	 $.fn.expandSelect.master = null;
	 $.fn.expandSelect.groups = [];
	 $.fn.expandSelect.selects = [];

    function debug($obj) {
        if (window.console && window.console.log)
        window.console.log('Expanding: ' + $obj.size());
    };

	 $.fn.expandSelect.refresh = function($select) {
		if ($select == null) {
			$.fn.expandSelect.master.find('select')
		}
	
		
		var $group = $select.siblings('.' + $.fn.expandSelect.options.groupClasses),
			 $options = $select.children('option')
			
			 $group.children()
				.each(function(){
						
					var selectItem = $(this),
						 selectValue = selectItem.find('input');
					 
					$options.each(function(){
						selectValue.attr({'disabled': 'disabled'}).removeAttr('checked');
						selectItem.addClass('disabled');
			
							if ($(this).attr('value') == selectValue.attr('value')) {
								//This is valid item:
							
								if (selectItem.is('.selected')) {
									$(this).attr('selected', 'selected');
									selectValue.attr('checked', 'checked');
								}
								selectValue.removeAttr('disabled');
								selectItem.removeClass('disabled');
		
								return false;
							} 
					});
				});
				
				
				//Trigger the change event on the select as we have changed the value:
				//$select.change();
				
				//Refresh the other selects in the group, in case they have changed as a result of this change:
				//$.fn.expandSelect.selects.change();
	 };
	
    $.fn.expandSelect.expand = function($select, o, index) {
	
		var groupClasses = o.groupClasses;
		
		var canvas = $('<ol class="' + groupClasses + '"></ol>'),
			 inputType = $select.attr('multiple') ? 'checkbox' : 'radio',
			 options = $select.children('option')
			
			 if (o.readOnly) canvas.addClass('readOnly');
			
			 options.each(function(i){
				
				$option = $(this);
				
				//Don't include the first option if it is disabled (this is used as a 'please select' placeholder)
				if (i != 0 || !$(this).attr('disabled')) {
			
					var $option = $(this);
				
					var classes = '';
						 classes += $option.attr('selected') ? ' selected' : '';
						 classes += $option.attr('disabled') ? ' disabled' : '';
						 classes += (i == 0) ? ' first' : '';
						 classes += (i == options.length - 1) ? ' last' : '';

					var checked = $option.attr('selected') ? 'checked="checked"' : '',
						 disabled = $option.attr('disabled') ? 'disabled="disabled"' : '';
			
					var input = $('<input type="' + inputType + '" id="' + $select.attr('name') + '_' + i + '-' + index + '" name="' + $select.attr('name') + '" value="' + $option.attr('value') + '" ' + checked + ' ' + disabled + '/>')
					
					if (!o.readOnly) {
						input
							.hover(
								function(){$(this).addClass('hover')},
								function(){$(this).removeClass('hover')}
							)
							.bind('click', {select: $select}, function(event){
								var $this = $(this),
								container = $this.closest('.selectOption'),
								group = container.closest('.dropdownoptions');
								
								if (!(container.is('.disabled') && container.is('.selected') && group.is('.unselectable'))) {
									
									container.siblings().removeClass('selected').end().addClass('selected');
									
									var preselected = event.data.select
										.children()
											.removeAttr('selected')
										.filter(function(){
											return $(this).attr('value') == $this.attr('value');
										})
										.attr({'selected': 'selected'});
										
										var preSelectedBoxes;
										if (preselected.length) {
											preSelectedBoxes = container.find('select');
										}
									
									event.data.select.change();
									//$.fn.expandSelect.refresh(event.data.opt.parent());
									
									group.trigger('select');
									
									$.fn.expandSelect.refresh($.fn.expandSelect.master.find('select'));
									
									preSelectedBoxes.change();

								}
							});
						}
				
					var listItem = $('<li class="' + o.itemClasses + classes + '"><label for="' + $select.attr('name') + '_' + i + '-' + index + '">' + $option.text() + '</label></li>');
						
					listItem.append(input);
					canvas.append(listItem);
					
					
					if (checked) $option.closest('.dropdownoptions').trigger('select'); //Signal that this group is pre-selected:

					
				}
			});

			return canvas;
    };

    $.fn.expandSelect.defaults = {
        groupClasses: 'selectGroup',
        itemClasses: 'selectOption',
		  readOnly:false,
		  sequenced:false
    };

    $.fn.expandSelect.options = {};

	 $.fn.expandSelect.flags = {
        initialised: false
    };


})(jQuery);
