/* global Bdf,$$ */

Bdf.Deploy = {};

Bdf.Deploy.visibilityListenerFunctionArray = new Array();

/**
 * listenerFunction doit avoir deux arguments :
 * - l'élement du DOM concerné
 * - une valeur booléenne indiquant si l'objet est visible
 * 
 * @param {type} listenerFunction
 * @returns {undefined}
 */
Bdf.Deploy.addVisibilityListener = function (listenerFunction) {
    Bdf.Deploy.visibilityListenerFunctionArray.push(listenerFunction);
};

Bdf.Deploy.fireVisibility = function (element, visible) {
    for(let visibilityListenerFunction of Bdf.Deploy.visibilityListenerFunctionArray) {
        visibilityListenerFunction(element, visible);
    }
};

Bdf.Deploy.init = function ($element) {
    var localData = Bdf.getMainLocalStorage();
    _detailsInit();
    _checkboxInit();
    _radioInit();
    
    
    function _detailsInit() {
        let $deployDetails = $$($element, {deployRole: "details"});
        if (localData) {
            if (localData.hasOwnProperty("deploy_details")) {
                let storeObject = localData["deploy_details"];
                for(let id in storeObject) {
                    try {
                        $$.one(id).open = storeObject[id];
                    } catch(e) {

                    }
                }
            }
        }
        $deployDetails.on("toggle", function () {
            let id = this.id;
            if (this.id) {
                localData = Bdf.getMainLocalStorage();
                if (localData) {
                    let storeObject;
                    if (!localData.hasOwnProperty("deploy_details")) {
                        storeObject = new Object();
                        localData["deploy_details"] = storeObject;
                    } else {
                        storeObject = localData["deploy_details"];
                    }
                    storeObject[this.id] = this.open;
                    Bdf.putMainLocalStorage(localData);
                }
            }
        });
    }
    
    
    function _checkboxInit() {
        let $deployCheckboxes = $$($element, {deployRole: "checkbox"});
        let checkboxesCount = $deployCheckboxes.length;
        for (let i = 0; i < checkboxesCount; i++) {
            let deployCheckbox = $deployCheckboxes[i];
            let $deployCheckbox = $(deployCheckbox);
            if ($deployCheckbox.data("deployInitialized")) {
                continue;
            } else {
                $deployCheckbox.data("deployInitialized", true);
            }
            Bdf.Deploy.checkVisibility(deployCheckbox);
            $deployCheckbox.on("change", function () {
                Bdf.Deploy.checkVisibility(this);
            });
        }
    }
    
    function _radioInit() {
        let $deployRadios = $$($element, {deployRole: "radio"});
        let radioCount = $deployRadios.length;
        if (radioCount > 0) {
            Bdf.Deploy.initRadioGroups($element);
            for (let i = 0; i < radioCount; i++) {
                let deployRadio = $deployRadios[i];
                let $deployRadio = $(deployRadio);
                if ($deployRadio.data("deployInitialized")) {
                    continue;
                } else {
                    $deployRadio.data("deployInitialized", true);
                }
                Bdf.Deploy.checkVisibility(deployRadio);
                Bdf.Deploy.getRadioGroup(deployRadio).push(Bdf.Deploy.getChangeFunction(deployRadio));
            }
        }
    }
    
};

Bdf.Deploy.initOverlay = function (overlayId) {
    Bdf.Deploy.init($$(overlayId, "dialog"));
};

Bdf.Deploy.ensureLinkVisibility = function($elements, visible) {
    $elements.each(function (index, element) {
        let $element = $(element);
        if ($element.data("deployRole") === "link") {
            let $deployTarget = $($element.data("deployTarget"));
            let currentVisible = !$deployTarget.hasClass("hidden");
            if (currentVisible !== visible) {
                $element.click();
            }
        } else {
            Bdf.Deploy.ensureLinkVisibility($$($element, {deployRole: "link"}), visible);
        }
    });
};

Bdf.Deploy.getChangeFunction = function (deployRadio) {
    return function () { 
        Bdf.Deploy.checkVisibility(deployRadio);
    };
};

Bdf.Deploy.checkVisibility = function (input) {
    var visible = input.checked;
    if (input.dataset.deployInvert) {
        visible = !visible;
    }
    var $target = $(input.dataset.deployTarget);
    if (visible) {
        $target.removeClass("hidden");
        $$($target, {deployRequired: "visible"}).prop("required", true);
    }
    else {
        $target.addClass("hidden");
        $$($target, {deployRequired: "visible"}).prop("required", false);
    }
    $target.each(function () {Bdf.Deploy.fireVisibility(this, visible);});
};

Bdf.Deploy.initRadioGroups = function ($element) {
    var $radioList = $element.find('input[type="radio"]');
    for(let i = 0, len = $radioList.length; i < len; i++) {
        _initRadio($radioList[i]);
    }
    
    function _initRadio(radioElement) {
        let $radio = $(radioElement);
        let $form = $radio.closest("form");
        let name = $radio.attr('name');
        if ((name) && ($form.length === 1)) {
            let map = $form.data("radioGroupMap");
            if (!map) {
                map = new Object();
                $form.data("radioGroupMap", map);
            }
            let radioGroup;
            if (!map.hasOwnProperty(name)) {
                radioGroup = new Bdf.Deploy.RadioGroup(name);
                map[name] = radioGroup;
            } else {
                radioGroup = map[name];
            }
            if (!$radio.data("deployRadioInitialized")) {
                $radio.data("deployRadioInitialized", true);
                $radio.change(function () {
                    Bdf.Deploy.getRadioGroup(this).change();
                });
            }
        }
    }
};

Bdf.Deploy.getRadioGroup = function(radio) {
    var $radio = $(radio);
    var $form = $radio.closest("form");
    var map = $form.data("radioGroupMap");
    if (map) {
        return map[$radio.attr('name')];
    } else {
        return null;
    }
};

/**
 * Conserve les informations sur un groupe de boutons radios partageant
 * le même attribut name
 * 
 * @param {string} name attribut name commun
 * @returns {undefined} cette fonction est un constructeur
 */
Bdf.Deploy.RadioGroup = function (name) {
    this.name = name;
    this.changeFunctionArray = new Array();
};

Bdf.Deploy.RadioGroup.prototype.push = function (changeFunction) {
    this.changeFunctionArray.push(changeFunction);
};

Bdf.Deploy.RadioGroup.prototype.change = function () {
    for(let changeFunction of this.changeFunctionArray) {
        changeFunction();
    }
};

$(function () {
    Bdf.Deploy.init($("body"));
});