/*
This file is part of SystemTestPortal.
Copyright (C) 2018  Institute of Software Technology, University of Stuttgart

SystemTestPortal is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

SystemTestPortal is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with SystemTestPortal.  If not, see <http://www.gnu.org/licenses/>.
*/

// selectedVersion is the name of the currently selected version
var selectedVersion = "";
//selectedVersionID is the ID of the currently selected version
var selectedVersionID = "";

var nextSelectedVersion = "";
var nextSelectedVersionID = "";

//project version data
var projectVariantData;
var urlVariants = getProjectURL().appendSegment("versions").toString();
var versionIdCounter = 0;
var variantIdCounter = 0;
var variantEditinglist = [];
var isNewSuTVersion = true;
var tempSuTData;
var oldVariantList = [];

var unsavedChanges = false;
//jquery
var inputProjectVersionField = $("#inputProjectVersionName");
var inputProjectVariantField = $("#inputProjectVariant");

var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
    if (this.readyState === 4 && this.status === 200) {
        projectVariantData = JSON.parse(this.responseText);
        resetTempVersionData();
        fillModalVersions(projectVariantData, "#projectVersionList");
    }
};
xmlhttp.open("GET", urlVariants, true);
xmlhttp.send();
//--------------------------------------------------------------------------|
// Listeners--|
//--------------------------------------------------------------------------|

/* Adds a on click listener apply button in the unsavedChangesVersionModal*/
$("#buttonApplyVersionChangesClosing").on("click", function () {
    resetSuTVersionModalValidity("inputProjectVersionName");
    resetSuTVersionModalValidity("inputProjectVariant");
    if (versionNameIsValid() && variantNamesAreValid()) {
        let versionNameInput = $("#inputProjectVersionName").val().trim();
        saveVersions(selectedVersion, tempSuTData, variantEditinglist, versionNameInput, selectedVersionID);
        variantEditinglist = [];
        $("#unsavedChangesVersionModal").modal("hide");
        newVersionReset();
        $("#modal-manage-versions").modal("hide");
    } else {
        $("#unsavedChangesVersionModal").modal("hide");
    }
});

/* Adds a on click listener discard button in the unsavedChangesVersionModal*/
$("#buttonDiscardVersionChangesClosing").on("click", function () {
    unsavedChanges = false;
    $("#unsavedChangesVersionModalClosing").modal("hide");
    if (selectedVersion !== "") {
        projectVariantData[selectedVersion].Variants = oldVariantList.slice(0);
    }
    newVersionReset();
    $("#modal-manage-versions").modal("hide");
});

/* Adds a on click listener apply button in the unsavedChangesVersionModalSwitching*/
$("#buttonApplyVersionChangesSwitching").on("click", function () {
    resetSuTVersionModalValidity("inputProjectVersionName");
    resetSuTVersionModalValidity("inputProjectVariant");
    if (versionNameIsValid() && variantNamesAreValid()) {
        let versionNameInput = $("#inputProjectVersionName").val().trim();
        saveVersions(selectedVersion, tempSuTData, variantEditinglist, versionNameInput, selectedVersionID);
        variantEditinglist = [];
        $("#unsavedChangesVersionModalSwitching").modal("hide");
        if (nextSelectedVersion !== "" && nextSelectedVersionID !== "") {
            versionSelected(nextSelectedVersionID, nextSelectedVersion);
        } else {
            newVersionReset();
        }
    } else {
        $("#unsavedChangesVersionModalSwitching").modal("hide");
    }
});

/* Adds a on click listener discard button in the unsavedChangesVersionModalSwitching*/
$("#buttonDiscardVersionChangesSwitching").on("click", function () {
    unsavedChanges = false;
    if (selectedVersion !== "") {
        projectVariantData[selectedVersion].Variants = oldVariantList.slice(0);
    }
    $("#unsavedChangesVersionModalSwitching").modal("hide");
    if (nextSelectedVersion !== "" && nextSelectedVersionID !== "") {
        versionSelected(nextSelectedVersionID, nextSelectedVersion);
    } else {
        newVersionReset();
    }
});

/* Adds a on click listener to the bottom right close button*/
$("#bottomButtonCloseManageVersionsModal").on("click", function () {
    if (unsavedChanges) {
        $("#unsavedChangesVersionModal").modal("show");
    } else {
        newVersionReset();
        $("#modal-manage-versions").modal("hide")
    }
});

