(function( $ ){
    var methods = {
        init : function(options) {                        
            $(document).bind('click', function(e) {
                var $clicked = $(e.target);
                if (!$clicked.parents().hasClass("custom_select")) {
                    $(".custom_select dd ul").hide();
                }
            });
            return this.each(function() {
                var $select = $(this);
                var classnames = $select.attr("class");
                var classnames_array = classnames.split(" ");
                var index = classnames_array.indexOf("custom");
                if (index >= 0) {
                    delete classnames_array[index];
                }
                var disabled = false;
                if ($select.attr("disabled")) {
                    disabled = true;
                }
                var selected = $select.find("option[selected]");
                var options = $select.find("option");
                var $dl = $('<dl class="custom_select '+classnames_array.join(" ")+'"></dl>');
                $select.after($dl);
                if (disabled) {
                    $dl.addClass("disabled");
                }
                $dl.append('<dt><a href="#">' + selected.text() + 
                '<span class="value">' + selected.val() + 
                '</span></a></dt>');
                $dl.append('<dd><ul></ul></dd>');
                var isNumber = function(n) {
                    return !isNaN(parseFloat(n)) && isFinite(n);
                };
                options.each(function(){
                    if ($(this).val() >= 0 || (!isNumber($(this).val()) && $(this).val() != "")) {
                        $dl.find("dd ul").append('<li><a href="#">' + 
                        $(this).text() + '<span class="value">' + 
                        $(this).val() + '</span></a></li>');
                    }
                    if ($(this).val() == -1) {
                        $(this).remove();
                    }
                });

                $dl.find("dt a").click(function() {
                    if (!$(this).parent().parent().hasClass("disabled")) {
                        var $ul = $dl.find("dd ul");
                        $ul.toggle();
                        $(".custom_select dd ul").not($ul.get(0)).hide();
                    }
                    return false;
                });
                $dl.find("dd ul li a").click(function() {
                    var text = $(this).html();
                    $dl.find("dt a").html(text);
                    $dl.find("dd ul").hide();
                    $select.val($(this).find("span.value").html()).trigger("change");
                    return false;
                });
                $select.data("list",$dl.get(0));
            });
        },
        select : function(options) {
            var settings = {
                triggerChange: false
            };
            $.extend(settings, options);
            var $select = $(this);
            var dl = $select.data("list");
            $(dl).find("dd ul li a span.value").each(function() {
                var $span = $(this);
                if ($span.html() == settings.value) {
                    $span.click();
                    if (settings.triggerChange) {
                        $select.trigger("change");
                    }
                }
            });
            return this;
        },
        sync : function(options) {
            var settings = {
                skipElements: [],
                skipValues: [],
                triggerChange: false
            };
            $.extend(settings, options);
            return this.each(function() {
                var $select = $(this);
                var $option = $select.find("option[selected]");
                if ($.inArray(this, settings.skipElements) == -1) {
                    var value = $option.val();
                    if ($.inArray(value, settings.skipValues) == -1) {
                        methods.select.apply(this, [{ triggerChange: settings.triggerChange, value: value}]);
                        
                    }
                }
            });
        },
        getValue : function() {
            var $select = $(this);
            var dl = $select.data("list");
            return $(dl).find('dt a span.value').html();
        },
        destroy : function() {
            
        }
    };
    $.fn.customSelects = function(method) {    
        if (methods[method]) {
            return methods[method].apply(this,Array.prototype.slice.call(arguments,1));
        }
        else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        }
        else {
            $.error('Method ' +  method + ' does not exist on jQuery.customSelects');
        }
    };
})(jQuery);
$(function() {
    $("select.custom").customSelects();
});
