const Toast = {
    showSuccess: function (text) {
        const duplicate = $("#success-alert").clone();
        duplicate.find("#success-alert-text").text(text);
        duplicate.appendTo("#toastContainer");
        duplicate.fadeTo(4000, 500).slideUp(1000, function () {
            $("#success-alert").slideUp(1500);
        });
    },
    showError: function (text) {
        const duplicate = $("#error-alert").clone();
        duplicate.find("#error-alert-text").text(text);
        duplicate.appendTo("#toastContainer");
        duplicate.fadeTo(4000, 500).slideUp(1000, function () {
            $("#error-alert").slideUp(1500);
        });
    },
    showWarning: function (text) {
        const duplicate = $("#warning-alert").clone();
        duplicate.find("#warning-alert-text").text(text);
        duplicate.appendTo("#toastContainer");
        duplicate.fadeTo(4000, 500).slideUp(1000, function () {
            $("#warning-alert").slideUp(1500);
        });
    }
};

function toggleMenu() {
    $("#top-nav").toggleClass("show");
}

function toggleAccordionVisibility(source, event) {
    event = event || window.event;
    const trgt = event.target || event.srcElement;
    if (trgt && trgt.className && trgt.className.indexOf('no-click') !== -1) {
        return;
    }

    const that = $(source);
    const icons = that.find("i.fas");
    if (icons) {
        icons.toggle();
    }
    const accordionBody = that.next();
    if (accordionBody && accordionBody.length > 0) {
        accordionBody.slideToggle(function () {
            // Animation complete.
            const id = accordionBody[0].id;
            localStorage.setItem(id, accordionBody.css("display"));
        });

        // update pozice buttonu
        setTimeout(function () {
            stickButtonTuBottom();
        }, 1002);

    }
}

function appendScript(wwwPath) {
    let path = wwwPath + "/javascript/ie11CustomProperties.js";
    const script = document.createElement("script");
    script.src = path;

    document.getElementsByTagName("head")[0].appendChild(script);
}

function toggleSlideById(id) {
    const elem = $("#" + id);

    if (elem) {
        elem.slideToggle();
    }

    setTimeout(function () {
        stickButtonTuBottom();
    }, 1001);
}

function hideSlideById(id) {
    $("#" + id).hide(1000);

    setTimeout(function () {
        stickButtonTuBottom();
    }, 1001);
}

function showSlideById(id) {
    $("#" + id).show(1000);

    setTimeout(function () {
        stickButtonTuBottom();
    }, 1001);
}

function hideById(id) {
    $("#" + id).hide(0);

    setTimeout(function () {
        stickButtonTuBottom();
    }, 1001);
}

function showById(id) {
    $("#" + id).show(0);

    setTimeout(function () {
        stickButtonTuBottom();
    }, 1001);
}

function copyToTarget(sourceElem, targetId) {
    const target = $("#" + targetId);
    if (!target || target.length === 0) {
        return;
    }
    const newText = $(sourceElem)[0].innerHTML;
    const currentText = target.val();
    // je to prazdne
    if (!currentText) {
        target.val(newText);
        return;
    }
    // uz tam je
    if (currentText.indexOf(newText) > -1) {
        return;
    }

    // pridame
    target.val(currentText + '\n' + newText);
}

function clickToNextFile(id) {
    if (id) {
        $("input#" + id).click();
    }
}

function showLoading() {
    $(".loader-wrapper").show();
}