/* Adds a on click listener for the top right close button*/
$("#topButtonCloseManageVersionsModal").on("click", function () {
    newVersionReset();
    if (unsavedChanges) {
        $("#unsavedChangesVersionModal").modal("show")
    } else {
        newVersionReset();
        $("#modal-manage-versions").modal("hide")
    }
});

/* Adds a on change listener to the project variant input field*/
inputProjectVariantField.change(function () {

    let variantNameInput = $("#inputProjectVariant");
    resetSuTVersionModalValidity("inputProjectVariant");
    if (!checkSuTVersionModalValidity("inputProjectVariant")) {
        variantNameInput[0].setCustomValidity("Please use letters, numbers or .,:_() .");
        reportSuTVersionModalValidity("inputProjectVariant");

    }
    let variantName = variantNameInput.val().trim();
    if (projectVariantDataContainsVariant(selectedVersion, variantName)) {
        variantNameInput[0].setCustomValidity("Desired name is already taken, please choose another name");
        reportSuTVersionModalValidity("inputProjectVariant");
    }
});

/* Adds a on keydown listener to the project variant input field*/
inputProjectVariantField.on("keydown", function (event) {
    if (event.keyCode === 13) {
        event.preventDefault();
        $("#buttonAddProjectVariant").click();
    }
});

/* Adds a on change listener to the project version input field*/
inputProjectVersionField.change(function () {
    unsavedChanges = true;
    resetSuTVersionModalValidity("inputProjectVersionName");
    versionNameIsValid();
});


/* Adds a on keydown listener to the project version input field*/
inputProjectVersionField.on("keydown", function (event) {
    if (event.keyCode === 13) {
        event.preventDefault();
        versionNameIsValid();

        $("#inputProjectVariant").focus();
    }
});

/* Adds a on click listener to the delete confirm button*/
$('#buttonDeleteVersionConfirm').on("click", function () {
    $(".tooltip").hide();
    $('#deleteVersions').modal('hide');
    deleteModalVersion();
});

/* Adds a on click listener to the project variant add button*/
$("#buttonAddProjectVariant").on("click", function () {
    let variantName = $("#inputProjectVariant").val().trim();
    resetSuTVersionModalValidity("inputProjectVariant");
    if (checkSuTVersionModalValidity("inputProjectVariant") && !projectVariantDataContainsVariant(selectedVersion, variantName)) {
        addVariantToProjectVariantDataAndUI(variantName, selectedVersion);
    } else if (projectVariantDataContainsVariant(selectedVersion, variantName)) {
        $("#inputProjectVariant")[0].setCustomValidity("Desired name is already taken, please choose another name");
        reportSuTVersionModalValidity("inputProjectVariant");
    } else {
        $("#inputProjectVariant")[0].setCustomValidity("Please use letters, numbers or .,:_() .");
        reportSuTVersionModalValidity("inputProjectVariant");
    }

});

/* Adds a on click listener to the project version save button*/
$("#buttonSaveVersions").on("click", function () {
    resetSuTVersionModalValidity("inputProjectVersionName");
    resetSuTVersionModalValidity("inputProjectVariant");
    if (versionNameIsValid() && variantNamesAreValid()) {
        let versionNameInput = $("#inputProjectVersionName").val().trim();
        saveVersions(selectedVersion, tempSuTData, variantEditinglist, versionNameInput, selectedVersionID);
        variantEditinglist = [];
    }
});
/* Adds a on click listener to the project version add button*/
$("#buttonAddVersions").on("click", function () {
    let versionNameInput = $("#inputProjectVersionName").val().trim();
    resetSuTVersionModalValidity("inputProjectVersionName");
    resetSuTVersionModalValidity("inputProjectVariant");
    if (versionNameIsValid() && variantNamesAreValid()) {
        saveVersions(selectedVersion, tempSuTData, variantEditinglist, versionNameInput, selectedVersionID);
        variantEditinglist = [];
        if (isNewSuTVersion && checkSuTVersionModalValidity("inputProjectVersionName")) {
            selectedVersion = tempSuTData.Name;
            selectedVersionID = "version-" + (versionIdCounter);
            addModalVersion(tempSuTData, "#projectVersionList");
            versionSelected(selectedVersionID, selectedVersion);
        }
    }
});
/* Adds a on click listener to the new project version button*/
$("#buttonNewProjectVersion").on("click", function () {
    newVersionReset();
});

