(function (element) {
    element.matches = element.matches || element.mozMatchesSelector || element.msMatchesSelector || element.oMatchesSelector || element.webkitMatchesSelector;
    element.closest = element.closest || function closest(selector) {
        if (!this || !this.parentElement && !this.matches(selector)) return null;
        else if (this.matches(selector)) return this;
        else return this.parentElement.closest(selector);
    };
}(Element.prototype));
function setFstDropdown() {
    var list = document.querySelectorAll(".fstdropdown-select:not(.fstcreated)");
    for (var sel in list)
        if (list.hasOwnProperty(sel))
            createDropdown(list[sel]);

    function createDropdown(select) {
        var searchDisable = select.dataset["searchdisable"];
        var placeholder = select.dataset["placeholder"];
        var opened = select.dataset["opened"];
        var div = createFstElement("div", "fstdiv", select.parentNode, null);
        var dropdown = createFstElement("div", "fstdropdown" + (opened != null && opened == "true" ? " open" : ""), div,
            opened == null || opened != "true" ? { "click": openSelect, "blur": openSelect } : null);
        dropdown.select = select;
        dropdown.setAttribute("tabindex", "0");
        if (opened == null || opened != "true")
            createFstElement("div", "fstselected", dropdown, null);
        if (searchDisable == null || searchDisable != "true") {
            var search = createFstElement("div", "fstsearch", dropdown, null);
            var e = { "keyup": getSearch, "paste": getSearch };
            if (opened == null || opened != "true") e["blur"] = openSelect;
            createFstElement("input", "fstsearchinput", search, e).placeholder = placeholder != undefined ? placeholder : "";
        }
        if (select.multiple) {
            var selectAll = createFstElement("button", "fstAll", dropdown, { "click": selectAllOptions });
            selectAll.textContent = "Select All";
            selectAll.type = "button";
            selectAll.selected = false;
        }
        createFstElement("div", "fstlist", dropdown, null);
        select.fstdropdown = { dd: dropdown, rebind: function () { rebindDropdown(select); }, setValue: function(value){setValue(dropdown, value)} };
        rebindDropdown(select);
        select.classList.add("fstcreated");
    }
    function setValue(dd, value) {
        if (Array.isArray(value))
            for (var v in value) {
                if (value.hasOwnProperty(v)) {
                    var val = dd.querySelector(".fstlist div[data-value='" + value[v] + "']");
                    if (val != null)
                        val.dispatchEvent(new Event('click', { 'bubbles': true }));
                }
            }
        else {
            var val = dd.querySelector(".fstlist div[data-value='" + value + "']");
            if(val != null)
                val.dispatchEvent(new Event('click', { 'bubbles': true }));
        }
    }
    function openSelect(event, open, force) {
        var select = event.target.classList.contains("fstdropdown") ? event.target.select : event.target.closest(".fstdropdown").select;
        open = open == null ? event.type != "blur" : open;
        var el = select.fstdropdown.dd;
        if (checkEvent(event, force)) return;
        if (!open || el.classList.contains("open")) {
            el.classList.remove("open");
            el.parentNode.classList.remove("open");
            return;
        }
        el.classList.add("open");
        el.parentNode.classList.add("open");
        if(select.dataset["searchdisable"] == null && select.dataset["searchdisable"] != "true")
            el.querySelector(".fstsearchinput").focus();
    }

    function checkEvent(event, force) {
        return event.relatedTarget != null && (event.relatedTarget.tagName == "INPUT" || (event.relatedTarget.tagName == "BUTTON" && force == undefined))
            || event.target.tagName == "INPUT" && event.type != "blur"
            || event.target.tagName == "INPUT" && (event.relatedTarget != null && event.relatedTarget.className == "fstdropdown open")
            || event.target.classList.contains("fstselected") && event.type == "blur" && document.activeElement.classList.contains("fstsearchinput")
            || event.type == "blur" && (document.activeElement.className == "fstlist" || document.activeElement.className == "fstAll")
            || event.target.tagName == "BUTTON" && force == undefined;
    }

    function changeSelect(event) {
        var select = event.target.closest(".fstdropdown").select;
        var dd = select.fstdropdown.dd;
        var selectAll = dd.querySelector(".fstAll");
        var opened = select.dataset["opened"] == null || select.dataset["opened"] != "true";
        if (select.value != event.target.dataset["value"] && !select.multiple) {
            select.value = event.target.dataset["value"];
            if (dd.querySelector(".fstlist>.selected") != null)
                dd.querySelector(".fstlist>.selected").classList.remove("selected");
            event.target.classList.add("selected");
            if (opened)
                dd.querySelector(".fstselected").textContent = event.target.textContent;
            initNewEvent("change", select);
        }
        if (select.multiple) {
            changeMultipleSelect(select, event, dd, selectAll, opened);
        }
        if (opened)
            openSelect(event, false);
    }

    function changeMultipleSelect(select, event, dd, selectAll, opened) {
        select.querySelector("[value='" + event.target.dataset["value"] + "']").selected = !event.target.classList.contains("selected");
        if (event.target.classList.contains("selected"))
            event.target.classList.remove("selected");
        else
            event.target.classList.add("selected");
        initNewEvent("change", select);
        var length = dd.querySelectorAll(".fstlist>.selected").length;
        selectAll.selected = length > 0;
        if (opened)
            dd.querySelector(".fstselected").textContent = length == 1 ? event.target.textContent : length + " options selected";
        selectAll.textContent = selectAll.selected ? "Deselect All" : "Select All";
    }

    function rebindDropdown(select) {
        var optList = select.querySelectorAll("option");
        var ddList = select.fstdropdown.dd.querySelector(".fstlist");
        while (ddList.lastChild)
            ddList.removeChild(ddList.lastChild);
        for (var opt in optList) {
            if (optList.hasOwnProperty(opt)) {
                var listEl = document.createElement("div");
                listEl.textContent = optList[opt].textContent;
                listEl.dataset["value"] = optList[opt].value;
                if (optList[opt].selected)
                    listEl.classList.add("selected");
                listEl.addEventListener("click", changeSelect);
                ddList.appendChild(listEl);
            }
        }
        setHeader(select, null);
    }

    function initNewEvent(eventName, target) {
        var event;
        if (typeof (Event) === "function")
            event = new Event(eventName, { bubbles: true });
        else {
            event = document.createEvent("Event");
            event.initEvent(eventName, true, true);
        }
        target.dispatchEvent(event);
    }

    function getSearch(event) {
        var pasteText = event.type != "paste" ? "" : typeof event.clipboardData === "undefined" ?
            window.clipboardData.getData("Text") : event.clipboardData.getData("text/plain");
        var val = event.type != "paste" ? event.target.value : pasteText;
        var dd = event.target.closest(".fstdropdown");
        var ddList = dd.querySelectorAll(".fstlist>div");
        for (var div in ddList)
            if (ddList.hasOwnProperty(div))
                if (ddList[div].textContent.trim().toLowerCase().indexOf(val.trim().toLowerCase()) != -1)
                    ddList[div].classList.remove("hideFst");
                else
                    ddList[div].classList.add("hideFst");
    }

    function createFstElement(type, className, parent, eventListener) {
        var element = document.createElement(type);
        if (className != null)
            for (var c in className.split(" "))
                if (!isNaN(c))
                    element.classList.add(className.split(" ")[c]);
        if (eventListener != null)
            for (var ev in eventListener)
                if (eventListener.hasOwnProperty(ev))
                    element.addEventListener(ev, eventListener[ev], true);
        parent.appendChild(element);
        return element;
    }

    function selectAllOptions(event) {
        var select = event.target.closest(".fstdropdown").select;
        var dd = select.fstdropdown.dd;
        var selected = !event.target.selected;
        event.target.selected = selected;
        var list = !selected ? dd.querySelectorAll(".selected") : dd.querySelectorAll(".fstlist>div:not(.hideFst)");
        for (var l in list)
            if (list.hasOwnProperty(l)) {
                select.querySelector("[value='" + list[l].dataset["value"] + "']").selected = selected;
                if (selected)
                    list[l].classList.add("selected");
                else
                    list[l].classList.remove("selected");
            }
        initNewEvent("change", select);
        event.target.textContent = !selected ? "Select All" : "Deselect All";
        setHeader(select, event);
    }

    function setHeader(select, event) {
        if (select.dataset["opened"] == null || select.dataset["opened"] != "true") {
            var text = "";
            var sOption = select.options[select.selectedIndex];
            if (select.multiple) {
                var count = 0;
                for (var s in select.options)
                    if (select.options.hasOwnProperty(s) && select.options[s].selected == true)
                        count++;
                text = count == 1 ? sOption.textContent : count + " options selected";
            }
            select.fstdropdown.dd.querySelector(".fstselected").textContent = select.multiple ? text : sOption != undefined ? sOption.textContent : "";
            if(event != null)
                openSelect(event, false, true);
        }
    }
}

document.addEventListener("DOMContentLoaded", setFstDropdown);