function customFormValidity2(form, disableEnergyCheck, programId) {
    let result = true;
    const existsValidationDialog = $("#validationFailedDialog").length > 0;
    if (existsValidationDialog) {
        $("#validationFailedDialog .modal-body #modal-content").html("");
    }

    // validace poctu obyvatel > 0
    const elem = $("#p1_11");
    if (elem && elem.length > 0) {
        let val = elem.val();
        if (val) {
            val = val.toString().replace(/ /g, "");
        }

        const popSizeOk = val && +val > 0;
        if (!popSizeOk) {
            elem[0].setCustomValidity('not valid');
            result = false;
        } else {
            elem[0].setCustomValidity('');
        }
    }
    // validace na Investment sector(s) targeted - others
    const chbOthersElem = $(form).find("#p2_1_7");
    const txtOthersElem = $(form).find("#p2_1_others");
    if (chbOthersElem && chbOthersElem.length > 0 && txtOthersElem && txtOthersElem.length > 0) {
        if (chbOthersElem[0].checked && (!txtOthersElem.val() || txtOthersElem.val() == '')) {
            txtOthersElem[0].setCustomValidity('not valid');
            result = false;
        } else {
            txtOthersElem[0].setCustomValidity('');
        }
    }

    // validace impactu, energy savings je povinný, a když je vyplněný renewable, tak savings > renewable
    const expSavings = $(form).find("#p3_3_1");
    const expRenew = $(form).find("#p3_3_2");
    if (!disableEnergyCheck && expSavings && expSavings.length > 0 && expRenew && expRenew.length > 0) {
        expSavings[0].classList.remove('custom-invalid-control');
        expRenew[0].classList.remove('custom-invalid-control');

        let val1 = expSavings.val();
        let val2 = expRenew.val();

        if (val1) {
            val1 = val1.toString().replace(/ /g, "");
        }
        if (val2) {
            val2 = val2.toString().replace(/ /g, "");
        }
        const isVal1 = expSavings && val1 && +val1 > 0;
        const isVal2 = expRenew && val2 && +val2 > 0;
        if (!isVal1) {
            expSavings[0].setCustomValidity(!isVal1 ? 'not valid' : '');
            expSavings[0].classList.add('custom-invalid-control');

            result = false;
        } else if (isVal1 && isVal2 && +val1 <= +val2) {
            expSavings[0].setCustomValidity('not valid');
            expRenew[0].setCustomValidity('not valid');
            expSavings[0].classList.add('custom-invalid-control');
            expRenew[0].classList.add('custom-invalid-control');

            result = false;

            if (existsValidationDialog) {
                $("#validationFailedDialog .modal-body #modal-content").html("Please make sure the Expected energy savings are greater than Expected renewable energy production.");
            }
        } else {
            expSavings[0].setCustomValidity('');
            expRenew[0].setCustomValidity('');

            expSavings[0].classList.remove('custom-invalid-control');
            expRenew[0].classList.remove('custom-invalid-control');
        }
    }

    // validace - musi byt secap doc nebo plan URl
    const planUrlElem = $(form).find("#plan_url");
    const p4_1 = $(form).find("input#f_p4_1");
    const f_p4_1 = $(form).find("input#p4_1");
    if (planUrlElem && planUrlElem.length > 0 && p4_1 && p4_1.length > 0) {
        const planUrl = planUrlElem.val();
        const fileName = p4_1.val();
        const f_fileName = f_p4_1.val();

        if (!planUrl && !(fileName || f_fileName)) {
            planUrlElem[0].setCustomValidity('not valid');
            p4_1[0].setCustomValidity('not valid');
            result = false;

            setRequiredByElem(planUrlElem[0]);
            setRequiredByElem(p4_1[0]);

            if (existsValidationDialog) {
                $("#validationFailedDialog .modal-body #modal-content").html("Nor SECAP document or URL of the plan are required.");
            }
        } else {
            planUrlElem[0].setCustomValidity('');
            p4_1[0].setCustomValidity('');

            if (planUrl) {
                setRequiredByElem(planUrlElem[0]);
                clearRequiredByElem(p4_1[0]);
            } else {
                clearRequiredByElem(planUrlElem[0]);
                setRequiredByElem(p4_1[0]);
            }
        }
    }

    // validace mitigation targets
    const mitTableRowsName = ['energy_savings', 'renewable_energy', 'ghg', 'other_targets'];
    const mitTableColsName = ['target_value', 'unit', 'target_year', 'page_number'];
    const exists = $(form).find("#energy_savings_target_value");
    let oneRowFilled = false;
    if (exists && exists.length > 0) {
        for (let i = 0; i < mitTableRowsName.length; i++) {
            let rowFilled = true;
            for (let j = 0; j < mitTableColsName.length; j++) {
                const id = mitTableRowsName[i] + '_' + mitTableColsName[j];
                const elem = document.getElementById(id);
                if (elem.value == null || elem.value == "") {
                    rowFilled = false;
                }
            }

            // test na radek
            if (rowFilled) {
                oneRowFilled = true;
                break;
            }
        }

        // hlaska
        if (!oneRowFilled && existsValidationDialog) {
            result = false;
            $('#migitation_targets_invalid_feedback').show();
            const html = $("#validationFailedDialog .modal-body #modal-content").html();
            $("#validationFailedDialog .modal-body #modal-content").html(html + "<br>" + "At least one row in mitigation targets must be filled in.");
        } else {
            $('#migitation_targets_invalid_feedback').hide();
        }
    }

    // validace - intended measures
    let rowsCount = $(form).find(".measure-row");
    if (programId === 1 && rowsCount && rowsCount.length > 0) {
        let isOk = false;
        for (let i = 1; i < rowsCount.length; i++) {
            const row = rowsCount[i];
            const v1 = $(row).find("input[name='intended_measure[]']").val();
            const v2 = $(row).find("select[name='investment_sector[]']").val();
            const v3 = $(row).find("input[name='investment_cost[]']").val();
            const v4 = $(row).find("input[name='energy_savings[]']").val();
            const v5 = $(row).find("input[name='renewable_energy[]']").val();

            if ((v1 && v2 && v3 && v4) || (v1 && v2 && v3 && v5)) {
                isOk = true;
                break;
            }
        }

        // hlaska
        if (!isOk && existsValidationDialog) {
            result = false;
            $('#intended_measures_invalid_feedback').show();
            const html = $("#validationFailedDialog .modal-body #modal-content").html();
            $("#validationFailedDialog .modal-body #modal-content").html(html + "<br>" + "At least one row in intended measures must be filled in. Columns 1, 2, 3, 4 or 1, 2, 3, 5.");
        } else {
            $('#intended_measures_invalid_feedback').hide();
        }
    }

    // validace - planned measures
    const measuresContainers = $(form).find(".measures-container");
    if (programId === 2 && measuresContainers && measuresContainers.length > 0) {
        for (let c = 0; c < measuresContainers.length; c++) {
            rowsCount = $(measuresContainers[c]).find(".measure-row.measure-row-item");
            if (rowsCount && rowsCount.length > 0) {
                let isOk = false;
                for (let i = 0; i < rowsCount.length; i++) {
                    const row = rowsCount[i];
                    const v1 = $(row).find("input.class-intended_measure").val();
                    const v2 = $(row).find("select.class-investment_sector ").val();
                    const v3 = $(row).find("input.class-investment_cost").val();
                    const v4 = $(row).find("input.class-energy_savings").val();
                    const v5 = $(row).find("input.class-renewable_energy").val();

                    if ((v1 && v2 && v3 && v4) || (v1 && v2 && v3 && v5)) {
                        isOk = true;
                        break;
                    }
                }

                // hlaska
                if (!isOk && existsValidationDialog) {
                    result = false;
                    $(measuresContainers[c]).parents(".accordion-body").find('#ic_project_planned_measures_invalid_feedback').show();
                    const html = $("#validationFailedDialog .modal-body #modal-content").html();
                    $("#validationFailedDialog .modal-body #modal-content").html(html + "<br>" + "At least one row in intended measures must be filled in. Columns 1, 2, 4, 7 or 1, 2, 5, 7.");
                } else {
                    $(measuresContainers[c]).parents(".accordion-body").find('#ic_project_planned_measures_invalid_feedback').hide();
                }
            }
        }
    }

    // validate na pocet projektu na formu - alespon 1
    const projectContainers = $(form).find(".accordion-group.ic_project");
    if (programId === 2) {
        if (projectContainers.length === 0) {
            result = false;
            $('#single_project_invalid_feedback').show();

            const html = $("#validationFailedDialog .modal-body #modal-content").html();
            $("#validationFailedDialog .modal-body #modal-content").html(html + "<br>" + "At least one project must be filled in.");

        } else {
            $('#single_project_invalid_feedback').hide();
        }
    }

    // validace - alespon jedno planned measure musi byt zadano
    if (programId === 2) {
        rowsCount = $(form).find(".measure-row.measure-row-item");
        if (rowsCount.length === 0) {
            result = false;
            $('#ic_project_planned_measures_invalid_feedback').show();

            const html = $("#validationFailedDialog .modal-body #modal-content").html();
            $("#validationFailedDialog .modal-body #modal-content").html(html + "<br>" + "At least one row in section 3.1.8 Description of planned measure must be filled in.");

        } else {
            $('#ic_project_planned_measures_invalid_feedback').hide();
        }
    }

    // validace na the total investment size is not the same in 3.1.9 and 3.4.5.
    // 3.4.5 id="tot_investment_size_project-1" class investment-total
    // 3.1.9 id="ic_project_summary_of_impacts_costs"
    const projects = $(form).find(".accordion-group.ic_project");
    if (programId === 2 && projects && projects.length > 0) {
        for (let c = 0; c < projects.length; c++) {
            let toValidate1 = $(projects[c]).find(".investment-total");
            let toValidate2 = $(projects[c]).find("#ic_project_summary_of_impacts_costs");

            let val1 = clearNumericValue(toValidate1[0].value);
            let val2 = clearNumericValue(toValidate2[0].value);

            if  (+val1 != 0 && +val2 != 0 && +val1 != +val2) {
                result = false;

                const html = $("#validationFailedDialog .modal-body #modal-content").html();
                $("#validationFailedDialog .modal-body #modal-content").html(html + "<br>" + "Investment size in section 3.4.5 is not same as in section 3.1.9!");
            }
        }
    }

    // validace na MM.YYYY
    if (programId === 2 && projects && projects.length > 0) {
        for (let c = 0; c < projects.length; c++) {
            let toValidate = $(projects[c]).find("#ic_project_lifetime_project_start");
            if (toValidate.length > 0) {
                for (let i = 0; i < toValidate.length; i++) {
                    const item = toValidate[i].value;
                    if (!item || !/^(0[1-9]|1[0-2])[.]\d{4}$/.test(item)) {
                        toValidate[i].setCustomValidity('not valid');
                        result = false;
                    } else {
                        toValidate[i].setCustomValidity('');
                    }
                }
            }

            toValidate = $(projects[c]).find("#ic_project_lifetime_project_revenues");
            if (toValidate.length > 0) {
                for (let i = 0; i < toValidate.length; i++) {
                    const item = toValidate[i].value;
                    if (!item || !/^(0[1-9]|1[0-2])[.]\d{4}$/.test(item)) {
                        toValidate[i].setCustomValidity('not valid');
                        result = false;
                    } else {
                        toValidate[i].setCustomValidity('');
                    }
                }
            }


            toValidate = $(projects[c]).find("#ic_project_lifetime_project_termination");
            if (toValidate.length > 0) {
                for (let i = 0; i < toValidate.length; i++) {
                    const item = toValidate[i].value;
                    if (!item || !/^(0[1-9]|1[0-2])[.]\d{4}$/.test(item)) {
                        toValidate[i].setCustomValidity('not valid');
                        result = false;
                    } else {
                        toValidate[i].setCustomValidity('');
                    }
                }
            }
        }
    }

    // validate Finac approach - kdyz je other, tak je textarea povinna
    if (programId === 2 && projects && projects.length > 0) {
        for (let c = 0; c < projects.length; c++) {
            let toValidate = $(projects[c]).find("#non_redee_others");
            if (toValidate.length > 0) {
                for (let i = 0; i < toValidate.length; i++) {
                    const item = toValidate[i].value;
                    const taText = $(projects[c]).find("#non_redee_others_others").val();
                    if (item != "0" && item != "" && !taText) {
                        $(projects[c]).find("#non_redee_others_others")[0].setCustomValidity('not valid');
                        result = false;
                    } else {
                        $(projects[c]).find("#non_redee_others_others")[0].setCustomValidity('');
                    }
                }
            }

            toValidate = $(projects[c]).find("#private_redee_others");
            if (toValidate.length > 0) {
                for (let i = 0; i < toValidate.length; i++) {
                    const item = toValidate[i].value;
                    const taText = $(projects[c]).find("#private_redee_others_others").val();
                    if (item != "0" && item != "" && !taText) {
                        $(projects[c]).find("#private_redee_others_others")[0].setCustomValidity('not valid');
                        result = false;
                    } else {
                        $(projects[c]).find("#private_redee_others_others")[0].setCustomValidity('');
                    }
                }
            }

            toValidate = $(projects[c]).find("#public_redee_others");
            if (toValidate.length > 0) {
                for (let i = 0; i < toValidate.length; i++) {
                    const item = toValidate[i].value;
                    const taText = $(projects[c]).find("#public_redee_others_others").val();
                    if (item != "0" && item != "" && !taText) {
                        $(projects[c]).find("#public_redee_others_others")[0].setCustomValidity('not valid');
                        result = false;
                    } else {
                        $(projects[c]).find("#public_redee_others_others")[0].setCustomValidity('');
                    }
                }
            }
        }
    }


    return result;
}