//--------------------------------------------------------------------------|
// CREATE-----|
//--------------------------------------------------------------------------|

/**
 * Adds a version the the list of versions
 * @param version the version Object
 * @param listID the current listID
 */
function addModalVersion(version, listID) {

    let list = $(listID);

    list.append($("<span></span>")
        .attr("id", "version-" + versionIdCounter)
        .attr("type", "button")
        .attr("class", "btn label-list-btn")
        .attr("data-placement", "left")
        .attr("style", "background-color:#007bff; color: #fff")
        .attr("onclick", "versionSelected('" + "version-" + versionIdCounter + "' ,'" + version.Name + "')")
        .text(version.Name));

    versionIdCounter = versionIdCounter + 1;
}

/**
 * Adds a Variant to the list of Variants. Adds delete buttons with listeners to the list
 * @param variant the variant object ({Name: "VariantXYZ"})
 */
function addVariant(variant) {
    let variantList = $("#projectVariantList");
    variantList.append($("<div></div>")
        .attr("class", "row")
        .attr("id", "row-" + variantIdCounter)
        .html("<div class='col-12'>" +
            "<div class='input-group mb-1'>" +
            "<input style='width: 75%' class='form-control' type='text' pattern=\"[\\sA-Za-z0-9-_().,:äöüÄÖÜß]{1,256}\"\n" +
            "required id='variant-input-id-" + variantIdCounter + "' >" +
            "<span class='input-group-prepend' style='width: 25%'>" +
            "<button style='border-top-right-radius: 0.25rem; border-bottom-right-radius: 0.25rem'" +
            " id='delete-" + variantIdCounter + "' class='btn btn-danger list-line-item btn-sm buttonDeleteVersion'>" +
            "<i class=\"fa fa-trash-o\" aria-hidden=\"true\"></i>" +
            "<span class=\"d-none d-sm-inline\">Delete</span>" +
            "</button>" +
            "</span>" +
            "</div>" +
            "</div>"));
    let inputVariantID = $("#variant-input-id-" + variantIdCounter);
    inputVariantID.val(variant.Name);
    $("#delete-" + variantIdCounter).attr("onClick", "deleteModalVariant('" + variant.Name + "','" + variantIdCounter + "')");
    inputVariantID.attr("onchange", "variantNameChanged('" + variant.Name + "', '" + variantIdCounter + "')");
    variantIdCounter++;
}

/**
 * Adds a Variant to the projectVariantData and adds it to the UI
 * @param variantName the variant Name
 * @param versionName the version name
 */
function addVariantToProjectVariantDataAndUI(variantName, versionName) {
    unsavedChanges = true;
    if (isNewSuTVersion) {
        let variantObject = JSON.parse('{"Name":"' + variantName + '"}');
        tempSuTData.Variants.push(variantObject);
        addVariant(variantObject);
        $("#inputProjectVariant").val("");
    }
    else {
        let variantObject = JSON.parse('{"Name":"' + variantName + '"}');
        projectVariantData[versionName].Variants.push(variantObject);
        addVariant(variantObject);
        $("#inputProjectVariant").val("");
    }
}

/**
 * adds a variant to the projectVariantData
 * @param variantName the variant name
 * @param versionName the version name
 */
function addVariantToProjectVariantData(variantName, versionName) {
    if (isNewSuTVersion) {
        if ((variantName !== "") && !containsVariant({Name: variantName}, tempSuTData.Variants)) {
            let variantObject = JSON.parse('{"Name":"' + variantName + '"}');
            tempSuTData.Variants.push(variantObject);
        }
    } else {
        if ((variantName !== "") && !containsVariant({Name: variantName}, projectVariantData[versionName].Variants)) {
            let variantObject = JSON.parse('{"Name":"' + variantName + '"}');
            projectVariantData[versionName].Variants.push(variantObject);
        }
    }
}

//--------------------------------------------------------------------------|
// Change-----|
//--------------------------------------------------------------------------|

/**
 * updates the UI, resets the variantIdCounter, sets isNewSuTVersion to false
 * and calls populateVariants after a version is selected
 * @param id the selected id
 * @param name the selected version name
 */
