/*
 * jHue selector plugin
 * it tranforms a select multiple into a searchable/selectable alphabetical list
 */
;(function ($, window, document, undefined) {

    var pluginName = "jHueSelector",
        defaults = {
            selectAllLabel: "Select all",
            searchPlaceholder: "Search",
            noChoicesFound: "No choices found for this element",
            width: 300,
            height: 200
        };

    function Plugin(element, options) {
        this.element = element;
        this.options = $.extend({}, defaults, options) ;
        this._defaults = defaults;
        this._name = pluginName;
        this.init();
    }

    Plugin.prototype.setOptions = function(options) {
        this.options = $.extend({}, defaults, options) ;
    };

    Plugin.prototype.init = function () {
        var _this = this;
        var addressBook = [];
        var selectorContainer = $("<div>");
        if (this.options.width != 300) {
            selectorContainer.width(this.options.width);
        }
        $(_this.element).hide();
        $(_this.element).find("option").each(function (cnt, opt) {
            var initial = $(opt).text().substr(0, 1).toLowerCase();
            if (addressBook[initial] == null) {
                addressBook[initial] = [];
            }
            addressBook[initial].push($(opt));
        });
        var sortedKeys = [];
        for (var key in addressBook) {
            sortedKeys.push(key);
        }
        sortedKeys.sort();

        if (sortedKeys.length == 0){
            $(_this.element).after($("<div>").addClass("alert").css("margin-top", "-2px").css("float", "left").html(this.options.noChoicesFound));
        }
        else {
            selectorContainer.addClass("jHueSelector");
            var body = $("<div>").addClass("jHueSelectorBody");
            body.appendTo(selectorContainer);

            for (var i = 0; i < sortedKeys.length; i++) {
                var key = sortedKeys[i];
                var ul = $("<ul>");
                var dividerLi = $("<li>").addClass("selectorDivider");
                dividerLi.html("<strong>" + key.toUpperCase() + "</strong>");
                dividerLi.appendTo(ul);
                $.each(addressBook[key], function (cnt, opt) {
                    var li = $("<li>");
                    var lbl = $("<label>").text(opt.text());
                    var chk = $("<input>").attr("type", "checkbox").addClass("selector").change(function () {
                        if ($(this).is(":checked")) {
                            $(this).data("opt").attr("selected", "selected");
                        }
                        else {
                            $(this).data("opt").removeAttr("selected");
                        }
                    }).data("opt", opt).prependTo(lbl);
                    if (opt.is(":selected")) {
                        chk.attr("checked", "checked");
                    }
                    lbl.appendTo(li);
                    li.appendTo(ul);
                });
                ul.appendTo(body);
            }

            var header = $("<div>").addClass("jHueSelectorHeader");
            header.prependTo(selectorContainer);

            var selectAll = $("<label>").text(this.options.selectAllLabel);
            $("<input>").attr("type", "checkbox").change(function () {
                var isChecked = $(this).is(":checked");
                selectorContainer.find("input.selector:visible").each(function () {
                    if (isChecked) {
                        $(this).attr("checked", "checked");
                        $(this).data("opt").attr("selected", "selected");
                    }
                    else {
                        $(this).removeAttr("checked");
                        $(this).data("opt").removeAttr("selected");
                    }
                });
                if (searchBox.val() != "") {
                    $(this).removeAttr("checked");
                }
            }).prependTo(selectAll);
            selectAll.appendTo(header);

            var searchBox = $("<input>").attr("type", "text").attr("placeholder", this.options.searchPlaceholder).keyup(function () {
                body.find("ul").attr("show", true).show();
                var q = $.trim($(this).val());
                if (q != "") {
                    body.find("li.selectorDivider").hide();
                    body.find("label").each(function () {
                        if ($(this).text().toLowerCase().indexOf(q.toLowerCase()) > -1) {
                            $(this).parent().show();
                        }
                        else {
                            $(this).parent().hide();
                        }
                    });
                    body.find("ul").attr("show", false);
                    body.find("ul > *:visible").parent().attr("show", true).find("li.selectorDivider").show();
                }
                else {
                    body.find("li.selectorDivider").show();
                    body.find("label").parent().show();
                }
                body.find("ul[show=false]").hide();
                body.find("ul[show=true]").show();
            });
            if (this.options.width != 300) {
                searchBox.css("margin-left", this.options.width - 120 + "px");
            }
            searchBox.prependTo(header);

            body.height(this.options.height - header.outerHeight());

            $(_this.element).after(selectorContainer);
        }
    };

    $.fn[pluginName] = function (options) {
        return this.each(function () {
            if (!$.data(this, 'plugin_' + pluginName)) {
                $.data(this, 'plugin_' + pluginName, new Plugin( this, options));
            }
            else {
                $.data(this, 'plugin_' + pluginName).setOptions(options);
            }
        });
    }

})(jQuery, window, document);
