(function($) {

    var FancyCombo = function(element, options) {
        //Defaults are below
        var settings = $.extend({}, $.fn.fancyCombo.defaults, options);
        //Useful variables.
        var vars = {};
        //Get this slider
        var select = $(element);
        select.data('fancyCombo:vars', vars);
        var selectedOption = select.find('option[value="' + select.val() + '"]');
        var selectOptions = $("option", select);
        var selectOption = function(option){
             // Render selected value
            $("dt", shadowSelect).html(settings.renderSelected(option));
            $("dd ul", shadowSelect).hide();
        }

        //Hide the original select box
        select.hide();
        var shadowId = "shadowSelect" + ++$.fn.fancyCombo.counter;
        select.after('<dl id="' + shadowId + '" class="dropdown"></dl>')
        var shadowSelect = $("#" + shadowId);
        shadowSelect.append('<dt>' + settings.renderSelected(selectedOption) + '</dt>')
        shadowSelect.append('<dd><ul></ul></dd>')

        selectOptions.each(function() {
            $("dd ul", shadowSelect).append('<li data-value="' + $(this).val() + '">' + settings.renderOption($(this)) + '</li>');
        });

        $("dd ul li, dt", shadowSelect).hover(function(){ $(this).addClass("hover") }, function(){$(this).removeClass("hover") });

        select.change(function(){
            var option = select.find("option[value='" + $(this).val() + "']");
            selectOption(option);
        });

        //Show, hide select dropdown on click
        $("dt", shadowSelect).click(function() {
            $("ul", shadowSelect).toggle();
        });

        // When a shadow option is clicked select it in the real select
        $("dd ul li", shadowSelect).click(function() {
            var value = $(this).data("value");
            var option = select.find("option[value='" + value + "']");
            selectOption(option);
            //select the corrent value in the original select
            select.val(option.val());
            select.trigger('change');
        });

        return this;
    };

    $.fn.fancyCombo = function(options) {

        return this.each(function(key, value) {
            var element = $(this);
            // Return early if this element already has a plugin instance
            if (element.data('fancyCombo')) return element.data('fancyCombo');
            // Pass options to plugin constructor
            var fancyCombo = new FancyCombo(this, options);
            // Store plugin object in this element's data
            element.data('fancyCombo', fancyCombo);
        });

    };

    //Default settings
    $.fn.fancyCombo.defaults = {
        effect: 'random',
        renderOption: function(selectOption) {
            return  selectOption.text();
        },
        renderSelected: function(selectOption) {
            return  selectOption.text();
        }
    };
    $.fn.fancyCombo.counter = 0;

    $.fn._reverse = [].reverse;

    $(document).bind('click', function(e) {
        var $clicked = $(e.target);
        if (! $clicked.parents().hasClass("dropdown"))
            $(".dropdown dd ul").hide();
    });

})(jQuery);
