﻿/*
// jQuery multiSelect
//
// Version 1.0.2 beta
//
// Cory S.N. LaViska
// A Beautiful Site (http://abeautifulsite.net/)
// 10 May 2009
//
// Visit http://abeautifulsite.net/notebook.php?article=62 for more information
//
// Usage: $('#control_id').multiSelect( options, callback )
//
// Options:  selectAll          - whether or not to display the Select All option; true/false, default = true
//           selectAllText      - text to display for selecting/unselecting all options simultaneously
//           noneSelected       - text to display when there are no selected items in the list
//           oneOrMoreSelected  - text to display when there are one or more selected items in the list
//                                (note: you can use % as a placeholder for the number of items selected).
//                                Use * to show a comma separated list of all selected; default = '% selected'
//
// Dependencies:  jQuery 1.2.6 or higher (http://jquery.com/)
//
// Change Log:
//
//		1.0.1	- Updated to work with jQuery 1.2.6+ (no longer requires the dimensions plugin)
//				- Changed $(this).offset() to $(this).position(), per James' and Jono's suggestions
//
//		1.0.2	- Fixed issue where dropdown doesn't scroll up/down with keyboard shortcuts
//				- Changed '$' in setTimeout to use 'jQuery' to support jQuery.noConflict
//				- Renamed from jqueryMultiSelect.* to jquery.multiSelect.* per the standard recommended at
//				  http://docs.jquery.com/Plugins/Authoring (does not affect API methods)
//
// 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. 
//	
*/
//  2009-09-16  EF      Parametrize css classes
//  2009-10-08  EF      Optionally place multi select DIVs directly under body because of visualization issues (o.adjacentOptionsDiv).
//  2010-02-23  FF      Added background arrow to input. Fix BUG: Doble click to open multiselect
if (jQuery) (function($) {

    $.extend($.fn, {
        multiSelect: function(o, callback) {
            // Default options
            if (!o) var o = {};
            if (o.selectAll == undefined) o.selectAll = true;
            if (o.selectAllText == undefined) o.selectAllText = "Select All";
            if (o.noneSelected == undefined) o.noneSelected = 'Select options';
            if (o.oneOrMoreSelected == undefined) o.oneOrMoreSelected = '% selected';
            //  2009-09-16  EF
            if (o.multiSelectClass == undefined) o.multiSelectClass = 'multiSelect';
            if (o.multiSelectOptionsClass == undefined) o.multiSelectOptionsClass = 'multiSelectOptions';
            if (o.selectAllClass == undefined) o.selectAllClass = 'selectAll';
            if (o.adjacentOptionsDiv == undefined) o.adjacentOptionsDiv = false;

            var _options = o;
            var _multiSelectCurrent = null;
            var _innerClick = false;

            // Initialize each multiSelect
            $(this).each(function() {

                var select = $(this);

                var htmlInput = '<input type="text" autocomplete="off" ';
                if (!o.adjacentOptionsDiv) {
                    htmlInput += 'id = "' + this.id + '_multiSelectInput' + '" ';
                }
                htmlInput += ' readonly="readonly" class="' + o.multiSelectClass + '" value="" style="cursor: default; background-color:Transparent;background-image:url(\'App_Images/master-page/ic_multiselect_background.gif\');background-position: right center;" />';

                var html = '<div ';
                if (!o.adjacentOptionsDiv) {
                    html += 'id = "' + this.id + '_multiSelectInput' + '_multiSelectOptionsDiv' + '" ';
                }
                html += ' class="' + o.multiSelectOptionsClass + '" style="position: absolute; z-index: 99999; display: none; border: 1px solid grey; background-color: white;height:107px;overflow-y:scroll;">';
                if (o.selectAll) html += '<label class="' + o.selectAllClass + '"><input type="checkbox" class="selectAll" />' + o.selectAllText + '</label>';

                $(select).find('OPTION').each(function(index, domElement) {
                    if (o.selectAll && index == 0 && !o.adjacentOptionsDiv) {
                        html += '<br/>';
                    }
                    if ($(this).val() != '') {
                        var labelStyle = '';
                        var checkboxStyle = '';
                        if (Browser_IE6()) { labelStyle = ' style="height:15px;"'; checkboxStyle = ' style="width:18px;"'; }
                        html += '<label' + labelStyle + '><input type="checkbox"' + checkboxStyle + ' name="' + $(select).attr('name') + '" value="' + $(this).val() + '"';
                        if ($(this).attr('selected')) html += ' checked="checked"';
                        html += ' /><a href="javascript:;" style="color:#000 !important;" onclick="if(Browser_FF()){$(this).prev().checked = !($(this).prev().checked);}else{$(this).prev().trigger(\'click\');}">' + $(this).html() + '</a></label>';
                    }
                    if (!o.adjacentOptionsDiv) {
                        if (!Browser_IE6()) { html += '<br/>'; }
                    }
                });
                html += '</div>';


                $(select).after(html);
                //                if (o.adjacentOptionsDiv) {
                //                    $(select).after(html);
                //                }
                //                else {
                //                    $(document.body).append(html);
                //                }

                $(select).after(htmlInput);
                //  "Mark" when we are over checkboxes area
                //                $(select).parent().children('.' + _options.multiSelectOptionsClass).bind("mouseenter focus", function() {
                //                    alert('addclass');
                //                    $(this).addClass('hover');
                //                }).bind("mouseout leave", function() {
                //                    alert('removeclass');
                //                    $(this).removeClass('hover');
                //                });

                // Events
                $(select).next('.' + _options.multiSelectClass).mouseover(function() {
                    $(this).addClass('hover');
                }).mouseout(function() {
                    $(this).removeClass('hover');
                }).click(function() {

                    // Show/hide on click
                    if (_innerClick) {
                        _innerClick = false;
                        return;
                    }
                    if ($(this).hasClass('active')) {
                        $(this).multiSelectOptionsHide(_options.multiSelectOptionsClass);
                    } else {
                        $(this).multiSelectOptionsShow(_options);
                    }
                    return false;
                }).focus(function() {
                    // So it can be styled with CSS
                    $(this).addClass('focus');
                }).blur(function() {
                    // So it can be styled with CSS
                    $(this).removeClass('focus');
                    //                    alert($(this).next('.' + _options.multiSelectOptionsClass).hasClass('hover'));
                    //                    if (!$(this).next('.' + _options.multiSelectOptionsClass).hasClass('hover')) {
                    //                        //  Hide if not over chckboxes area
                    //                        $(this).multiSelectOptionsHide(_options);
                    //                    }
                });

                // Determine if Select All should be checked initially
                if (o.selectAll) {
                    var sa = true;
                    $(select).next('.' + o.multiSelectClass).multiSelectOptionsGetContainer(o).find('INPUT:checkbox').not('.selectAll').each(function() {
                        if (!$(this).attr('checked')) sa = false;
                    });
                    if (sa) $(select).next('.' + o.multiSelectClass).multiSelectOptionsGetContainer(o).find('INPUT.selectAll').attr('checked', true).parent().addClass('checked');
                }

                // Handle Select All
                $(select).next('.' + o.multiSelectClass).multiSelectOptionsGetContainer(o).find('INPUT.selectAll').live("click", function() {
                    if (o.adjacentOptionsDiv) {
                        _innerClick = true;
                    }
                    if ($(this).attr('checked') == true) $(this).parent().parent().find('INPUT:checkbox').attr('checked', true).parent().addClass('checked'); else $(this).parent().parent().find('INPUT:checkbox').attr('checked', false).parent().removeClass('checked');
                });

                // Handle checkboxes
                $(select).next('.' + o.multiSelectClass).multiSelectOptionsGetContainer(o).find('INPUT:checkbox').live("click", function() {
                    //if (o.adjacentOptionsDiv) {
                    //_innerClick = true;
                    //}
                    //alert('innerClick');
                    $(this).parent().parent().multiSelectUpdateSelected(o);
                    $(this).parent().parent().find('LABEL').removeClass('checked').find('INPUT:checked').parent().addClass('checked');
                    //$(this).parent().parent().prev('.' + o.multiSelectClass).focus();

                    if (!$(this).attr('checked')) $(this).parent().parent().find('INPUT:checkbox.selectAll').attr('checked', false).parent().removeClass('checked');
                    if (callback) callback($(this));
                });

                // Initial display
                $(select).next('.' + o.multiSelectClass).multiSelectOptionsGetContainer(o).each(function() {
                    $(this).multiSelectUpdateSelected(o);
                    $(this).find('INPUT:checked').parent().addClass('checked');
                });

                // Handle hovers
                $(select).next('.' + o.multiSelectClass).multiSelectOptionsGetContainer(o).find('LABEL').mouseover(function() {
                    $(this).parent().find('LABEL').removeClass('hover');
                    $(this).addClass('hover');
                }).mouseout(function() {
                    $(this).parent().find('LABEL').removeClass('hover');
                });

                // Keyboard
                $(select).next('.' + o.multiSelectClass).keydown(function(e) {
                    // Is dropdown visible?
                    if ($(this).multiSelectOptionsGetContainer(o).is(':visible')) {
                        // Dropdown is visible
                        // Tab
                        if (e.keyCode == 9) {
                            $(this).addClass('focus').trigger('click'); // esc, left, right - hide
                            $(this).focus().next(':input').focus();
                            return true;
                        }

                        // ESC, Left, Right
                        if (e.keyCode == 27 || e.keyCode == 37 || e.keyCode == 39) {
                            // Hide dropdown
                            $(this).addClass('focus').trigger('click');
                        }
                        // Down
                        if (e.keyCode == 40) {
                            if (!$(this).multiSelectOptionsGetContainer(o).find('LABEL').hasClass('hover')) {
                                // Default to first item
                                $(this).multiSelectOptionsGetContainer(o).find('LABEL:first').addClass('hover');
                            } else {
                                // Move down, cycle to top if on bottom
                                $(this).multiSelectOptionsGetContainer(o).find('LABEL.hover').removeClass('hover').next('LABEL').addClass('hover');
                                if (!$(this).multiSelectOptionsGetContainer(o).find('LABEL').hasClass('hover')) {
                                    $(this).multiSelectOptionsGetContainer(o).find('LABEL:first').addClass('hover');
                                }
                            }

                            // Adjust the viewport if necessary
                            $(this).multiSelectAdjustViewport($(this), o);

                            return false;
                        }
                        // Up
                        if (e.keyCode == 38) {
                            if (!$(this).multiSelectOptionsGetContainer(o).find('LABEL').hasClass('hover')) {
                                // Default to first item
                                $(this).multiSelectOptionsGetContainer(o).find('LABEL:first').addClass('hover');
                            } else {
                                // Move up, cycle to bottom if on top
                                $(this).multiSelectOptionsGetContainer(o).find('LABEL.hover').removeClass('hover').prev('LABEL').addClass('hover');
                                if (!$(this).multiSelectOptionsGetContainer(o).find('LABEL').hasClass('hover')) {
                                    $(this).multiSelectOptionsGetContainer(o).find('LABEL:last').addClass('hover');
                                }
                            }

                            // Adjust the viewport if necessary
                            $(this).multiSelectAdjustViewport($(this), o);

                            return false;
                        }
                        // Enter, Space
                        if (e.keyCode == 13 || e.keyCode == 32) {
                            // Select All
                            if ($(this).multiSelectOptionsGetContainer(o).find('LABEL.hover INPUT:checkbox').hasClass('selectAll')) {
                                if ($(this).multiSelectOptionsGetContainer(o).find('LABEL.hover INPUT:checkbox').attr('checked')) {
                                    // Uncheck all
                                    $(this).multiSelectOptionsGetContainer(o).find('INPUT:checkbox').attr('checked', false).parent().removeClass('checked');
                                } else {
                                    // Check all
                                    $(this).multiSelectOptionsGetContainer(o).find('INPUT:checkbox').attr('checked', true).parent().addClass('checked');
                                }
                                $(this).multiSelectOptionsGetContainer(o).multiSelectUpdateSelected(o);
                                if (callback) callback($(this));
                                return false;
                            }
                            // Other checkboxes
                            if ($(this).multiSelectOptionsGetContainer(o).find('LABEL.hover INPUT:checkbox').attr('checked')) {
                                // Uncheck
                                $(this).multiSelectOptionsGetContainer(o).find('LABEL.hover INPUT:checkbox').attr('checked', false);
                                $(this).multiSelectOptionsGetContainer(o).multiSelectUpdateSelected(o);
                                $(this).multiSelectOptionsGetContainer(o).find('LABEL').removeClass('checked').find('INPUT:checked').parent().addClass('checked');
                                // Select all status can't be checked at this point
                                $(this).multiSelectOptionsGetContainer(o).find('INPUT:checkbox.selectAll').attr('checked', false).parent().removeClass('checked');
                                if (callback) callback($(this));
                            } else {
                                // Check
                                $(this).multiSelectOptionsGetContainer(o).find('LABEL.hover INPUT:checkbox').attr('checked', true);
                                $(this).multiSelectOptionsGetContainer(o).multiSelectUpdateSelected(o);
                                $(this).multiSelectOptionsGetContainer(o).find('LABEL').removeClass('checked').find('INPUT:checked').parent().addClass('checked');
                                if (callback) callback($(this));
                            }
                        }
                        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).removeClass('focus').trigger('click');
                            $(this).multiSelectOptionsGetContainer(o).find('LABEL:first').addClass('hover');
                            return false;
                        }
                        //  Tab key
                        if (e.keyCode == 9) {
                            // Shift focus to next INPUT element on page
                            $(this).focus().next(':input').focus();
                            return true;
                        }
                    }
                    // Prevent enter key from submitting form
                    if (e.keyCode == 13) return false;
                });

                // Eliminate the original form element
                $(select).remove();
            });

        },

        //  Get DIV
        multiSelectOptionsGetContainer: function(o) {
            if (o.adjacentOptionsDiv) {
                return $(this).next('.' + o.multiSelectOptionsClass);
            }
            else {
                //alert('id: ' + $(this).attr('id') + ', len: ' + $(this).length);
                return $('#' + $(this).attr('id') + '_multiSelectOptionsDiv');
            }
        },

        // Hide the dropdown
        multiSelectOptionsHide: function(multiSelectOptionsClass) {
            //$(this).removeClass('active').next('.' + multiSelectOptionsClass).hide();
            $(this).removeClass('active');
            $(document.body).find('.' + multiSelectOptionsClass).hide().each(function(index, domElement) {
                if (domElement.parentNode.tagName == 'BODY') {
                    //  Element was moved to body temporary in order to prevent displaying issues (truncated div)
                    //  Restore it
                    //alert('appendTo: ' + domElement.id.replace('_multiSelectOptionsDiv', ''));
                    $(domElement).remove().insertAfter('#' + domElement.id.replace('_multiSelectOptionsDiv', ''));
                }
            });
        },

        // Show the dropdown
        multiSelectOptionsShow: function(o) {
            var optionsContainer = $(this).multiSelectOptionsGetContainer(o);

            // Hide any open option boxes
            $('.' + o.multiSelectClass).multiSelectOptionsHide(o.multiSelectOptionsClass);
            $(this).multiSelectOptionsGetContainer(o).find('LABEL').removeClass('hover');
            $(this).addClass('active').multiSelectOptionsGetContainer(o).show();

            if (!o.adjacentOptionsDiv) {
                //  Element is moved to body temporary in order to prevent displaying issues (truncated div)
                //alert('appendToBody');
                if (!Browser_IE6()) { optionsContainer.remove().appendTo(document.body); }

            }

            // Position it
            if (o.adjacentOptionsDiv) {
                var offset = $(this).position();
                $(this).multiSelectOptionsGetContainer(o).css({ top: offset.top + $(this).outerHeight() + 'px' });
                $(this).multiSelectOptionsGetContainer(o).css({ left: offset.left + 'px' });

            }
            else {
                var offset;
                if (Browser_IE6()) {
                    offset = $(this).position();
                } else {
                    offset = $(this).offset();
                }
                $(this).multiSelectOptionsGetContainer(o).css({ top: offset.top + $(this).outerHeight() + 'px' });
                $(this).multiSelectOptionsGetContainer(o).css({ left: offset.left + 'px' });
                $(this).multiSelectOptionsGetContainer(o).css({ width: $(this).width() + 'px' });
            }

            // Disappear on hover out
            _multiSelectCurrent = $(this);
            var timer = '';
            $(this).multiSelectOptionsGetContainer(o).hover(function() {
                clearTimeout(timer);
            }, function() {
                timer = setTimeout('jQuery(_multiSelectCurrent).multiSelectOptionsHide("' + o.multiSelectOptionsClass + '"); $(_multiSelectCurrent).unbind("hover");', 0);
            });

        },

        // Update the textbox with the total number of selected items
        multiSelectUpdateSelected: function(o) {
            var i = 0, s = '';
            $(this).find('INPUT:checkbox:checked').not('.selectAll').each(function() {
                i++;
            })

            var input;

            if (o.adjacentOptionsDiv) {
                input = $(this).prev('INPUT.' + o.multiSelectClass);
            }
            else {
                var inputId = $(this).attr('id').replace('_multiSelectOptionsDiv', '');
                input = $(document.body).find('#' + inputId);
            }

            //alert('inputId' + input.attr('id'));

            if (i == 0) {
                input.val(o.noneSelected);
                input.attr('title', input.val());
            } else {
                if (o.oneOrMoreSelected == '*') {
                    var display = '';
                    $(this).find('INPUT:checkbox:checked').each(function() {
                        if ($(this).parent().text() != o.selectAllText) display = display + $(this).parent().text() + ', ';
                    });
                    display = display.substr(0, display.length - 2);
                    input.val(display.substr(0, 22));
                    input.attr('title', display);
                } else {
                    input.val(o.oneOrMoreSelected.replace('%', i));
                    input.attr('title', input.val());
                }
            }


        },

        // Ensures that the selected item is always in the visible portion of the dropdown (for keyboard controls)
        multiSelectAdjustViewport: function(el, o) {
            // Calculate positions of elements
            var i = 0;
            var selectionTop = 0, selectionHeight = 0;
            $(el).multiSelectOptionsGetContainer(o).find('LABEL').each(function() {
                if ($(this).hasClass('hover')) { selectionTop = i; selectionHeight = $(this).outerHeight(); return; }
                i += $(this).outerHeight();
            });
            var divScroll = $(el).multiSelectOptionsGetContainer(o).scrollTop();
            var divHeight = $(el).multiSelectOptionsGetContainer(o).height();
            // Adjust the dropdown scroll position
            $(el).multiSelectOptionsGetContainer(o).scrollTop(selectionTop - ((divHeight / 2) - (selectionHeight / 2)));
        }

    });

})(jQuery);