function customFormValidity() {
    try {
        // povinne checkboxy
        const invalidControls = $("input.custom-form-check-required-one-input");
        const chbGroupValid = {};
        for (let i = 0; i < invalidControls.length; i++) {
            const c = invalidControls[i];
            const msgId = $(c).data("valid-msg-id");
            const isChecked = c.checked;
            chbGroupValid[msgId] = chbGroupValid[msgId] || isChecked;
        }

        // Loop to print keys
        let isValid = true;
        for (let key in chbGroupValid) {
            if (chbGroupValid.hasOwnProperty(key)) {
                if (!chbGroupValid[key]) {
                    $("#" + key).show();
                    isValid = false;
                } else {
                    $("#" + key).hide();
                }
            }
        }
        return isValid;
    } catch (e) {
        console.log("customFormValidity error", e);
        return false;
    }
}

function customFormValidityNumChbChecked(desiredCheckedNumber) {
    try {
        // povinne checkboxy
        const chbGroupValid = {};
        const invalidControls = $("input.custom-form-check-required-max-four-input");
        for (let i = 0; i < invalidControls.length; i++) {
            const c = invalidControls[i];
            const msgId = $(c).data("valid-msg-id");
            const isChecked = c.checked;

            const val = chbGroupValid[msgId] ?? 0;
            chbGroupValid[msgId] = isChecked ? val + 1 : val;
        }

        // Loop to print keys
        let isValid = true;
        for (let key in chbGroupValid) {
            if (chbGroupValid.hasOwnProperty(key)) {
                if (chbGroupValid[key] > desiredCheckedNumber || !chbGroupValid[key]) {
                    $("#" + key).show();
                    isValid = false;
                } else {
                    $("#" + key).hide();
                }
            }
        }
        return isValid;
    } catch (e) {
        console.log("customFormValidityNumChbChecked error", e);
        return false;
    }
}

function customFormValidityExtended() {
    try {
        // povinne checkboxy
        const invalidControls = $("input.custom-form-check-required-one-input");
        const chbGroupValid = {};
        for (let i = 0; i < invalidControls.length; i++) {
            const c = invalidControls[i];
            const msgId = $(c).data("valid-msg-id");
            const parentId = $(c).data("test-parent-check");
            const requiredIds = $(c).data("required-target-ids");
            let isChecked = c.checked;
            if (parentId) {
                const parent = document.getElementById(parentId);
                if (parent) {
                    if (!parent.checked) {
                        isChecked = true;
                    }
                }
            }
            if (requiredIds) {
                const ids = requiredIds.split(',');
                for (let j = 0; j < ids.length; j++) {
                    const elem = document.getElementById(ids[j]);
                    if (!elem) {
                        continue;
                    }

                    elem.required = isChecked;
                    if (isChecked) {
                        elem.setAttribute("required", "");
                        $("#" + ids[j]).attr('required', '');
                        console.log("Set required ON to element " + ids[j]);
                    } else {
                        elem.removeAttribute("required");
                        $("#" + ids[j]).removeAttr('required');
                        console.log("Set required OFF to element " + ids[j]);
                    }
                }
            }
            chbGroupValid[msgId] = chbGroupValid[msgId] || isChecked;
        }

        // Loop to print keys
        let isValid = true;
        for (let key in chbGroupValid) {
            if (chbGroupValid.hasOwnProperty(key)) {
                if (!chbGroupValid[key]) {
                    $("#" + key).show();
                    isValid = false;
                } else {
                    $("#" + key).hide();
                }
            }
        }
        return isValid;
    } catch (e) {
        console.log("customFormValidityExtended error", e);
        return false;
    }
}

function getURLSync(url) {
    return $.ajax({
        type: "GET",
        url: url,
        cache: false,
        async: false
    }).responseText;
}

function fillTaxDuplicityModalAndShow(list) {
    let result =
        " <div class='form-group font-weight-bolder row mb-2'>\n" +
        "                        <div class='col-8'>\n" +
        "                           Municipality name" +
        "                        </div>\n" +
        "                        <div class='col-4'>\n" +
        "                           Project id" +
        "                        </div>\n" +
        "                    </div>";
    for (let i = 0; i < list.length; i++) {
        result +=
            " <div class='form-group row mb-0'>\n" +
            "                        <div class='col-8'>\n" +
            "                          " +
            list[i].p1_2 +
            "                        </div>\n" +
            "                        <div class='col-4'>\n" +
            "                          " +
            list[i].id_project +
            "                        </div>\n" +
            "                    </div>";
    }

    $("#taxDuplicityConfirmation .modal-body #modal-content").html("");
    $("#taxDuplicityConfirmation .modal-body #modal-content").html(result);
    $("#taxDuplicityConfirmation").modal();
}

function getDuplicityText(list) {
    let result =
        " <div class='form-group font-weight-bolder row mb-2'>\n" +
        "                        <div class='col-8'>\n" +
        "                           Municipality name" +
        "                        </div>\n" +
        "                        <div class='col-4'>\n" +
        "                           Project id" +
        "                        </div>\n" +
        "                    </div>";
    for (let i = 0; i < list.length; i++) {
        result +=
            " <div class='form-group row mb-0'>\n" +
            "                        <div class='col-8'>\n" +
            "                          " +
            list[i].lau_name_national +
            "                        </div>\n" +
            "                        <div class='col-4'>\n" +
            "                          " +
            list[i].fk_id_project +
            "                        </div>\n" +
            "                    </div>";
    }
    return result;
}

function fillDuplicityModalAndShow(list, text) {
    const result = getDuplicityText(list);
    $("#duplicityConfirmation .modal-body #modal-content").html("");
    $("#duplicityConfirmation .modal-body #modal-content").html("");

    if (text) {
        $("#duplicityConfirmation .modal-body #modal-validation-result").html("Please note that one (or more) of the provided LAU codes corresponds to a municipality/local authority that has been selected for EUCF support. Municipalities/local authorities are able to benefit only once from the support provided by the EUCF. Therefore, beneficiaries from previous calls will not be able to submit their applications.");
    } else {
        $("#duplicityConfirmation .modal-body #modal-validation-result").html("Duplicities in LAU codes were detected. One or more municipalities participating in your application takes also part in another application(s) in frame of the same EUCF call. In case of doubts, please contact the EUCF helpdesk.");
    }

    $("#duplicityConfirmation .modal-body #modal-content").html(result);
    $("#duplicityConfirmation").modal();
}