function versionSelected(id, name) {
    resetSuTVersionModalValidity("inputProjectVersionName");
    resetSuTVersionModalValidity("inputProjectVariant");
    nextSelectedVersion = name;
    nextSelectedVersionID = id;
    if (unsavedChanges) {
        $("#unsavedChangesVersionModalSwitching").modal("show");
    } else {
        unsavedChanges = false;
        selectedVersionID = id;
        selectedVersion = name;
        $("#buttonSaveVersions").attr("style", "float:inherit;");
        $("#buttonAddVersions").attr("style", "float:inherit; display: none");
        $("#modeVersionApplicabilityNew").attr("style", "display: none");
        $("#modeVersionApplicabilityEdit").attr("style", "");
        $("#inputProjectVersionName").val(name);
        $("#inputProjectVariant").val("");
        $("#" + id).attr("class", "btn label-list-btn");
        $("#projectVariantList").empty();
        variantIdCounter = 0;
        populateVariants(selectedVersion);
        isNewSuTVersion = false;
        $("#buttonDeleteVersion").prop("disabled", false);
        variantEditinglist = [];
        oldVariantList = projectVariantData[selectedVersion].Variants.slice(0);
    }
}

/**
 * reacts to the change of a variant name. Checks whether the new name is a valid one.
 * If the new name is valid it is added to the list of changed variants
 * @param variantName the variant name
 * @param counter the id counter
 */
function variantNameChanged(variantName, counter) {
    unsavedChanges = true;
    let newVariantName = $("#variant-input-id-" + counter).val().trim();
    let oldVariantName = variantName;
    let alreadyExists = false;
    if (projectVariantDataContainsVariant(selectedVersion, newVariantName) && newVariantName !== oldVariantName) {
        $("#variant-input-id-" + counter)[0].setCustomValidity("Desired name is already taken, please choose another name");
        reportSuTVersionModalValidity("variant-input-id-" + counter);

        variantEditinglist.forEach(function (changedVariantEntry, index) {
            if (changedVariantEntry[1] === oldVariantName) {
                variantEditinglist.splice(index, 1);
            }
        });
    } else {
        resetSuTVersionModalValidity("variant-input-id-" + counter);
        if (checkSuTVersionModalValidity("variant-input-id-" + counter)) {
            variantEditinglist.forEach(function (changedVariantEntry, index) {
                if (changedVariantEntry[1] === oldVariantName) {
                    variantEditinglist.splice(index, 1);
                    changedVariantEntry = JSON.parse('["' + selectedVersion + '","' + oldVariantName + '", "' + newVariantName + '", "' + counter + '"]');
                    variantEditinglist.push(changedVariantEntry);
                    alreadyExists = true;
                }
            });
            if (variantName !== newVariantName && !alreadyExists) {
                let changedVariant = JSON.parse('["' + selectedVersion + '","' + oldVariantName + '", "' + newVariantName + '", "' + counter + '"]');
                variantEditinglist.push(changedVariant);
            }
        } else {
            $("#variant-input-id-" + counter)[0].setCustomValidity("'Please use letters, numbers or .,:_() .'");
            reportSuTVersionModalValidity("variant-input-id-" + counter);
        }
    }

}

//--------------------------------------------------------------------------|
// DELETE-----|
//--------------------------------------------------------------------------|

/**
 * Deletes the currently selected version and saves the deletion.
 */
function deleteModalVersion() {
    delete projectVariantData[selectedVersion];
    $("#" + selectedVersionID).remove();
    saveVersionDeletion();
    newVersionReset();
}

/**
 * Deletes a variant from the list of variants of a version
 * @param variantName the variant name
 * @param idNumber the id number
 */
function deleteModalVariant(variantName, idNumber) {
    unsavedChanges = true;
    if (isNewSuTVersion) {
        tempSuTData.Variants.forEach(function (variant, index) {
            if (variant.Name === variantName) {
                tempSuTData.Variants.splice(index, 1);
                $("#row-" + idNumber).remove();
            }
        });
        variantEditinglist.forEach(function (changedVariantEntry, index) {
            if (changedVariantEntry[1] === variantName) {
                variantEditinglist.splice(index, 1);
            }
        });
    } else {
        if (selectedVersion !== "") {
            projectVariantData[selectedVersion].Variants.forEach(function (variant, index) {
                if (variant.Name === variantName) {
                    projectVariantData[selectedVersion].Variants.splice(index, 1);
                    $("#row-" + idNumber).remove();
                }
            });
        }
        variantEditinglist.forEach(function (changedVariantEntry, index) {
            if (changedVariantEntry[1] === variantName) {
                variantEditinglist.splice(index, 1);
            }
        });
    }
}

