/*
//
// This is a modification of the jQuery plugin "multiSelect" version 1.0.2 beta
// Visit http://abeautifulsite.net/notebook.php?article=62 for more information about "multiselect"
//
// Original Licensing & Terms of Use
//
// This plugin is dual-licensed under the GNU General Public License and the MIT License and
// is copyright 2008 A Beautiful Site, LLC.
*/

/* Notering:
 * För att denna plugin ska funglera krävs följande struktur:
 *
 * <input id="ID" type="text" readonly="readonly" class="multiSelect" value="" style="cursor: default;"  autocomplete="off" />
 * <div class="multiSelectOptions" style="position: absolute; z-index: 99999; display: none;">
 *  <label class="selectAll"><input type="checkbox" name="NAMN[]" value="-1" class="selectAll"/>Välj alla</label>
 *  <label><input type="checkbox" name="NAMN[]" value="VALUE" class="selectAll" checked="checked" />Alt 1</label>...
 * </div>
 * CSS  i standard*.css
 */
(function($) {
    $.widget("ui.multiselectz", {
        _init: function() {

            var self = this;

            self.boxcontainer = self.element.next('.multiSelectOptions');

            self.boxcontainer.mouseover(function() {
                self.boxcontainer.addClass("hover");
            }).mouseout(function() {
                self.boxcontainer.removeClass("hover");
            });

            //Lyssnare på textrutan
            self.element.mouseover(function() {
                self.element.addClass('hover');
            }).mouseout(function() {
                self.element.removeClass('hover');
            }).click(function() {
                // Show/hide on click
                if (self.element.hasClass('active') ) {
                    self._multiSelectOptionsHide();
                } else {
                    self._multiSelectOptionsShow();
                }
                return false;
            }).focus( function() {
                // So it can be styled with CSS
                self.element.addClass('focus');
            }).blur( function() {
                // So it can be styled with CSS
                self.element.removeClass('focus');

                if (!self.boxcontainer.hasClass("hover")) {
                    self._multiSelectOptionsHide();
                }
            });

            //Tangentlyssnare
            self.element.keydown( function(event) {
                self._handleKeydown(event);
            });

            // Handle hovers
            // PRESTANDADÖDARE!!!!
            //self.boxcontainer.find('label').mouseover(function() {
            //    self.boxcontainer.find('label.hover').removeClass('hover');
            //    $(this).addClass('hover');
            //}).mouseout( function() {
            //    self.boxcontainer.find('label.hover').removeClass('hover');
            //});


            // Initial display
            self._multiSelectUpdateSelected();
            self.boxcontainer.find('INPUT:checked').parent().addClass('checked');

            //Lyssnare för checkboxarna
            self._addEventListenerToCheckboxes();
        },

        // Hide the dropdown
        _multiSelectOptionsHide: function() {
            this.element.removeClass("active");
            this.boxcontainer.hide();
        },

        // Show the dropdown
        _multiSelectOptionsShow: function() {

            var offset = this.element.position();
            var y = offset.top + this.element.outerHeight();
            
            this.boxcontainer.css({
                'top': y + 'px',
                'left': offset.left + 'px'
            }).show().find('label.hover').removeClass('hover');

            this.element.addClass('active');
        },

        _addEventListenerToCheckboxes: function() {
            var self = this;
            var bc = self.boxcontainer;

            // Väljer man selectAll ska alla andra fält avmarkeras
            bc.find(':checkbox.selectAll').click(function() {
                var elem = $(this);

                if (elem.attr('checked') == true) {
                    bc.find(':checked:not(.selectAll)').attr('checked', false).parent().removeClass('checked');
                }

                self._multiSelectUpdateSelected();
                self.element.focus();
            });

            // Handle checkboxes
            bc.find(':checkbox:not(.selectAll)').click(function() {
                var elem = $(this);

                if (elem.attr('checked')) {
                    bc.find(':checkbox.selectAll').attr('checked', false).parent().removeClass('checked');
                }

                self._multiSelectUpdateSelected();
                self.element.focus();
            });

        },

        _handleKeydown: function(e) {
            if (this.boxcontainer.is(':visible')) {
                // Dropdown is visible

                // Tab
                if (e.keyCode == 9) {
                    this.element.addClass('focus').trigger('click'); // esc, left, right - hide
                    this.element.focus().next(':input').focus();
                    return true;
                }

                // ESC, Left, Right
                if (e.keyCode == 27 || e.keyCode == 37 || e.keyCode == 39) {
                    // Hide dropdown
                    this.element.addClass('focus').trigger('click');
                }
                
                // Down
                if (e.keyCode == 40) {
                    if (this.boxcontainer.find('label.hover').length == 0) {
                        // Default to first item
                        this.boxcontainer.find('label:first').addClass('hover');
                    } else {
                        // Move down, cycle to top if on bottom
                        this.boxcontainer.find('label.hover').removeClass('hover').next('label').addClass('hover');

                        if (!this.boxcontainer.find('label').hasClass('hover')) {
                            this.boxcontainer.find('label:first').addClass('hover');
                        }
                    }

                    // Adjust the viewport if necessary
                    this._multiSelectAdjustViewport();

                    return false;
                }
                
                // Up
                if (e.keyCode == 38) {
                    if (this.boxcontainer.find('label.hover').length == 0) {
                        // Default to first item
                        this.boxcontainer.find('label:first').addClass('hover');
                    } else {
                        // Move up, cycle to bottom if on top
                        this.boxcontainer.find('label.hover').removeClass('hover').prev('label').addClass('hover');

                        if (!this.boxcontainer.find('label').hasClass('hover')) {
                            this.boxcontainer.find('label:last').addClass('hover');
                        }
                    }

                    // Adjust the viewport if necessary
                    this._multiSelectAdjustViewport();

                    return false;
                }

                // Enter, Space
                if (e.keyCode == 13 || e.keyCode == 32) {

                    var checkbox = this.boxcontainer.find('label.hover :checkbox.selectAll');

                    // Select All
                    if (checkbox.length > 0) {

                        if (checkbox.attr('checked')) {
                            // Uncheck all
                            checkbox.attr('checked', false).parent().removeClass('checked');
                        } else {
                            // Check select all
                            checkbox.attr('checked', true).parent().addClass('checked');

                            // Om något gått fel, avmarkera alla andra checkboxar
                            this.boxcontainer.find(':checked:not(.selectAll)').attr('checked', false).parent().removeClass('checked');
                        }

                        this._multiSelectUpdateSelected();
                        return false;
                    }

                    checkbox = this.boxcontainer.find('label.hover :checkbox')

                    // Other checkboxes
                    if (checkbox.attr('checked')) {
                        // Uncheck
                        checkbox.attr('checked', false);
                        this._multiSelectUpdateSelected();

                        //this.boxcontainer.find('label.checked').removeClass('checked').find(':checked').parent().addClass('checked');
                    } else {
                        // Check
                        checkbox.attr('checked', true);
                        this._multiSelectUpdateSelected();

                        //this.boxcontainer.find('label.checked').removeClass('checked').find(':checked').parent().addClass('checked');
                    }

                    this.boxcontainer.find(':checkbox.selectAll').attr('checked', false).parent().removeClass('checked');
                }

                //Om användaren tryckt på en bokstavstangent ska man gå till det första alternetivet
                //som börjar på den aktuella bokstaven.
                var keyChar = String.fromCharCode(e.keyCode).toLowerCase();
                var regexp = "[a-z]" //Matcha a-z. å,ä,ö fungerar ej med keydowneventent. För detta får man lösa detta med keypress.
                var tmpSelf = this;
               
                if (e.keyCode > 40 && ((keyChar).match(regexp) != null)) {

                    this.boxcontainer.find("label:not(.selectAll)").each (function() {

                        //Vi behöver första tecknet som liten bokstav.
                        var c = this.text().match(/^[-\s]*(.)/)[1];

                        if (c != "" && c != undefined) {

                            c = c.toLowerCase();

                            if (keyChar == c) {

                                //Ta bort alla hover
                                tmpSelf.boxcontainer.find("label.hover").removeClass("hover");

                                //Sätter klassen hover för att simulera att användaren för musen över elementen.
                                //Anropar sedan _multiSelectAdjustViewport() för att anpassa vyn så den aktuella elementet syns.
                                this.addClass("hover");
                                tmpSelf._multiSelectAdjustViewport();

                                return false;
                            }
                        }
                    });
                }

                return false;
                
            } else {
                // Dropdown is not visible
                if (e.keyCode == 38 || e.keyCode == 40 || e.keyCode == 13 || e.keyCode == 32 ) { // down, enter, space - show
                    // Show dropdown
                    this.element.removeClass('focus').trigger('click');
                    this.boxcontainer.find('label:first').addClass('hover');
                    return false;
                }

                //  Tab key
                if (e.keyCode == 9 ) {
                    // Shift focus to next INPUT element on page
                    this.element.focus().next(':input').focus();
                    return true;
                }
            }

            // Prevent enter key from submitting form
            if (e.keyCode == 13 ) return false;
        },

        //Update the textbox with the total number of selected items
        _multiSelectUpdateSelected: function() {

            //Kolla om alternativet "välj alla" är i kryssat
            if (this.boxcontainer.find(':checked.selectAll').length > 0) {
                this.element.val(this.options.selectAllText);
            } else {
                //Antal valda element:
                var numSelectedElements = this.boxcontainer.find(':checked:not(.selectAll)').length;

                if (numSelectedElements == 0) {
                    this.element.val(this.options.noneSelected);
                } else {
                    var str = '';

                    if (this.options.oneOrMoreSelectedCallback) {
                        str = this.options.oneOrMoreSelectedCallback(this.boxcontainer, this.options.selectAllText);
                    } else {
                        str = this.options.oneOrMoreSelected.replace('%', numSelectedElements);
                    }

                    this.element.val(str);
                }
            }

        },

        // Ensures that the selected item is always in the visible portion of the dropdown (for keyboard controls)
        _multiSelectAdjustViewport: function() {
            // Calculate positions of elements
            var i = 0;
            var selectionTop = 0, selectionHeight = 0;
            this.boxcontainer.find('LABEL').each(function() {
                var self = $(this);

                if (self.hasClass('hover')) {
                    selectionTop = i; selectionHeight = self.outerHeight(); return;
                }
                i += self.outerHeight();
            });

            var divScroll = this.boxcontainer.scrollTop();
            var divHeight = this.boxcontainer.height();

            // Adjust the dropdown scroll position
            this.boxcontainer.scrollTop(selectionTop - ((divHeight / 2) - (selectionHeight / 2)));
        },

        /*************************************************
                Publika funktionsdeklarationer
        **************************************************/
        destroy: function() {
            this.boxcontainer.children().remove();
            $.widget.prototype.destroy.apply(this, arguments);
        },


        loadUrl: function (region_id) {

            var bc = this.boxcontainer;

            this.element.attr("disabled", true);
            bc.children().remove();

            var tmpSelf = this;
            var tmpElement = this.element;
            bc.load("/sok/kommunlista",{
                "id": region_id,
                "multiselect": 1
            },
            function() {
                tmpSelf._addEventListenerToCheckboxes();
                tmpSelf._multiSelectUpdateSelected();
                tmpElement.attr("disabled", false);
                if ($.fn.bgiframe) {
                    bc.bgiframe();
                }
            }
            );

        },

        //Simulerar ett klick på selectAll och markerar denna checkbox som vald.
        checkSelectAll: function() {
            this.boxcontainer.find(":checkbox.selectAll").attr("checked", true).trigger("click").attr("checked", true);
        }

    });

    $.extend($.ui.multiselectz, {
        defaults: {
            selectAllText: "Select All",
            oneOrMoreSelected: '% selected',
            noneSelected: 'Select options',
            selectAll: true,
            selectAllValue: '',
            oneOrMoreSelectedCallback: undefined
        }
    });
})(jQuery);