function fillDuplicityModalAndShowNoContinue(list, text) {
    const result = getDuplicityText(list);

    $("#duplicityConfirmationNoContinue .modal-body #modal-content").html("");

    if (text) {
        $("#duplicityConfirmationNoContinue .modal-body #modal-validation-result").html("One (or more) of the provided LAU codes corresponds to a municipality/local authority that has already been selected for EUCF support. Municipalities/local authorities are able to benefit only once from the support provided by the EUCF. The application cannot be submitted.");
    } else {
        $("#duplicityConfirmationNoContinue .modal-body #modal-validation-result").html("Duplicities in LAU codes were detected. One or more municipalities participating in your application takes also part in another application(s) in frame of the same EUCF call. In case of doubts, please contact the EUCF helpdesk.");
    }

    $("#duplicityConfirmationNoContinue .modal-body #modal-content").html(result);
    $("#duplicityConfirmationNoContinue").modal();
}

function fillDuplicityModalOnCityChangeAndShow(list) {
    const result = getDuplicityText(list);

    $("#duplicityOnCityChangeConfirmation .modal-body #modal-content").html("");
    $("#duplicityOnCityChangeConfirmation .modal-body #modal-content").html(result);
    $("#duplicityOnCityChangeConfirmation").modal();
}

function parse_query_string(query) {
    const vars = query.split("&");
    const query_string = {};
    for (let i = 0; i < vars.length; i++) {
        const pair = vars[i].split("=");
        const key = decodeURIComponent(pair[0]);
        const value = decodeURIComponent(pair[1]);
        // If first entry with this name
        if (typeof query_string[key] === "undefined") {
            query_string[key] = decodeURIComponent(value);
            // If second entry with this name
        } else if (typeof query_string[key] === "string") {
            const arr = [query_string[key], decodeURIComponent(value)];
            query_string[key] = arr;
            // If third or later entry with this name
        } else {
            query_string[key].push(decodeURIComponent(value));
        }
    }
    return query_string;
}

function checkTaxNumberDuplicity(idProject) {
    const taxNumberElem = document.getElementById("tax_number");
    // neni potreba kontrolovat
    if (!taxNumberElem || taxNumberElem.value == null || taxNumberElem.value == "") {
        return true;
    }

    const isDuplicityList = getURLSync(
        "../../../Utils/isTaxNumberDuplicity.php?id_project=" + idProject + "&taxNumber=" + taxNumberElem.value
    );

    if (isDuplicityList !== "-1") {
        const list = JSON.parse(isDuplicityList);
        // no duplicities
        if (list && list.length === 0) {
            console.log(
                "Try to check tax number duplicity after submitting ... CONTINUE"
            );
            return true;
        }

        console.log(
            "Try to check tax number duplicity after submitting ... FAIL"
        );
        fillTaxDuplicityModalAndShow(list);
        return false;
    }

    console.log(
        "Duplicity checking error, please contact administrator."
    );
    Toast.showError(
        "Duplicity checking error, please contact administrator."
    );

    return false;
}

