(function($) {
    $.fn.templatedSelect = function(options) {
        if (this.length == 0) {
            return;
        }
        
        //keep a reference back to the select which is being replaced
        var $originalSelect = this;
        
        //getting the dropdown id
        var dropdownId = $originalSelect[0].id;

        //define the default options
        var defaults = {
            backgroundColor: "#FFFFFF",
            borderColor: "#C0C0C0",
            borderSelectedColor: "#000000",
            width: "85px",
			maxHeight: "100px",
			
			isMultiSelect: false,
			multiSelectHeadOption: "Choose Options",
			
			optionIdPrefix: dropdownId + "_option_checkbox_",
			
            getOption: function(value, text, isChecked) {
                var checkedText = "";
        		if (isChecked) {
        			checkedText = ' checked="checked selected="selected"';
        		}
                
        		return "<input type='checkbox' id='"
                	+ dropdownId + "_option_checkbox_"+ value
                	+ "' name='" + dropdownId + "_option_checkbox' "
                	+ "class='hotelSearchFormCheckboxInput' value='1'" + checkedText + " />&nbsp;"
                	+ "<label for='" + dropdownId + "_option_checkbox_" + value + "' class='customSelectBoxCheckboxLabel'>"
                	+ text
                	+ "</label>";
            }
        };

        //merge passed in options with the defaults
        var opts = $.extend(defaults, options);

        //create a div to contain everything
        var $container = $(document.createElement('div'))
			.css({
			    width: opts.width,
			    backgroundColor: opts.backgroundColor
			})
			.hover(
				function() {
				    $selectBox.css("border-color", opts.borderSelectedColor);
				},
				function() {
				    if (!$menuItems.is(":visible"))
				        $selectBox.css("border-color", opts.borderColor);
				})
			.attr('id', "imageSelect_container_" + this.attr('id'));

        //create the box the user will see
        var $selectBox = $(document.createElement('div'))
			.click(function(e) {
				ToggleMenuItems(false);
			})
			.addClass('customSelectBoxInner')
		;

		

        //create a placeholder for the selected item. When the user selects an item, the html will be copied from the menu item
        var $selectedItem = $(document.createElement('div'))
			.addClass('customSelectBoxSelectedItem');

        //create a handle to let the user click to show the selection item list
        var $selectHandle = $(document.createElement('div'))
			.addClass('customSelectBoxHandle');

        var $menuItems = $(document.createElement('div'))
			.addClass('customSelectBoxMenuItems');

        
        //closing the dropdowns, if elsewhere is clicked
        $("body").click(function (evt) {
    		var target = evt.target;
    		
    		if (
    			(
    				(target.className != "hotelSearchFormCheckboxInput")
	    			&& (target.className != "customSelectBoxMenuItem")
	    			&& (target.className != "customSelectBoxCheckboxLabel")
	    			&& (target.className != "customSelectBoxInner")
    			)
    			&& (target.parentNode.nextSibling !== $menuItems[0])
				
    		) {
    			if ($menuItems.is(":visible")) {
					ToggleMenuItems(false);
				}
    		}
    	});
        
        $originalSelect.children("option").each(function(i, selected) {
            var $menuItem = $(document.createElement('div'))
				.addClass("customSelectBoxMenuItem")
				.html(opts.getOption($(this).val(), $(this).text(), selected.selected))
				.val($(this).val())
				.click(function(e) {
				    ToggleMenuItems(true);
				    
				    if (!opts.isMultiSelect) {
					    $originalSelect.val($(this).val());
					    $selectedItem.html($(this).html());
				    } else {
				    	var selectOptionCount = $originalSelect.children("option").length;
				    	
				    	$stringSelectedItems = "";
				    	
				    	for (var i = 0; i < selectOptionCount; i++) {
				    		if ($("#" + opts.optionIdPrefix + $originalSelect.children("option")[i].value + ":checked").val() != null) {
				    			$originalSelect.children("option")[i].selected = true;
				    			
				    			if ($stringSelectedItems != "") {
				    				$stringSelectedItems += "; ";
				    			}
				    			$stringSelectedItems += $originalSelect.children("option")[i].innerHTML;
				    			
				    		} else {
				    			$originalSelect.children("option")[i].selected = false;
				    		}
				    	}
				    	
				    	if ($stringSelectedItems != "") {
				    		$selectedItem.html($stringSelectedItems);
				    	} else {
				    		$selectedItem.html(opts.multiSelectHeadOption);
				    	}
				    }
				    
				    //casting onchange event on the original select input
				    $originalSelect.change(); //there is a bug that makes this code run twice
				})
				.appendTo($menuItems);
        });

        //preset the selectedItem
        if (opts.isMultiSelect) {
        	$selectedItem.html(opts.multiSelectHeadOption);
        	
        } else {
	        $selectedItem.html(
				$menuItems.children("div:eq(" + $originalSelect[0].selectedIndex + ")").html()
			);
        }

        //put everything together
        $selectBox.appendTo($container);
        $selectHandle.appendTo($selectBox);
        $selectedItem.appendTo($selectBox);
        $menuItems.appendTo($container);
        
        //hide the original select and put ours in
        $originalSelect.hide();
        $container.insertBefore($originalSelect);

        //generating the initial text
        if (opts.isMultiSelect) {
        	var selectOptionCount = $originalSelect.children("option").length;
        	
        	$stringSelectedItems = "";
	    	
	    	for (var i = 0; i < selectOptionCount; i++) {
	    		if ($("#" + opts.optionIdPrefix + $originalSelect.children("option")[i].value + ":checked").val() != null) {
	    			if ($stringSelectedItems != "") {
	    				$stringSelectedItems += "; ";
	    			}
	    			$stringSelectedItems += $originalSelect.children("option")[i].innerHTML;
	    		}
	    	}
	    	
	    	if ($stringSelectedItems != "") {
	    		$selectedItem.html($stringSelectedItems);
	    	} else {
	    		$selectedItem.html(opts.multiSelectHeadOption);
	    	}
        }
        
        //set the width and height of the UI components so everything lines up nicely
        if ($menuItems.height() > parseInt($menuItems.css("maxHeight"))) {
            $menuItems.height($menuItems.css("maxHeight"));
		}
		$selectHandle.height($selectBox.height() - 2);
        $menuItems.width($selectBox.width());
        $menuItems.hide();

        //hack: When inside of a hidden element, widths and heights don't calculate propertly. 
        //apply the widths and heights once on focus until a better solution is found.
        if ($selectBox.width() == 0) {
            $container.one("mouseover", function() {
                $menuItems.width($selectBox.width());
            });
        }

        function ToggleMenuItems(childClicked) {
            if ($menuItems.is(":visible") && (!(opts.isMultiSelect && childClicked))) {
                $menuItems.hide();
                $selectBox.css("border", "solid 1px " + opts.borderColor);
            } else {
                $menuItems.show();
                $selectBox.css("border", "solid 1px " + opts.borderSelectedColor);
            }
        }

    };

})(jQuery);
