﻿var multiselectAgent = new MultiSelectAgent();

function MultiSelectAgent() {
    this.timeOutHandler = 0;
    this.initialized = false;
}

// CONTROL FINDING
MultiSelectAgent.prototype.findControl = function(control, cssClass) {
    var container = $(control).closest(".multiselect-dropdown");
    if (container.length == 0)
        alert('A error occured finding parent multiselect control.');
    var controls = $("." + cssClass, container);
    if (controls.length != 1)
        alert('I can not find control properly, css:' + cssClass);
    return $(controls.get(0));
}
MultiSelectAgent.prototype.findTextBox = function(control) {
    return multiselectAgent.findControl(control, "text-box");
}
MultiSelectAgent.prototype.findSearchBox = function(control) {
    return multiselectAgent.findControl(control, "search-box");
}
MultiSelectAgent.prototype.findContainerPanel = function(control) {
    return multiselectAgent.findControl(control, "panel-container");
}
MultiSelectAgent.prototype.findSelectedItemsPanel = function(control) {
    return multiselectAgent.findControl(control, "selected-items");
}
// END OF CONTROL FINDING

MultiSelectAgent.prototype.textBlur = function(control) {
    var panel = multiselectAgent.findContainerPanel(control);
    var textBox = multiselectAgent.findTextBox(control);

    textBox.addClass("__BLURED");

    if (panel.hasClass("__LEAVED")) {
        multiselectAgent.HideItems(control);
    }
}
MultiSelectAgent.prototype.textFocus = function(control) {
    clearTimeout(multiselectAgent.timeOutHandler);
    var searchBox = multiselectAgent.findSearchBox(control);
    var textBox = multiselectAgent.findTextBox(control);

    searchBox.show();

    textBox.removeClass("__BLURED");

    multiselectAgent.ShowItems(searchBox);
    textBox.hide();
}


MultiSelectAgent.prototype.panelOut = function(control) {
    var textbox = multiselectAgent.findTextBox(control);
    var panel = multiselectAgent.findContainerPanel(control);

    panel.addClass("__LEAVED");

    if (textbox.hasClass("__BLURED")) {
        multiselectAgent.HideItems(textbox);
    }
}
MultiSelectAgent.prototype.panelIn = function(control) {
    if (multiselectAgent.timeOutHandler) {
        clearTimeout(multiselectAgent.timeOutHandler);
    }
    var panel = multiselectAgent.findContainerPanel(control);
    control.removeClass("__LEAVED");
}

MultiSelectAgent.prototype.ShowItems = function(control) {
    var textElement = multiselectAgent.findSearchBox(control);
    var itemsContainer = multiselectAgent.findContainerPanel(control);

    var pos = textElement.position();

    if (pos.top + itemsContainer.outerHeight() > $(window.document.body).height())
        itemsContainer.css({ top: pos.top - itemsContainer.outerHeight(), left: pos.left });
    else
        itemsContainer.css({ top: pos.top + textElement.outerHeight(), left: pos.left });

    // hide all open panels
    $('.multiselect-dropdown .panel-container').hide();

    if ($(":checkbox", itemsContainer).length > 0)
        itemsContainer.show();

    multiselectAgent.refreshDisplay(itemsContainer);
}

MultiSelectAgent.prototype.HideItems = function(control) {
    multiselectAgenttimeOutHandler = setTimeout(function() {
        var textElement = multiselectAgent.findTextBox(control);
        var searchElement = multiselectAgent.findSearchBox(control);
        textElement.show();
        searchElement.hide();

        var itemsContainer = multiselectAgent.findContainerPanel(control);
        itemsContainer.hide();

        multiselectAgent.revertAllCheckBoxFromSelectedItems(itemsContainer);

        // FIRE POSTBACK IF NECESSARY
        if (textElement.attr("autoPostBack") == "true" && textElement.attr("somethingIsChanged") == "true") {
            setTimeout('__doPostBack(\'' + textElement.attr("controlID") + '\',\'\')', 0);
        }

    }, parseInt($(control).attr("hideDelay")));
}

MultiSelectAgent.prototype.filterOptions = function(container, searchbox) {
    var parts = $(searchbox).val().split(" ");
    var allCheckBoxes = $("td :checkbox", container);
    allCheckBoxes.each(function(index, checkbox) {
        var jCheckbox = $(checkbox);
        var value = jCheckbox.next().html();
        var matches = true;
        for (var i = 0; i < parts.length; i++) {
            if (value == null || value == undefined || value.toLowerCase().indexOf(parts[i].toLowerCase()) == -1) {
                matches = false;
                break;
            }
        }
        if (matches) {
            jCheckbox.parent().parent().show();
        }
        else {
            jCheckbox.parent().parent().hide();
        }
    });
}

MultiSelectAgent.prototype.addCheckBoxToSelectedItems = function(checkbox, selectedItemsPanel) {
    if ($(checkbox).parent().is("td")) {
        var div = $("<div/>");
        var parent = $(checkbox).parent();
        parent.attr("id", 'td_' + $(checkbox).attr("id"));
        parent.children().appendTo(div);
        div.attr("checkboxID", $(checkbox).attr("id"));
        parent.parent().css("visibility", "hidden");
        parent.parent().hide();
        div.appendTo(selectedItemsPanel);
    }
}