(function () {
    if ($.fn.dataTable) {
        $.extend($.fn.dataTable.defaults, {
            lengthMenu: [
                [16, 32, 64, -1],
                [16, 32, 64, "All"]
            ],
            bLengthChange: true,
            pageLength: 16,
            iDisplayLength: 16,
            responsive: true,
            buttons: [
                'csvHtml5', 'excelHtml5', {
                    extend: 'pdfHtml5',
                    orientation: 'landscape',
                    exportOptions: {
                        columns: 'th:not(:last-child)'
                    }
                }
            ]
        });
    }

    ("use strict");
    window.addEventListener(
        "load",
        function () {
            // Fetch all the forms we want to apply custom Bootstrap validation styles to
            const forms = document.getElementsByClassName("needs-validation");
            // Loop over them and prevent submission
            const validation = Array.prototype.filter.call(forms, function (form) {
                form.addEventListener(
                    "submit",
                    function (event) {
                        if (this.submited === "onlySave") {
                            // test na unikatnost municipality/local authority
                            console.log("Try to test on fully-loaded NUTS3 data ...");
                            const cities = document.querySelectorAll('.chosen-select-city');
                            let isOk = true;
                            const codes = [];
                            cities.forEach(c => {
                                if (!c.value) {
                                    isOk = false;
                                    return;
                                }

                                if (codes.includes(c.value)) {
                                    isOk = false;
                                    return;
                                }

                                codes.push(c.value);
                            });

                            if (!isOk) {
                                event.preventDefault();
                                event.stopPropagation();
                                console.log("Try to test on fully-loaded NUTS3 data ... FAIL");

                                Toast.showError("The page is still loading data, please try again in a while. Also please check if there is no duplicity in the form section 1.3.1 LAU and NUTS 3 code. Please try to save the form again ...");
                                return;
                            }

                            console.log("Try to check LAUS duplicity after submitting ...");
                            const query = window.location.search.substring(1);
                            const qs = parse_query_string(query);

                            if (!qs.id_project || qs.id_project === "-1") {
                                console.log(
                                    "Try to check LAUS duplicity after submitting ... SKIP - creating project"
                                );
                                showLoading();
                                return;
                            }

                            const lauCodes = document.getElementsByName("lauCode[]");
                            const typeOfApplicant = document.getElementById("type_of_applicant").value;
                            if (typeOfApplicant === "public") {
                                console.log(
                                    "CHECKING Tax number duplicity after submitting ... PUBLIC ENTITY"
                                );

                                const canProceed = checkTaxNumberDuplicity(qs.id_project);
                                if (!canProceed) {
                                    event.preventDefault();
                                    event.stopPropagation();
                                    console.log(
                                        "Try to check LAUS duplicity after submitting ... FAIL"
                                    );
                                } else {
                                    showLoading();
                                }

                                return;
                            }

                            if (!lauCodes || lauCodes.length === 0) {
                                Toast.showError("No LAU and NUTS 3 code of the municipality/local authority provided, can not continue.");
                                event.preventDefault();
                                event.stopPropagation();
                                return;
                            }

                            const lauCodesValues = [];
                            if (lauCodes) {
                                for (let i = 0; i < lauCodes.length; i++) {
                                    lauCodesValues.push(lauCodes[i].value);
                                }
                            }
                            const isLauCodeDuplicityList = getURLSync(
                                "../../../Utils/isLauCodeDuplicity.php?id_project=" + qs.id_project + "&lauCodes=" + lauCodesValues.join(',')
                            );

                            const isLauCodeDuplicityListForAll = getURLSync(
                                "../../../Utils/isLauCodeDuplicityForAllCalls.php?id_project=" + qs.id_project + "&lauCodes=" + lauCodesValues.join(',')
                            );

                            if (isLauCodeDuplicityList !== "-1" || isLauCodeDuplicityListForAll !== "-1") {
                                const list = JSON.parse(isLauCodeDuplicityList);
                                const listAll = JSON.parse(isLauCodeDuplicityListForAll);
                                // no duplicities
                                if (list && list.length === 0 && listAll && listAll.length === 0) {
                                    console.log(
                                        "Try to check LAUS duplicity after submitting ... CONTINUE"
                                    );
                                    showLoading();
                                    return;
                                }

                                event.preventDefault();
                                event.stopPropagation();

                                // duplicity v ramci callu
                                if (list && list.length !== 0) {
                                    console.log(
                                        "Try to check LAUS duplicity after submitting ... FAIL"
                                    );
                                    fillDuplicityModalAndShow(list, null);
                                    return;
                                }

                                // duplicity v ramci vsech callu
                                if (listAll && listAll.length !== 0) {
                                    console.log(
                                        "Try to check LAUS duplicity for all after submitting ... FAIL"
                                    );
                                    fillDuplicityModalAndShow(listAll, "aaaaa");
                                    return;
                                }
                            }

                            event.preventDefault();
                            event.stopPropagation();
                            console.log(
                                "Duplicity checking error, please contact administrator."
                            );
                            Toast.showError(
                                "Duplicity checking error, please contact administrator."
                            );
                            return;
                        }

                        if (this.submited === "reallySave" || this.submited === "mustContinue") {
                            showLoading();
                            return;
                        }

                        const isSubmit = this.submited === "onlySubmit" || (this.hidden_is_post && this.hidden_is_post.value === "reallySubmit");
                        const customValidity2 = customFormValidity2(form, true);
                        const formValidity = form.checkValidity();
                        const customValidity = customFormValidity();
                        // neni validni
                        if (formValidity === false || customValidity === false || customValidity2 === false) {
                            event.preventDefault();
                            event.stopPropagation();

                            // neni validni, ale jeste potrebujeme check duplicity LAUS
                            const typeOfApplicant = document.getElementById("type_of_applicant").value;
                            const duplicityText = typeOfTheApplicant === 'local' ? checkDuplicityAndReturnText() : "";
                            $("#validationFailedDialog .modal-body #modal-content").html("");
                            $("#validationFailedDialog .modal-body #modal-validation-result").html("");

                            if (formValidity === false || customValidity === false || customValidity2 === false) {
                                $("#validationFailedDialog .modal-body #modal-validation-result").html("The Application form is not completed. Please check the items marked in red.");
                            }

                            if (duplicityText) {
                                $("#validationFailedDialog .modal-body #modal-content").html("One (or more) of the provided LAU codes corresponds to a municipality/local authority that has already been selected for EUCF support. Municipalities/local authorities are able to benefit only once from the support provided by the EUCF. The application cannot be submitted.<br /><br />" + duplicityText);
                            }

                            $("#validationFailedDialog").modal();
                        } else {
                            if (isSubmit) {
                                // test if call is open
                                const query = window.location.search.substring(1);
                                const qs = parse_query_string(query);
                                const isCallOpen = getURLSync(
                                    "../../../Utils/isCallOpen.php?id_project=" + qs.id_project
                                );
                                if (isCallOpen !== "1") {
                                    console.log("Try to submitting project for closed call!!!");
                                    Toast.showError("Call is already closed!");
                                    event.preventDefault();
                                    event.stopPropagation();
                                    return;
                                }
                                console.log(
                                    "Call for " + qs.id_project + " is open, proceed..."
                                );

                                console.log("Try to check LAUS duplicity after submitting ...");
                                const lauCodes = document.getElementsByName("lauCode[]");
                                const typeOfApplicant = document.getElementById("type_of_applicant").value;
                                if (typeOfApplicant === "public") {
                                    console.log(
                                        "CHECKING Tax number duplicity after submitting ... PUBLIC ENTITY"
                                    );

                                    const canProceed = checkTaxNumberDuplicity(qs.id_project);
                                    if (!canProceed) {
                                        event.preventDefault();
                                        event.stopPropagation();
                                        console.log(
                                            "Try to check LAUS duplicity after submitting ... FAIL"
                                        );
                                    } else {
                                        // uspesny submit
                                        event.preventDefault();
                                        event.stopPropagation();

                                        document.getElementById(
                                            "submitConfirmationText"
                                        ).textContent =
                                            "Do you really want to submit the application";
                                        $("#submitConfirmation #project_text").show();
                                        $("#submitConfirmation").modal();

                                        if (form && (this.hidden_is_post && this.hidden_is_post.value === "reallySubmit")) {
                                            form.submit();
                                        }
                                    }

                                    return;
                                }

                                if (!lauCodes || lauCodes.length === 0) {
                                    Toast.showError("No LAU and NUTS 3 code of the municipality/local authority provided, can not continue.");
                                    event.preventDefault();
                                    event.stopPropagation();
                                    return;
                                }

                                const lauCodesValues = [];
                                if (lauCodes) {
                                    for (let i = 0; i < lauCodes.length; i++) {
                                        lauCodesValues.push(lauCodes[i].value);
                                    }
                                }
                                // kontrola duplicit
                                const isLauCodeDuplicityList = getURLSync(
                                    "../../../Utils/isLauCodeDuplicity.php?id_project=" +
                                    qs.id_project + "&lauCodes=" + lauCodesValues.join(',')
                                );
                                const isLauCodeDuplicityListForAll = getURLSync(
                                    "../../../Utils/isLauCodeDuplicityForAllCalls.php?id_project=" + qs.id_project + "&lauCodes=" + lauCodesValues.join(',')
                                );

                                if (isLauCodeDuplicityList === "-1" || isLauCodeDuplicityListForAll === "-1") {
                                    event.preventDefault();
                                    event.stopPropagation();
                                    console.log(
                                        "Duplicity checking error, please contact administrator."
                                    );
                                    Toast.showError(
                                        "Duplicity checking error, please contact administrator."
                                    );
                                    return;
                                }

                                const list = JSON.parse(isLauCodeDuplicityList);
                                const listAll = JSON.parse(isLauCodeDuplicityListForAll);

                                // no duplicities
                                if (list && list.length === 0 && listAll && listAll.length === 0) {
                                    // uspesny submit
                                    event.preventDefault();
                                    event.stopPropagation();
                                    console.log(
                                        "Try to check LAUS duplicity after submitting ... CONTINUE"
                                    );

                                    document.getElementById(
                                        "submitConfirmationText"
                                    ).textContent =
                                        "Do you really want to submit the application";
                                    $("#submitConfirmation #project_text").show();
                                    $("#submitConfirmation").modal();

                                    if (form && (this.hidden_is_post && this.hidden_is_post.value === "reallySubmit")) {
                                        form.submit();
                                    }
                                    return;
                                }

                                event.preventDefault();
                                event.stopPropagation();
                                console.log(
                                    "Try to check LAUS duplicity after submitting ... FAIL"
                                );
                                // schovame potvrzeni o submitu
                                const modalWindow = $('#submitConfirmation');
                                if (modalWindow && modalWindow.length > 0) {
                                    modalWindow.modal('hide');
                                }

                                if (list && list.length > 0) {
                                    fillDuplicityModalAndShowNoContinue(list, null);
                                }

                                if (listAll && listAll.length > 0) {
                                    fillDuplicityModalAndShowNoContinue(listAll, "aaaa");
                                }

                                return;
                            } else {
                                showLoading();
                            }
                        }
                        form.classList.add("was-validated");
                    },
                    false
                );
            });
        },
        false
    );
})();

function checkDuplicityAndReturnText() {
    const lauCodes = document.getElementsByName("lauCode[]");
    if (!lauCodes || lauCodes.length === 0) { // nothing to check
        return "";
    }

    const lauCodesValues = [];
    if (lauCodes) {
        for (let i = 0; i < lauCodes.length; i++) {
            lauCodesValues.push(lauCodes[i].value);
        }
    }

    const isLauCodeDuplicityList = getURLSync(
        "../../../Utils/isLauCodeDuplicity.php?id_project=" + idProject + "&lauCodes=" + lauCodesValues.join(',')
    );

    const isLauCodeDuplicityListForAll = getURLSync(
        "../../../Utils/isLauCodeDuplicityForAllCalls.php?id_project=" + idProject + "&lauCodes=" + lauCodesValues.join(',')
    );

    if (isLauCodeDuplicityList !== "-1" || isLauCodeDuplicityListForAll !== "-1") {
        const list = JSON.parse(isLauCodeDuplicityList);
        const listAll = JSON.parse(isLauCodeDuplicityListForAll);
        // no duplicities
        if (list && list.length === 0 && listAll && listAll.length === 0) {
            console.log(
                "Try to check LAUS duplicity after validating ... CONTINUE"
            );
            return "";
        }

        // duplicity v ramci callu
        if (list && list.length !== 0) {
            console.log(
                "Try to check LAUS duplicity after validating ... FAIL"
            );
            return getDuplicityText(list);
        }

        // duplicity v ramci vsech callu
        if (listAll && listAll.length !== 0) {
            console.log(
                "Try to check LAUS duplicity for all after validating ... FAIL"
            );
            return getDuplicityText(listAll);
        }
    }
}