/**
 * Deletes a variant from a version inside of the projectVariantData
 * @param versionName the version name
 * @param variantName the variant name
 */
function deleteFromProjectVariantData(versionName, variantName) {
    if (versionName !== "") {
        projectVariantData[versionName].Variants.forEach(function (variant, index) {
            if (variant.Name === variantName) {
                projectVariantData[versionName].Variants.splice(index, 1);
            }
        });
    }
}

//--------------------------------------------------------------------------|
// SAVE-----|
//--------------------------------------------------------------------------|

/**
 * saves the deletion of a version
 */
function saveVersionDeletion() {
    let xhr = new XMLHttpRequest();
    xhr.open("POST", urlVariants, true);
    xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
    xhr.send(JSON.stringify(projectVariantData));
    xhr.onloadend = function () {
        if (this.status === 200) {
        } else {
            console.log(this.response);
        }
    };
}

/**
 * saves the version and the variants. calls saveVersionRename.
 * @param selectedVersion the version name
 * @param tempSuTData the tempSuTData
 * @param variantEditingList the variantEditingList
 * @param versionNameInput  the new version name
 */
function saveVersions(selectedVersion, tempSuTData, variantEditingList, versionNameInput, selectedVersionID) {
    unsavedChanges = false;
    if (isNewSuTVersion) {
        selectedVersion = $("#inputProjectVersionName").val().trim();
        tempSuTData.Name = selectedVersion;
        projectVariantData[selectedVersion] = tempSuTData;
    }
    let xhr = new XMLHttpRequest();
    xhr.open("POST", urlVariants, true);
    xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
    xhr.send(JSON.stringify(projectVariantData));
    xhr.onloadend = function () {
        if (this.status === 200) {
            saveVersionRename(selectedVersion, versionNameInput, variantEditingList, selectedVersionID);
        } else {
            console.log(this.response);
        }
    };
}

/**
 * renames the version. calls saveEditedVariants
 * @param selectedVersion the versionName
 * @param versionNameInput the new versionName
 * @param variantEditingList the variantEditingList
 */
function saveVersionRename(selectedVersion, versionNameInput, variantEditingList, selectedVersionID) {
    let oldVersionName = selectedVersion;
    let newVersionName = versionNameInput;
    if (newVersionName !== oldVersionName) {

        //change the name of the old version
        projectVariantData[oldVersionName].Name = newVersionName;
        projectVariantData[newVersionName] = projectVariantData[oldVersionName];
        delete projectVariantData[oldVersionName];

        renameModalVersionInUI(selectedVersionID, newVersionName);
        let changedVersionName = JSON.parse('["' + oldVersionName + '", "' + newVersionName + '"]');
        let xhr = new XMLHttpRequest();
        xhr.open("PUT", urlVariants, true);
        xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
        xhr.send(JSON.stringify(changedVersionName));
        xhr.onloadend = function () {
            if (this.status === 200) {
                saveEditedVariants(oldVersionName, newVersionName, variantEditingList);
                renameOptionSelector('#inputTestCaseSUTVersions', oldVersionName, newVersionName);
                updateVariantList('#inputTestCaseSUTVersions', '#inputTestCaseSUTVariants', newVersionName, variantEditingList);
            } else {
                console.log(this.response);
            }
        }
    }
    else {
        saveEditedVariants(oldVersionName, oldVersionName, variantEditingList);
    }
}

/**
 *  renameOptionSelector renames the option prev of the selector id to new
 * @param id id of the selector, starting with #
 * @param p previous option 
 * @param n new option
 */
function renameOptionSelector(id, p, n) {
    var select = $(id);
    for (var i = 0, l = select.length; i < l; i++) {
        var option = select[i];
        if(option.value == p)
        {
            option = n;
        }
 }
}

/**
 * udateVariantList refreshes the variantList if the edited version is currently selected
 * @param {*} verId id of the version selector
 * @param {*} varId id of the variant list
 * @param {*} version version to check 
 * @param {*} variants new variants for the edited version
 */
function updateVariantList(verId, varId, version, variants) {
    var versionKey = $(verId).val();
    if (typeof versionKey === 'undefined'){
        return;
    }
    if (versionKey != version) {
        return;
    }
    var list = $(varId);
    // remove all previously shown elements
    list.empty();
    // add versions of selected version to list
    $.each(variants, function (key, variant) {
        var listElement = ($("<li></li>")
            .attr("class", "list-group-item")
            .html('<span>' + variant.Name + '</span>'));
        list.append(listElement)
    });
}
/**
 * saves the renamed Variants
 * @param versionName the version name
 * @param variantEditinglist the variantEditinglist
 */