MultiSelectAgent.prototype.revertAllCheckBoxFromSelectedItems = function(container) {
    var selectedItemsPanel = multiselectAgent.findSelectedItemsPanel(container);
    var allCheckBoxes = $("div input[type='checkbox']", container);
    allCheckBoxes.each(function(index, checkbox) {
        multiselectAgent.revertCheckBoxFromSelectedItems(checkbox, selectedItemsPanel);
    });
}
MultiSelectAgent.prototype.revertCheckBoxFromSelectedItems = function(checkbox, selectedItemsPanel) {
    if ($(checkbox).parent().is("div")) {
        var parent = $(checkbox).parent();
        var originalParent = $('#td_' + parent.attr("checkboxID"));
        originalParent.parent().css("visibility", "visible");
        originalParent.parent().show();
        parent.children().remove().appendTo(originalParent);
        parent.remove();
    }
}
MultiSelectAgent.prototype.refreshDisplay = function(container) {
    var allCheckBoxes = $("input[type='checkbox']", container);
    //var jtext = $('#'+$(container).attr("textID"));
    var jtext = multiselectAgent.findTextBox(container);
    var single = "";
    var allSelected = new Array();
    var count = 0;
    var pluralName = jtext.attr('pluralName');
    var selectedItemsPanel = multiselectAgent.findSelectedItemsPanel(container);

    allCheckBoxes.each(function(index, checkbox) {
        if (checkbox.checked) {
            single = $(checkbox).next().html();
            allSelected.push(single);
            count++;

            multiselectAgent.addCheckBoxToSelectedItems(checkbox, selectedItemsPanel);
        }
        else {
            multiselectAgent.revertCheckBoxFromSelectedItems(checkbox, selectedItemsPanel);
        }
    });

    multiselectAgent.handleCheckboxChangeEvent(container);

    var result = single;
    if (count > 1) {
        result = count + ' ' + pluralName;
    }

    jtext.attr("title", allSelected.join(", "));
    if (result.length == 0)
        result = jtext.attr("notSetText");
    jtext.val(result);

    ///
    if (selectedItemsPanel.children().length == 0)
        selectedItemsPanel.hide();
    else
        selectedItemsPanel.show();
}

MultiSelectAgent.prototype.handleCheckboxChangeEvent = function(container) {
    var searchbox = multiselectAgent.findSearchBox(container);
    var textbox = multiselectAgent.findTextBox(container);

    $("input[type='checkbox']", container).unbind("change");
    $("input[type='checkbox']", container).bind("change", function(index, element) {
        multiselectAgent.refreshDisplay(container);
        searchbox.focus();
        textbox.attr("somethingIsChanged", "true");
    });
}

MultiSelectAgent.prototype.initializeMultiselects = function() {
    $(".multiselect-dropdown").each(function(index, multiselect) {
        if ($(multiselect).hasClass("__INITIALIZED"))
            return;
        $(multiselect).addClass("__INITIALIZED");
        var searchBox = multiselectAgent.findSearchBox(multiselect);
        var textBox = multiselectAgent.findTextBox(multiselect);
        var container = multiselectAgent.findContainerPanel(multiselect);

        container.addClass("__LEAVED");
        textBox.addClass("__BLURED");

        searchBox.unbind("blur");
        searchBox.blur(function() { multiselectAgent.textBlur(searchBox); });
        searchBox.unbind("focus");
        searchBox.focus(function() { multiselectAgent.textFocus(searchBox); });
        textBox.unbind("focus");
        textBox.focus(function() {
            multiselectAgent.textFocus(textBox);
            searchBox.focus();
        });
        searchBox.unbind("keyup");
        searchBox.keyup(function() {
            multiselectAgent.filterOptions(container, searchBox);
        });
        $("*", container).unbind("hover");
        $("*", container).hover(function() { multiselectAgent.panelIn(container); });
        container.unbind("hover");
        container.hover(
            function() { multiselectAgent.panelIn(container); },
            function() { multiselectAgent.panelOut(container); }
            );

        multiselectAgent.refreshDisplay(container);
        multiselectAgent.filterOptions(container, searchBox);
    });

    // INTERVAL FOR REVIEWING REGULARLY
    //     setInterval(function(){
    //         $(".multiselect-dropdown").each(function(index, multiselect)
    //         {
    //            var searchBox = multiselectAgent.findSearchBox(multiselect);
    //            var textBox = multiselectAgent.findTextBox(multiselect);
    //            var container = multiselectAgent.findContainerPanel(multiselect);
    //            
    //            if(textBox.hasClass("__BLURED") && container.hasClass("__LEAVED"))
    //                multiselectAgent.HideItems(textBox);
    //         });
    //     }, 500);
}

MultiSelectAgent.prototype.initialize = function() {
    //if(multiselectAgent.initialized)
    //  return;

    multiselectAgent.initialized = true;
    multiselectAgent.initializeMultiselects();

    // solve the IE bug of not firing check event properly 
    $("form :checkbox").click(function() {
        if ($.browser.msie) {
            $(this).fire("change").blur();
            $(this).focus();
        }
    });
}

$(document).ready(function() {
    multiselectAgent.initialize();
});

// THIS HAS TO BE EMBEDDED INTO THE ONLY PAGELOAD() FUNCTION IN THE WHOLE APP (AJAX)
function pageLoad() {
    //multiselectAgent.initialize();
}

jQuery.fn.extend({
    fire: function(evttype) {
        el = this.get(0);
        if (document.createEvent) {
            var evt = document.createEvent('HTMLEvents');
            evt.initEvent(evttype, false, false);
            el.dispatchEvent(evt);
        } else if (document.createEventObject) {
            el.fireEvent('on' + evttype);
        }
        return this;
    }
});