function loadDuplicitiesForAllAndShowDialog(lauCode, id_project) {
    const isLauCodeDuplicityListForAll = getURLSync(
        "../../../Utils/isLauCodeDuplicityForAllCalls.php?id_project=" + id_project + "&lauCodes=" + lauCode
    );

    if (isLauCodeDuplicityListForAll === "-1") {
        console.log(
            "Duplicity checking error, please contact administrator."
        );
        Toast.showError(
            "Duplicity checking error, please contact administrator."
        );

        return;
    }

    const listAll = JSON.parse(isLauCodeDuplicityListForAll);
    // no duplicities
    if (listAll && listAll.length === 0) {
        console.log(
            "Try to check LAUS duplicity after city change ... CONTINUE"
        );

        return;
    }

    if (listAll && listAll.length > 0) {
        fillDuplicityModalOnCityChangeAndShow(listAll);
    }
}

function fillCanvasBackgroundWithColor(canvas, color) {
    // Get the 2D drawing context from the provided canvas.
    const context = canvas.getContext("2d");

    // We're going to modify the context state, so it's
    // good practice to save the current state first.
    context.save();

    // Normally when you draw on a canvas, the new drawing
    // covers up any previous drawing it overlaps. This is
    // because the default `globalCompositeOperation` is
    // 'source-over'. By changing this to 'destination-over',
    // our new drawing goes behind the existing drawing. This
    // is desirable so we can fill the background, while leaving
    // the chart and any other existing drawing intact.
    // Learn more about `globalCompositeOperation` here:
    // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation
    context.globalCompositeOperation = "destination-over";

    // Fill in the background. We do this by drawing a rectangle
    // filling the entire canvas, using the provided color.
    context.fillStyle = color;
    context.fillRect(0, 0, canvas.width, canvas.height);

    // Restore the original context state from `context.save()`
    context.restore();
}

$(document).on("click", ".btn-download-graph", function () {
    const graphId = this.attributes["data-target-id"].value;
    const canvas = document.getElementById(graphId);
    fillCanvasBackgroundWithColor(canvas, "white");
    this.href = canvas.toDataURL("image/png");
});

$(document).on("change", ".with-radio", function (e) {
    $(this).parent().next(".main-sector-radio").prop('disabled', !e.target.checked);
});


function validateWholeNumbers(evt) {
    evt = evt ? evt : window.event;
    const charCode = evt.which ? evt.which : evt.keyCode;
    if (charCode > 31 && (charCode < 48 || charCode > 57)) {
        return false;
    }
    return true;
}

function validateWholeNumbersCanNegative(el, evt) {
    evt = evt ? evt : window.event;
    const charCode = evt.which ? evt.which : evt.keyCode;
    if (charCode > 31 && (charCode < 48 || charCode > 57) && charCode !== 45) {
        return false;
    }

    const number = el.value.split("-");
    //just one negative sign
    if (number.length > 1 && charCode === 45) {
        return false;
    }

    //get the carat position
    const caratPos = getSelectionStart(el);
    if (charCode === 45 && caratPos) {
        return false;
    }

    return true;
}

function validateFloatKeyPress(el, evt) {
    const charCode = evt.which ? evt.which : event.keyCode;
    const number = el.value.split(".");
    if (charCode != 46 && charCode > 31 && (charCode < 48 || charCode > 57)) {
        return false;
    }
    //just one dot
    if (number.length > 1 && charCode == 46) {
        return false;
    }

    // override na pocet desetinnych mist
    const decimals = el.attributes.getNamedItem("data-decimal-length");
    let numberOfDecimals = 2; // 3 desetinna mista
    if (decimals) {
        const numberOfDecimalsValue = decimals.value;
        if (numberOfDecimalsValue) {
            numberOfDecimals = parseInt(numberOfDecimalsValue) - 1;
        }
    }


    //get the carat position
    const caratPos = getSelectionStart(el);
    const dotPos = el.value.indexOf(".");
    if (caratPos > dotPos && dotPos > -1 && number[1].length > numberOfDecimals) {
        return false;
    }
    return true;
}

//thanks: http://javascript.nwbox.com/cursor_position/
function getSelectionStart(o) {
    if (o.createTextRange && document.selection) {
        const r = document.selection.createRange().duplicate();
        r.moveEnd("character", o.value.length);
        if (r.text == "") return o.value.length;
        return o.value.lastIndexOf(r.text);
    } else return o.selectionStart;
}

$(document).on("blur", "input.whole-number", function () {
    //apply formatting
    this.value = this.value.toString().replace(/[^0-9]/g, "").replace(/\B(?=(\d{3})+(?!\d))/g, " ");
});

function formatWholeNumber(value) {
    return (value ?? 0).toString().replace(/[^0-9]/g, "").replace(/\B(?=(\d{3})+(?!\d))/g, " ");
}

function formatDecimalNumber(value) {
    return removeAllButLast((value ?? 0).toString().replace(/[^0-9.]/g, ""), ".").replace(/\B(?=(\d{3})+(?!\d))/g, " ");
}

$(document).on("focus", "input.whole-number", function () {
    //apply formatting
    this.value = this.value.toString().replace(/ /g, "");
});

$(document).on("blur", "input.whole-number-can-negative", function () {
    //apply formatting
    this.value = this.value.toString().replace(/[^0-9-]/g, "").replace(/\B(?=(\d{3})+(?!\d))/g, " ");
});

$(document).on("focus", "input.whole-number-can-negative", function () {
    //apply formatting
    this.value = this.value.toString().replace(/ /g, "");
});


function removeAllButLast(string, token) {
    const parts = string.split(token);
    if (parts[1] === undefined)
        return string;
    else
        return parts.slice(0, -1).join('') + token + parts.slice(-1)
}

$(document).on("blur", "input.decimal-numbers.with-formatting", function () {
    //apply formatting
    this.value = removeAllButLast(this.value.toString().replace(/[^0-9.]/g, ""), ".").replace(/\B(?=(\d{3})+(?!\d))/g, " ");
});

$(document).on("focus", "input.decimal-numbers.with-formatting", function () {
    //apply formatting
    this.value = this.value.toString().replace(/ /g, "");
});

function clearNumericValue(value) {
    if (value == null || value == "") {
        return value;
    }

    return value.toString().replace(/ /g, "");
}

$(document).on("input", "input.decimal-numbers", function (e) {
    let clean = this.value.replace(/[^0-9.]/g, "");
    if (clean.split(".").length > 2) {
        clean = clean.replace(/\.+$/, "");
    }
    // test to max value
    const maxAttr = this.attributes.getNamedItem("max");
    const stepAttr = this.attributes.getNamedItem("step");
    const allowStepData = this.attributes.getNamedItem("data-allow-step");

    if (maxAttr) {
        const maxValue = maxAttr.value;
        if (maxValue) {
            if (clean > parseFloat(maxValue)) {
                this.value = maxValue;
                return;
            } else {
                if (stepAttr && allowStepData && clean) {
                    const stepValue = parseFloat(stepAttr.value);
                    if (stepValue) {
                        const result = parseFloat(clean) / stepValue;
                        if (!Number.isInteger(result)) {
                            this.value = (Math.round(parseFloat(clean) / stepValue) * stepValue).toFixed(1);
                            return;
                        }
                    }
                }
            }
        }
    }

    // don't move cursor to end if no change
    if (clean !== this.value) this.value = clean;
});

function format_whole_number(value) {
    return removeAllButLast(value.toString().replace(/[^0-9.]/g, ""), ".").replace(/\B(?=(\d{3})+(?!\d))/g, " ");
}

var pfx = ["webkit", "moz", "ms", "o", ""];

function RunPrefixMethod(obj, method) {
    var p = 0,
        m,
        t;
    while (p < pfx.length && !obj[m]) {
        m = method;
        if (pfx[p] == "") {
            m = m.substr(0, 1).toLowerCase() + m.substr(1);
        }
        m = pfx[p] + m;
        t = typeof obj[m];
        if (t != "undefined") {
            pfx = [pfx[p]];
            return t == "function" ? obj[m]() : obj[m];
        }
        p++;
    }
}