function saveEditedVariants(oldVersionName, newVersionName, variantEditinglist) {
    if (variantEditinglist !== []) {
        variantEditinglist.forEach(function (changedVariant) {
            if (newVersionName !== "") {
                changedVariant[0] = newVersionName;
            }
            let version = changedVariant[0];
            let oldVariantName = changedVariant[1];
            let newVariantName = changedVariant[2];
            let idNumber = changedVariant[3];
            changedVariant.splice(3, 1);
            let xhr = new XMLHttpRequest();
            xhr.open("PUT", urlVariants, true);
            xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
            xhr.send(JSON.stringify(changedVariant));
            xhr.onloadend = function () {
                if (this.status === 200) {
                    deleteFromProjectVariantData(version, oldVariantName);
                    addVariantToProjectVariantData(newVariantName, version);

                    let modalVariantDeletebutton = $("#delete-" + idNumber);
                    let modalVariant = $("#variant-input-id-" + idNumber);
                    if (selectedVersion === oldVersionName) {
                        modalVariantDeletebutton.attr("onClick", "deleteModalVariant('" + newVariantName + "','" + idNumber + "')");
                        modalVariant.attr("onchange", "variantNameChanged('" + newVariantName + "', '" + idNumber + "')");
                    }
                } else {
                    console.log(this.response);
                }
            };
        });
    }
    if (oldVersionName === selectedVersion) {
        selectedVersion = newVersionName;
    }
}

//--------------------------------------------------------------------------|
// UI-----|
//--------------------------------------------------------------------------|

/**
 * renames a version in the UI
 * @param selectedVersionID
 * @param versionName
 */
function renameModalVersionInUI(selectedVersionID, versionName) {
    let toRenameVersion = $("#" + selectedVersionID);
    toRenameVersion.attr("onclick", "versionSelected('" + "version-" + versionIdCounter + "' ,'" + versionName + "')");
    toRenameVersion.text(versionName);
}

/**
 * fills the version list
 * @param versionMap
 * @param listID
 */
function fillModalVersions(versionMap, listID) {
    $('#inputTestCaseSUTVersions').empty();
    $(listID).empty();
    $.each(versionMap, function (key, version) {
        addModalVersion(version, listID);
    });
}

/**
 * adds the variants to the variant list
 * @param selectedVersionKey
 */
function populateVariants(selectedVersionKey) {
    let version = projectVariantData[selectedVersionKey];
    if (version.Variants === null) {
        version.Variants = [];
    }
    if (version.Variants.length > 0) {
        $.each(version.Variants, function (key, variant) {
            addVariant(variant);
        });
    }
}

//--------------------------------------------------------------------------|
// Reset-----|
//--------------------------------------------------------------------------|

/**
 * resets the Dialog
 */
function newVersionReset() {
    resetSuTVersionModalValidity("inputProjectVersionName");
    resetSuTVersionModalValidity("inputProjectVariant");
    if (unsavedChanges) {
        nextSelectedVersionID = "";
        nextSelectedVersion = "";
        $("#unsavedChangesVersionModalSwitching").modal("show");
    } else {
        unsavedChanges = false;
        if (projectVariantData === null) {
            projectVariantData = {};
        }
        selectedVersion = "";
        selectedVersionID = "";
        $("#buttonAddVersions").attr("style", "float:inherit;");
        $("#buttonSaveVersions").attr("style", "float:inherit; display: none");
        $("#modeVersionApplicabilityEdit").attr("style", "display: none");
        $("#modeVersionApplicabilityNew").attr("style", "");
        $("#inputProjectVersionName").val("");
        $("#projectVariantList").empty();
        resetSuTVersionModalValidity("inputProjectVersionName");
        isNewSuTVersion = true;
        resetTempVersionData();
        $("#buttonDeleteVersion").prop("disabled", true);
        variantIdCounter = 0;
        variantEditinglist = [];
    }
}

/**
 * resets the tempVersionData
 */
function resetTempVersionData() {
    tempSuTData = JSON.parse('{"Name":"tempSuT","Variants":"' + [] + '"}');
    tempSuTData.Variants = [];
    let variantObject = JSON.parse('{"Name":"Default"}');
    tempSuTData.Variants.push(variantObject);
    addVariant(variantObject);
}

