(function($)
{
	// This script was written by Steve Fenton
	// http://www.stevefenton.co.uk/Content/Jquery-Mega-Select-List/
	// Feel free to use this jQuery Plugin
	// Version: 3.0.1
	
	var nextModifierNumber = 0;

	$.fn.megaselectlist = function (settings) {
	
		var config = {
			classmodifier: "megaselectlist",
			headers: "rel",
			animate: false,
			animateevent: "mouseover",
			multiple: false,
			maximumitems: 0,
			warningmessage: "You can only select {0} items",
			itemseparator: ", "
		};
	
		if (settings) {
			$.extend(config, settings);
		}
		
		function IsSelected(compareList, compareValue) {
			var found = false;
			for (var i = 0; i < compareList.length; i++) {
				if ($(compareList[i]).val() == compareValue) {
					found = true;
				}
			}
			return found;
		}
		
		return this.each(function () {
			var classModifier = config.classmodifier;
			nextModifierNumber++;
			
			var originalId = $(this).attr("id");
			//alert(originalId);
			var originalName = $(this).attr("name");
			var label = $("label[for='" + originalId + "']");
			var labelText = $(label).text();
			var selectedValue = $(this).val();
			var selectedOptionValues = $(this).find("option:selected");

			if (labelText == "") {
				label = $(this).parents("label");
				labelText = $(label).clone().children().remove().end().text();
			}
			//alert(classModifier+' - '+nextModifierNumber);	
			var replacementHtml = '<div id="' + classModifier + nextModifierNumber +'" class="' + classModifier + '">' +
				'<p tabindex="0" class="closed">' +labelText +  ': <span class=mybox></span></p>' +
				'<div class="' + classModifier + 'options">';
		//	var replacementHtml = '<label>'+labelText+':</label>'+'<div id="' + classModifier + nextModifierNumber +'" class="' + classModifier + '">' +
		//		'<p style="display:block" "tabindex="0">&nbsp;' + '<span></span></p>' +
		//		'<div class="' + classModifier + 'options">';
			
			var currentHeader = "";
			var isHeaderOpen = false;
			var header = "";
			var options;
			var i;
			var offset;
			var optgroups = $(this).children("optgroup");
			
			// If optgroups exist, use them rather than attributes
				var ii=0;
				if (optgroups.length > 0) {
				for (var og = 0; og < optgroups.length; og++) {
					//header = $(optgroups[og]).attr("label");
					options = $(optgroups[og]).children("option");
					if (ii==0) {
						offset = options.length;
						replacementHtml += '<p class="selection">Select one or more items from this list:</p>';ii++;
					}
					replacementHtml += '<div class="' + classModifier + 'column">' + header + '<ul>';
					var tabindex = "0";
					if (config.animate) {
						tabindex = "-1";
					}
				
					for (i = 0; i < options.length; i++) {
						var x = IsSelected(selectedOptionValues, $(options[i]).val());
						var cnn = "";
						if (x) {
							cnn = ' class="currentitem"';
						}
						replacementHtml += '<li class="blank_content" rel="' + $(options[i]).val() + '" tabindex="' + tabindex + '"' + cnn + '>' + $(options[i]).text() + '</li>';
					}
					
					replacementHtml += '</ul></div>';
				}
				
			} else {
			
				options = $(this).children("option");
				for (i = 0; i < options.length; i++) {
					//header = $(options[i]).attr(config.headers);
					
					if (header != currentHeader) {
						currentHeader = header;
						if (isHeaderOpen) {
							replacementHtml += '</ul></div>';
						}
						isHeaderOpen = true;
						replacementHtml += '<div class="' + classModifier + 'column"><h2>' + header + '</h2><ul>';
					}

					var x = IsSelected(selectedOptionValues, $(options[i]).val());
					var cnn = "";
					if (x) {
						cnn = ' class="currentitem"';
					}
					replacementHtml += '<li rel="' + $(options[i]).val() + '"' + cnn + '>' + $(options[i]).text() + '</li>';
				}
				if (isHeaderOpen) {
					replacementHtml += '</ul></div>';
				}
			}
			
			// The form element to contain the selected value
			replacementHtml += '<div style="clear: both">&nbsp;</div></div>' +
				'<div style="display: none;"><select name="' + originalName + '" id="' + originalId + '" multiple="true" size="5"><option value="' + selectedValue + '" selected="true">Selected</option></div>';

			$(this).remove();
			$(label).hide().after(replacementHtml);
			$(label).remove();
			
			//$("#" + classModifier + nextModifierNumber + " li[rel='" + selectedValue + "']").addClass("currentitem");
			
			// Set span to show current selection
			var spanText = "";
			$("#" + classModifier + nextModifierNumber + " li.currentitem").each( function () {
				$("#" + originalId).append('<option value="' + $(this).attr("rel") + '" selected="true">' + $(this).text() + '</option>');
				spanText += $(this).text() + config.itemseparator;
			});
			spanText = spanText.substring(0, spanText.length - config.itemseparator.length);
			
			//var spanText = $("#" + classModifier + nextModifierNumber + " li.currentitem").text();

			$("#" + classModifier + nextModifierNumber + " span").text(spanText);
//XXX
if (spanText=='') {$("#" + classModifier + nextModifierNumber + " span").css({'height':'21px'});} else {$("#" + classModifier + nextModifierNumber + " span").css({'height':'auto'});}
		
			// For keyboard use, trigger the click event when "enter" or "space" is pressed
			$("#" + classModifier + nextModifierNumber + " li").keypress( function (e) {
				if (e.keyCode == "13" || e.keyCode == "0") {
					e.preventDefault();
					$(this).trigger("click");
				} else if (e.keyCode == "33") {
					e.preventDefault();
					$("#" + classModifier + nextModifierNumber + " li:first")[0].focus();
				} else if (e.keyCode == "34") {
					e.preventDefault();
					$("#" + classModifier + nextModifierNumber + " li:last")[0].focus();
				} else if (e.keyCode == "27" && config.animate) {
					e.preventDefault();
					$("#" + classModifier + nextModifierNumber + " .megaselectlistoptions").animate({ height: "0px" });
					$("#" + classModifier + nextModifierNumber + " p:first")[0].focus();
					$("#" + classModifier + nextModifierNumber + " li").attr("tabindex", "-1");
				} else {
					//alert(e.keyCode);
				}
			});
			
			// Event handler for selection click
			$("#" + classModifier + nextModifierNumber + " li").click(function () {
				var item = $(this);
				var thisValue = $(item).attr("rel");
				
				if (!config.multiple) {
					// If this isn't a multi select, remove any other current item
					$(item).parents("." + classModifier).find(".currentitem").removeClass("currentitem");
				}
				
				if ($(item).hasClass("currentitem") && config.multiple) {
					// This is a de-select on a multiple select
					$(item).removeClass("currentitem");
				} else {
					// Set selected class on item
					$(item).addClass("currentitem");
				}
				
				if (config.animate && !config.multiple) {
					// If it is a single select, collapse the list on selection
					$(item).parent().parent().parent().parent().find(".megaselectlistoptions").animate({ height: "0px" });
					$(item).parent().parent().parent().parent().find("p:first")[0].focus();
					$(item).parent().parent().parent().parent().find("li").attr("tabindex", "-1");
				}
				
				// Remove all previous selections as we will re-add the current selections
				$("#" + originalId).children("option").remove();
				spanText = "";
			
				// Check number of selections
				if (config.multiple && config.maximumitems > 0) {
					var selectedItems = $(item).parent().parent().parent().find(".currentitem");
					if (selectedItems.length > config.maximumitems) {
						$(this).removeClass("currentitem");
						alert(config.warningmessage.replace("{0}", config.maximumitems));
					}
				}
				
				// Add all current selections
				$(item).parent().parent().parent().find(".currentitem").each( function () {
					$("#" + originalId).append('<option value="' + $(this).attr("rel") + '" selected="true">' + $(this).text() + '</option>');
					spanText += $(this).text() + config.itemseparator;
				});
				spanText = spanText.substring(0, spanText.length - config.itemseparator.length);

				// Set span to show current selections
				$(item).parents("." + classModifier).find("span").text(spanText);
				if (spanText=='') {$(item).parents("." + classModifier).find("span").css({'height':'17px'});} else {$(item).parents("." + classModifier).find("span").css({'height':'auto'});}

				return false;
			});
			
			if (config.animate) {
				var optionHeight = $("#" + classModifier + nextModifierNumber + " .megaselectlistoptions").height();
				$("#" + classModifier + nextModifierNumber + " .megaselectlistoptions").attr("rel", optionHeight).css({ overflow: "hidden" }).animate({ height: "0px" });
			
				$("#" + classModifier + nextModifierNumber + " p:first").keypress( function (e) {
					if (e.keyCode == "13" || e.keyCode == "0") {
						e.preventDefault();
						$(this).trigger(config.animateevent);
					}
				});
			
				$("#" + classModifier + nextModifierNumber + " p:first").css({ cursor: "pointer" }).bind(config.animateevent, function () {
					var optionList = $(this).parent().find(".megaselectlistoptions");
					if ($(optionList).height() > 0) {
						$(this).attr("class", "closed");
						var animateHeight = 0;
						$(this).parent().find("li").attr("tabindex", "-1");
					} else {
						$(this).attr("class", "open");
						var animateHeight = $(optionList).attr("rel")*1 + offset*1;
						$(this).parent().find("li").attr("tabindex", "0");
					}
					$(optionList).animate({ height: animateHeight + "px" });
				});
			}
		});
	};
})(jQuery);