$(document).on("dblclick", ".chart-body", function () {
    const e = document.getElementById(this.id);
    if (
        RunPrefixMethod(document, "FullScreen") ||
        RunPrefixMethod(document, "IsFullScreen")
    ) {
        RunPrefixMethod(document, "CancelFullScreen");
    } else {
        RunPrefixMethod(e, "RequestFullScreen");
    }
});

function clearAttachment(inputId, hiddenInputId) {
    if (!confirm("Are you sure to remove this file?")) {
        return;
    }

    $("input[type=file]#" + inputId).val('');
    const fileInput = document.querySelector("input[type=file]#" + inputId);
    if (fileInput) {
        fileInput.files = null;
        fileInput.value = '';
        fileInput.removeAttribute('value');
        fileInput.setAttribute("required", "required");
    }

    const fileName = document.getElementById("filename_" + inputId);
    if (fileName) {
        fileName.innerHTML = "";
    }

    const fileHiddenInput = document.getElementById("f_" + inputId);
    if (fileHiddenInput) {
        fileHiddenInput.value = "";
    }

    if (hiddenInputId) {
        const fileHiddenInput2 = document.querySelector("input[name='f_" + hiddenInputId + "']");
        if (fileHiddenInput2) {
            fileHiddenInput2.value = "";
        }
    }
}

const randomColorGenerator = function () {
    return "#" + (Math.random().toString(16) + "0000000").slice(2, 8);
};

function checkVisible(elm, evalType) {
    evalType = evalType || "visible";

    const vpH = $(window).height(), // Viewport Height
        st = $(window).scrollTop(), // Scroll Top
        y = $(elm).offset().top,
        elementHeight = $(elm).height();

    // console.log('vpH:', vpH, 'st:', st,'y:', y, 'elementHeight:',elementHeight )

    if (evalType === "visible") return ((y < (vpH + st)) && (y > (st - elementHeight)));
    if (evalType === "above") return ((y < (vpH + st)));
}

function stickButtonTuBottom() {
    const footers = document.getElementsByTagName("footer");
    if (footers.length === 0) {
        return;
    }
    const footer = footers[0];
    const isVisible = checkVisible(footer);
    const floats = document.getElementsByClassName("float-bottom");
    if (floats.length === 0) {
        return;
    }
    const float = floats[0];
    if (!isVisible) {
        float.style.bottom = 0;

        return;
    }
    const b = $(window).height();
    const offset = Math.max(b - footer.getBoundingClientRect().y, 0);
    float.style.bottom = offset + "px";
}

window.onscroll = function () {
    stickButtonTuBottom();
};

function copyOrReplaceDown(sourceElem, targetId) {
    let targetText = document.getElementById(targetId).value;
    const newText = $(sourceElem)[0].innerHTML;

    // jeste tam neni
    if (targetText.indexOf(newText) === -1) {
        document.getElementById(targetId).value += (targetText ? "\n" : "") + newText;
    }
}

function copyOrReplaceText(newText, targetId) {
    let targetText = document.getElementById(targetId).value;

    // jeste tam neni
    if (targetText.indexOf(newText) === -1) {
        document.getElementById(targetId).value += (targetText ? "\n" : "") + newText;
    }
}

function copyDown(sourceElem, targetId) {
    document.getElementById(targetId).value = $(sourceElem)[0].innerHTML;
}

function clearTextareaById(targetId) {
    document.getElementById(targetId).value = "";
    document.getElementById(targetId).removeAttribute("required");
}

function clearRequiredById(targetId) {
    if (document.getElementById(targetId)) {
        document.getElementById(targetId).removeAttribute("required");
    }
}

function clearRequiredByElem(elem) {
    if (elem) {
        elem.removeAttribute("required");
    }
}

function setRequiredById(targetId) {
    if (document.getElementById(targetId)) {
        document.getElementById(targetId).setAttribute("required", "");
    }
}

function setRequiredByElem(elem) {
    if (elem) {
        elem.setAttribute("required", "");
    }
}

function setCustomRequiredByName(targetName) {
    const elems = document.getElementsByName(targetName);
    if (elems.length > 0) {
        for (let i = 0; i < elems.length; i++) {
            elems[i].classList.remove('custom-form-check-required-one-input');
            elems[i].classList.add('custom-form-check-required-one-input');
        }
    }
}

function clearCustomRequiredByName(targetName) {
    const elems = document.getElementsByName(targetName);
    if (elems.length > 0) {
        for (let i = 0; i < elems.length; i++) {
            elems[i].classList.remove('custom-form-check-required-one-input');
        }
    }
}

function setRequiredByIdAndChecked(targetId, chb) {
    if (chb.checked) {
        document.getElementById(targetId).setAttribute("required", "");
    } else {
        document.getElementById(targetId).removeAttribute("required");
    }
}

var nuts3cities = {};

function calculateFundingSums(targetId, originalValue, setSumValue) {
    setSumValue = (setSumValue === undefined) ? true : setSumValue;
    const values = document.querySelectorAll("input.ic-dev-calc-value");
    let sum = 0;
    // nejdrive suma
    for (let i = 0; i < values.length; i++) {
        const elem = values[i];
        if (elem.value == null || elem.value == "") {
            $("#" + elem.id + "_value").val("");
            continue;
        }

        sum += parseFloat(clearNumericValue(elem.value));
    }

    if (setSumValue) {
        $("#" + targetId).val(sum);
    }

    // v druhem pruchodu procenta
    for (let i = 0; i < values.length; i++) {
        const elem = values[i];
        if (elem.value == null || elem.value == "") {
            continue;
        }

        $("#" + elem.id + "_value").val(parseInt(((parseFloat(clearNumericValue(elem.value)) / sum)) * 100));
    }

    createHolders(targetId, originalValue, sum);
}


function calculateRowPercentage(parents) {
    if (!parents || parents.length === 0) {
        return;
    }

    let row = parents[0];
    let leftElem = row.querySelector('.percent-left');
    let rightElem = row.querySelector('.percent-right');
    let percentElem = row.querySelector('.mon-percent');

    if (!leftElem) {
        return;
    }

    let leftValue = clearNumericValue(leftElem.value);
    let rightValue = clearNumericValue(rightElem.value);

    if (leftValue != "" && rightValue != "" && rightValue != 0) {
        leftValue = parseFloat(leftValue);
        rightValue = parseFloat(rightValue);

        const percent = leftValue / (leftValue + rightValue);
        percentElem.value = parseFloat((percent) * 100).toFixed(2);
    } else {
        percentElem.value = "--";
    }

    // total hodnoty
    let sumLeft = 0;
    let sumRight = 0;
    let sumPercent = 0;
    const rows = row.parentNode.children;
    let sumRow = null;
    for (let i = 1; i < rows.length; i++) {
        row = rows[i];

        let leftElem = row.querySelector('.percent-left');
        let rightElem = row.querySelector('.percent-right');
        let percentElem = row.querySelector('.mon-percent');

        if (leftElem.id === 'total_secured') {
            sumRow = row;
            continue;
        }

        let leftValue = clearNumericValue(leftElem.value);
        let rightValue = clearNumericValue(rightElem.value);
        let percentValue = clearNumericValue(percentElem.value);

        if (leftValue != "") {
            sumLeft += parseFloat(leftValue);
        }

        if (rightValue != "") {
            sumRight += parseFloat(rightValue);
        }

        if (percentValue != "" && percentValue != "--") {
            sumPercent += parseFloat(percentValue);
        }
    }

    document.getElementById('total_investment_secured').value = "";
    if (sumLeft != null && sumLeft != "") {
        document.getElementById('total_investment_secured').value = sumLeft.toString().replace(/[^0-9]/g, "").replace(/\B(?=(\d{3})+(?!\d))/g, " ");
    }

    document.getElementById('total_investment_planned').value = "";
    if (sumRight != null && sumRight != "") {
        document.getElementById('total_investment_planned').value = sumRight.toString().replace(/[^0-9]/g, "").replace(/\B(?=(\d{3})+(?!\d))/g, " ");
    }

    if (sumRow) {
        sumRow.querySelector('.percent-left').value = sumLeft;
        sumRow.querySelector('.percent-right').value = sumRight;

        if (sumLeft === 0 || sumRight === 0) {
            sumRow.querySelector('.mon-percent').value = "--";
            return;
        }

        const percent = sumLeft / (sumLeft + sumRight);
        sumRow.querySelector('.mon-percent').value = parseFloat((percent) * 100).toFixed(2);
        ;
    }

}