//--------------------------------------------------------------------------|
// Validity-----|
//--------------------------------------------------------------------------|
/**
 * checks the validity
 * @param elementID the input field id
 * @returns {boolean}
 */
function checkSuTVersionModalValidity(elementID) {
    let inputName = $("#" + elementID);
    return (inputName[0].checkValidity() && (inputName.val().trim() !== ""));
}

/**
 * reports the validity
 * @param elementID the input field id
 */
function reportSuTVersionModalValidity(elementID) {
    let inputName = $("#" + elementID);
    inputName[0].reportValidity();
}

/**
 * resets the validity
 * @param elementID the input field id
 */
function resetSuTVersionModalValidity(elementID) {
    let inputName = $("#" + elementID);
    inputName[0].setCustomValidity('');
}


/**
 * checks whether the version name is valid
 * @returns {boolean}
 */
function versionNameIsValid() {
    let containsVersionName;
    let inputProjectVersionName = $("#inputProjectVersionName");
    let newVersionName = inputProjectVersionName.val().trim();
    let isValidInput = checkSuTVersionModalValidity("inputProjectVersionName");
    if (selectedVersionID === "") {
        containsVersionName = projectVariantDataContains(newVersionName);
    } else {
        containsVersionName = projectVariantDataContains(newVersionName) && newVersionName !== $("#" + selectedVersionID).text().trim();
    }
    if (isValidInput && !containsVersionName) {
        return true
    }
    if (containsVersionName) {
        inputProjectVersionName[0].setCustomValidity("Desired name is already taken, please choose another name");
        reportSuTVersionModalValidity("inputProjectVersionName");
        return false;
    } else if (!isValidInput) {
        inputProjectVersionName[0].setCustomValidity("'Please use letters, numbers or .,:_() .'");
        reportSuTVersionModalValidity("inputProjectVersionName");
        return false;
    }
}

/**
 *  checks whether the variant names are valid
 * @returns {boolean}
 */
function variantNamesAreValid() {
    $("#projectVariantList").each(function (index) {
        if ($("#variant-input-id-" + index).length) {
            resetSuTVersionModalValidity("variant-input-id-" + index);
            if (!checkSuTVersionModalValidity("variant-input-id-" + index)) {
                $("#variant-input-id-" + index)[0].setCustomValidity("Please use letters, numbers or .,:_() .");
                reportSuTVersionModalValidity("variant-input-id-" + index);
                return false
            } else if (DesiredVariantNameTaken(index)) {
                $("#variant-input-id-" + index)[0].setCustomValidity("Desired name is already taken, please choose another name");
                reportSuTVersionModalValidity("variant-input-id-" + index);
                return false
            }
        }
    });
    return true
}

/**
 * checks whether the desired name is already in the list of variants
 * @returns {boolean}
 */
function DesiredVariantNameTaken(index) {
    let uiVariantName = $("#variant-input-id-" + index);
    variantEditinglist.forEach(function (changedVariantEntry) {
        let newVariantName = changedVariantEntry[2];
        let oldVariantName = changedVariantEntry[1];
        if (projectVariantDataContainsVariant(selectedVersion, newVariantName)
            && newVariantName !== oldVariantName
            && uiVariantName === newVariantName) {
            return true
        }
    });
    return false
}

//--------------------------------------------------------------------------|
// Contains-----|
//--------------------------------------------------------------------------|

/**
 * checks whether the projectVariantData contains a version
 * @param versionName the version name
 * @returns {boolean}
 */
function projectVariantDataContains(versionName) {
    let containsVersionName = false;
    $.each(projectVariantData, function (key, version) {
        if (version.Name === versionName) {
            containsVersionName = true;
        }
    });
    return containsVersionName;
}

/**
 * checks whether a version contains a variant
 * @param versionName the version name
 * @param variantName the variant name
 * @returns {boolean}
 */
function projectVariantDataContainsVariant(versionName, variantName) {
    let contains = false;
    if (isNewSuTVersion) {
        tempSuTData.Variants.forEach(function (variant) {
            if (variant.Name === variantName) {
                contains = true;
            }
        })
    } else {
        projectVariantData[versionName].Variants.forEach(function (variant) {
            if (variant.Name === variantName) {
                contains = true;
            }
        })
    }
    return contains;
}