function createHolders(targetId, originalValue, sum, afterField, threshold) {
    originalValue = originalValue != null && originalValue !== '' && originalValue !== 0
        ? parseFloat(originalValue) : 0;
    sum = sum != null && sum !== '' && sum !== 0
        ? parseFloat(sum) : 0;
    // odchylky
    const odchylka = originalValue != 0
        ? parseFloat(((sum / originalValue) - 1) * 100).toFixed(2)
        : 0;

    console.log("ODCHYLKA-" + targetId + ":: originalValue=" + originalValue + ", actualValue=" + sum);

    let tooltip = '';
    let tooltip2 = '';
    if (targetId === 'total_investment_planned') {
        tooltip = 'Original Application investment value';
        tooltip2 = 'Percentage investment variance';
    }

    if (targetId === 'energy_savings') {
        tooltip = 'Original Application energy savings value';
        tooltip2 = 'Percentage energy savings variance';
    }

    if (targetId === 'renewable_energy') {
        tooltip = 'Original Application renewable energy production value';
        tooltip2 = 'Percentage renewable energy production variance';
    }

    let addClass = "";
    if (afterField === 'tisId') {
        addClass = " mt-46 ";
    }

    if (!threshold) {
        threshold = 10;
    }

    let holdersOdchylka = $("#" + targetId).parent().find('.input-group-append.indicators.odchylka');
    if (holdersOdchylka.length === 0 && afterField) {
        holdersOdchylka = $("#" + targetId).parents(".accordion-group").find('.input-group-append.indicators.odchylka.' + afterField);
    }
    const errorClass = odchylka < -threshold || odchylka > threshold ? "error" : '';
    const tooltipAppend = odchylka < -threshold || odchylka > threshold ? " There is a significant difference between original value provided in the application and the value provided in investment concept. Please justify reasons for the difference in the lessons learned section below in the form" : '';
    tooltip2 += tooltipAppend;
    const holderOdchylka = holdersOdchylka.length === 0 ? createHolder(odchylka, 'odchylka indicators ' + errorClass + ' ' + afterField + addClass, tooltip2, $("#" + targetId), afterField) : holdersOdchylka[0];
    updateHolder(holderOdchylka, odchylka, errorClass, tooltip2, "%");

    let holdersOriginalValue = $("#" + targetId).parent().find('.input-group-append.indicators.originalValue');
    if (holdersOriginalValue.length === 0 && afterField) {
        holdersOriginalValue = $("#" + targetId).parents(".accordion-group").find('.input-group-append.indicators.originalValue.' + afterField);
    }
    const holderOriginalValue = holdersOriginalValue.length === 0 ? createHolder(originalValue, 'originalValue indicators ' + afterField + addClass, tooltip, $("#" + targetId), afterField) : holdersOriginalValue[0];
    updateHolder(holderOriginalValue, originalValue, '', tooltip, '');

    return odchylka;
}

function createHolder(value, clazz, tooltip, textbox, afterField) {
    const tmp = $('<div class="input-group-append ' + clazz + '" title="' + tooltip + '"><div class="input-group-text">' + value + '</div></div>');
    if (afterField) {
        textbox.parent().after(tmp);
    } else {
        textbox.after(tmp);
    }

    return tmp;
}

function updateHolder(holder, value, errorClass, tooltip, units) {
    holder = holder.length ? holder[0] : holder;

    value = value != null && value != '' && value.toString().indexOf('.') === -1
        ? parseFloat(value).toString().replace(/[^0-9]/g, "").replace(/\B(?=(\d{3})+(?!\d))/g, " ") : value;

    holder.firstElementChild.textContent = (value == null || value == '' ? '--' : value) + units;
    holder.classList.remove('error');

    if (errorClass) {
        holder.classList.add(errorClass);
    }

    holder.tooltip = tooltip;
}

function setEnergySavingsAndRenewEnergy(energySavingsOriginal, energySavings, renewableEnergyOriginal, renewableEnergy) {
    energySavingsOriginal = energySavingsOriginal | 0;
    renewableEnergyOriginal = renewableEnergyOriginal | 0;
    energySavings = energySavings | 0;
    renewableEnergy = renewableEnergy | 0;

    $("#energy_savings_renewable_energy").val((energySavings + renewableEnergy).toString().replace(/[^0-9]/g, "").replace(/\B(?=(\d{3})+(?!\d))/g, " "));
    createHolders('energy_savings_renewable_energy', energySavingsOriginal + renewableEnergyOriginal, energySavings + renewableEnergy);
}

function calculateNPV(totalInvestment, discountRate, lifetimePeriod, totalRevenue, totalOperationCost) {
    totalInvestment = totalInvestment | 0;
    discountRate = +discountRate;
    lifetimePeriod = lifetimePeriod | 0;
    totalRevenue = totalRevenue | 0;
    totalOperationCost = totalOperationCost | 0;

    let sum = 0;
    for (let j = 0; j < lifetimePeriod; j++) {

        let values = 0;
        if (j === 0) {
            values = totalInvestment * (-1);
        } else {
            values = totalRevenue - totalOperationCost;
        }

        sum += (values / (Math.pow((1 + discountRate), j)));
    }

    sum = sum.toFixed(2) | "--";

    console.log("NPV:: totalInvestment=" + totalInvestment + ", discountRate=" + discountRate + ", lifetimePeriod=" + lifetimePeriod +
        ", totalRevenue=" + totalRevenue + ", totalOperationCost=" + totalOperationCost);

    const holdersNPV = $("#net_present_value").parent().find('.input-group-append.indicators.npv');
    const tooltip = 'Suggested computed NPV';
    const holderNPV = holdersNPV.length === 0 ? createHolder(sum, 'npv indicators ', tooltip, $("#net_present_value")) : holdersNPV[0];
    updateHolder(holderNPV, sum, '', tooltip, "");

}

function sumIntValues(values) {
    if (!values || values.length === 0) {
        return 0;
    }

    let sum = 0;
    for (let i = 0; i < values.length; i++) {
        const value = values[i];
        if (value == null || value == "") {
            continue;
        }
        sum += parseInt(clearNumericValue(value));
    }

    return sum;
}

function calculateSectionSum(targetId, elements) {
    let sum = 0;
    for (let i = 0; i < elements.length; i++) {
        if (!elements[i].checked || !elements[i].attributes['data-count-value']) {
            continue;
        }
        const val = elements[i].attributes['data-count-value'].value;
        sum = sum + parseFloat(val);
    }

    const sumBackup = sum;
    try {
        sum = sum.toFixed(3);
    } catch (e) {
        sum = sumBackup;
    }
    document.getElementById(targetId).classList.remove('color-red-i');
    document.getElementById(targetId).value = sum;
    document.getElementById('crit' + targetId.replace("criterion", "")).value = sum;

    const maxScore = {};
    maxScore['criterion1'] = 7.0;
    maxScore['criterion2'] = 5.0;
    maxScore['criterion3'] = 5.0;
    maxScore['criterion4'] = 3.0;
    if ((sum) < (maxScore[targetId] / 2)) {
        document.getElementById(targetId).classList.add('color-red-i');
    }

    return sum;
}

function getFloatValueOrDefault(value, defaultVal) {
    if (value == null || value == "") {
        return defaultVal;
    }

    try {
        return parseFloat(value);
    } catch (e) {
        return defaultVal;
    }
}

function setState(chb, inputId) {
    $('#' + inputId).prop('disabled', chb.checked);

}
