/*
This file is part of SystemTestPortal.
Copyright (C) 2017  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/>.
*/

$.getScript("/static/js/util/ajax.js");
$.getScript("/static/js/util/common.js");

/** Adds the listeners on page load */
function initializeExecutionClickListener() {

    $("#buttonExecuteFirstTestStep").off('click').on('click', buttonExecuteFirstTestStepPressed);
    $("#buttonExecuteNextTestStep").off('click').on('click', buttonExecuteNextTestStepPressed);
    $("#buttonSummaryFinish").off('click').on('click', buttonSummaryFinishPressed);
    $("#buttonAbort").off('click').on('click', buttonAbortPressed);
    $("#buttonPause").off('click').on('click', buttonPausePressed);
    $("#buttonPauseStep").off('click').on('click', buttonPausePressed);
    $("#buttonPreviousStep").off('click').on('click', getPreviousStep);
    $("#buttonPreviousStepFromSummary").off('click').on('click', getPreviousStepFromSummary);
    $("#buttonPreviousStepFromStartPage").off('click').on('click', getPreviousStepFromStartPage);

    var $check = $(".preconditionCheckbox"), el;
    $check
        .data('checked', 0)
        .click(function (e) {
            el = $(this);
            clearSelection();
            preconditionSelection(e, el)
        });

    //Handle File Change
    $('#resultFileInput').off('change').on('change', function() {
        readUploadInput(this);
    });

}

var timerID;
var secondsElement;
var minutesElement;
var hoursElement;
$(window).on('load', initTimer());

var seqProtocol;
var caseProtocol;
var stepProtocol;

var isInSequenceExecution;

/** Sequence start/summary page */
var isSequence;

// isTaskExecution indicates if the execution was started by a task. A
// execution that was started by a task has predefined version+variant.
// It is needed to get the correct version+variant for the protocol.
var isTaskExecution;

var initHours;
var initMinutes;
var initSeconds;

/** Will start the test execution timer */
function initTimer() {

    secondsElement = $('#timeSeconds');
    minutesElement = $('#timeMinutes');
    hoursElement = $('#timeHours');

    let sec = parseInt(secondsElement.text());
    let min = parseInt(minutesElement.text());
    let hour = parseInt(hoursElement.text());

    secondsElement.text(sec.toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping: false}));
    minutesElement.text(min.toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping: false}));
    hoursElement.text(hour.toString());

    resumeTimer();
}

function buttonPausePressed() {

    clearInterval(timerID);

    $("#buttonPause")
        .off()
        .on("click", resumeTimer);


    $(".buttonPauseIcon")
        .removeClass("fa-play fa-pause")
        .addClass("fa-play");
}

function resumeTimer() {

    clearInterval(timerID);
    timerID = setInterval(tickSec, 1000);

    $("#buttonPause")
        .off()
        .on("click", buttonPausePressed);

    $(".buttonPauseIcon")
        .removeClass("fa-pause fa-play")
        .addClass("fa-pause");
}

/**
 * Displays an abort dialog which will delegate back to overview on abort confirm
 * @param event the event which invokes this method
 */
function buttonAbortPressed(event) {
    showAbortModalWith(() => ajaxRequestFragment(event, getTestURL().toString(), "", "GET"));

}

/**
 * Saves inputs and requests for first currentStep execution page
 * @param event the event which invokes this method
 */
function buttonExecuteFirstTestStepPressed(event) {
    if (isInSequenceExecution) {
        // only update the init sequence protocol on the start page of the sequence execution

        if (isSequence) {
            initProtocol(seqProtocol);
        } else {
            initProtocol(caseProtocol);
            caseProtocol.CurrentStep = 0;
            storeCaseProtocol(caseProtocol);
        }
        // update with added protocolIDs of caseProtocols
        storeSeqProtocol(seqProtocol);
    } else {
        initProtocol(caseProtocol);
        caseProtocol.CurrentStep = 0;
        storeCaseProtocol(caseProtocol);
    }
    ajaxRequestFragment(event, currentURL().toString(), getExecutionStartPageData(false), "POST");
}

/**
 * Saves inputs and requests for next currentStep execution page
 * @param event the event which invokes this method
 */
function buttonExecuteNextTestStepPressed(event) {
    //get caseProt
    caseProtocol = retrieveCaseProtocol();
    //Update CaseProt with current stepProt
    setStepProtocol(caseProtocol);
    //go step further
    caseProtocol.CurrentStep++;
    //store caseProt
    storeCaseProtocol(caseProtocol);
    //Ajax to next step
    ajaxRequestFragment(event, currentURL().toString(), getExecutionStepPageData(false), "POST");
}

/**
 * Saves inputs and redirects
 * @param event the event which invokes this method
 */
function buttonSummaryFinishPressed(event) {
    disableAbortWarnings();
    if (!isSequence) {
        caseProtocol = retrieveCaseProtocol();
        appendCaseSummary(caseProtocol);

        if (isInSequenceExecution) {
            if (seqProtocol.caseProtocols == null) {
                seqProtocol.caseProtocols = [];
                seqProtocol.caseProtocols.push(caseProtocol);
            } else {
                if (seqProtocol.caseProtocols[seqProtocol.CurrentCase-1] != null) {
                    seqProtocol.caseProtocols[seqProtocol.CurrentCase-1] = caseProtocol
                } else {
                    seqProtocol.caseProtocols.push(caseProtocol);
                }
            }
            seqProtocol.CurrentCase++;
            storeSeqProtocol(seqProtocol)
        }

        var path = currentURL().removeLastSegments(1).toString();
        const data = getSummaryPageData(false);
        const target = currentURL().toString();

        if (data.case > 0) {
            path = currentURL().toString();
        }
            $.ajax({
                url: target,
                type: "POST",
                data: data
        
            }).done(response => {
                window.history.pushState("data", "", path);
                $(() => $("[data-toggle='tooltip']").tooltip());
                if (isInSequenceExecution) {
                    $("#tabarea").empty().append(response)
                } else {
                    window.location.replace(response)
                }
                return true;
        
            }).fail(response => {
                $("#modalPlaceholder").empty().append(response.responseText);
                $("#errorModal").modal("show");
        
        });
        sessionStorage.removeItem("caseProtocol");
        caseProtocol = null;
    } else {
        seqProtocol = retrieveSeqProtocol();
        seqProtocol.OtherNeededTime = getDuration(getSeconds(seqProtocol.OtherNeededTime) + getTimeInSeconds() - getInitTimeSeconds());
        storeSeqProtocol(seqProtocol);

        $.ajax({
            url: currentURL().toString(),
            type: "PUT",
            data: getSummaryPageData(false)

        }).done(response => {
            window.location.replace(response);
            sessionStorage.removeItem("caseProtocol");
            sessionStorage.removeItem("seqProtocol");
            caseProtocol = null;
            seqProtocol = null;
            return true;
        }).fail(response => {
            $("#modalPlaceholder").empty().append(response.responseText);
            $("#errorModal").modal("show");
    
        });

    }
    //caseProtocol = null;
}

/**
 * Fills the page with data, if execution page already got executed
 */
function fillWithData() {
    //Dont fill if there is no stepprotocol (startpage got called for the first time)
    if (caseProtocol == null) {
        return;
    }
    if (caseProtocol.StepProtocols.length === 0) {
        return;
    }

    //Dont fill anything if execution is new
    caseProtocol = retrieveCaseProtocol();
    if (caseProtocol == null) {
        return;
    }

    //Fill start page with data
    if (caseProtocol.CurrentStep === 0) {


    }

    //Fill currentStep page with data
    if (caseProtocol.StepProtocols.length !== 0 && caseProtocol.StepProtocols[caseProtocol.CurrentStep] != null) {
        stepProtocol = caseProtocol.StepProtocols[caseProtocol.CurrentStep];
        document.getElementById("inputTestStepActualResult").value = stepProtocol.ObservedBehavior;
        document.getElementById("inputTestStepNotes").value = stepProtocol.Comment;
        $('#inputTestStepNotes').html(caseProtocol.StepProtocols[caseProtocol.CurrentStep].Comment);
        setResult(caseProtocol.StepProtocols[caseProtocol.CurrentStep].Result)
    }

}

/**
 * sets result
 */
function setResult(number) {
    //document.getElementById("0").checked = false;
    document.getElementById(number.toString()).checked = true;
}

/** Shows next second on the timer */
function tickSec() {

    let sec = parseInt(secondsElement.text()) + 1;
    if (sec >= 60) {
        sec -= 60;
        tickMin()
    }
    secondsElement.text(sec.toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping: false}));
}

/** Shows next minute on the timer */
function tickMin() {

    let min = parseInt(minutesElement.text()) + 1;
    if (min >= 60) {
        min -= 60;
        tickHour();
    }
    minutesElement.text(min.toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping: false}));
}

/** Shows next hour on the timer */
function tickHour() {

    const hour = parseInt(hoursElement.text()) + 1;
    hoursElement.text(hour.toString());
}

/**
 * Initializes the case protocol.
 * Sets meta data for the protocol.
 */
function initProtocol(protocol) {

    if ((!isInSequenceExecution || isSequence) && !isTaskExecution) {
        protocol.SUTVersion = $('#inputTestObjectSUTVersions').val();
        protocol.SUTVariant = $('#inputTestObjectSUTVariants').val();
    } else {
        protocol.SUTVersion = $('#sutVersText').text();
        protocol.SUTVariant = $('#sutVarText').text();
    }

    saveOtherNeededTime(protocol);
    const results = JSON.parse(getPreconditionResults());
    for (let i = 0; i < protocol.PreconditionResults.length; i++)
        protocol.PreconditionResults[i].Result = results[i];

    protocol.IsAnonymous = $("#optionAnonymous:checkbox:checked").length > 0;
    protocol.CurrentStep = 1

}

/** Returns an object with the information given on the execution start page */
function getExecutionStartPageData(previous) {
    let protocols;
    if (isInSequenceExecution && previous) {
        protocols = seqProtocol.caseProtocols
    }
    return {
        fragment: true,
        step: 0,
        case: $('#inputTestCaseNumber').val(),
        duration: JSON.stringify(getDuration(getTimeInSeconds())),
        caseProtocol: JSON.stringify(caseProtocol),
        seqProtocol: JSON.stringify(seqProtocol),
        isInSequenceExecution: isInSequenceExecution,
        isPrevious: previous,
        caseProtocols: JSON.stringify(protocols)
    }
}

function setStepProtocol(protocol) {
    const seconds = getTimeInSeconds() - getInitTimeSeconds();

    stepProtocol.Visited = true;
    stepProtocol.ObservedBehavior = $('#inputTestStepActualResult').val();
    stepProtocol.Comment = $('#inputTestStepNotes').val();
    stepProtocol.Result = parseInt($("input:radio[name ='testResults']:checked").attr('id'));

    if (protocol.StepProtocols.length !== 0 && protocol.StepProtocols[caseProtocol.CurrentStep] != null) {
        //Adds time on already executed time
        stepProtocol.NeededTime = getDuration(getSeconds(stepProtocol.NeededTime) + seconds);
        //Overrides already executed protocol
        protocol.StepProtocols[caseProtocol.CurrentStep] = stepProtocol;
    } else {
        stepProtocol.NeededTime = getDuration(seconds);
        protocol.StepProtocols.push(stepProtocol);
    }

}

/** Returns an object with the information given on the execution currentStep page */
function getExecutionStepPageData(previous) {
    let protocols;
    if (isInSequenceExecution) {
        protocols = seqProtocol.caseProtocols;
    }
    return {
        fragment: true,
        step: $('#inputTestStepNumber').val(),
        case: $('#inputTestCaseNumber').val(),
        duration: JSON.stringify(getDuration(getTimeInSeconds())),
        caseProtocol: JSON.stringify(caseProtocol),
        seqProtocol: JSON.stringify(seqProtocol),
        isInSequenceExecution: isInSequenceExecution,
        isPrevious: previous,
        caseProtocols: JSON.stringify(protocols)
    }
}

function appendCaseSummary(protocol) {
    protocol.Comment = $('#inputTestComment').val();
    protocol.Result = parseInt($("input:radio[name ='testResults']:checked").attr('id'));
    saveOtherNeededTime(protocol);
}

/** Returns an object with the information given on the summary page */
function getSummaryPageData(previous) {
    let protocols;
    let thisCaseProtocol;
    if (isInSequenceExecution) {
        protocols = seqProtocol.caseProtocols;
        if (!isSequence){
            thisCaseProtocol = caseProtocol;
        }else{
            thisCaseProtocol = seqProtocol.caseProtocols[seqProtocol.caseProtocols.length-1];
        }
    }else{
        thisCaseProtocol = caseProtocol;
    }
    return {
        fragment: true,
        step: $('#inputTestStepNumber').val(),
        case: $('#inputTestCaseNumber').val(),
        duration: JSON.stringify(getDuration(getTimeInSeconds())),
        caseProtocol: JSON.stringify(thisCaseProtocol),
        seqProtocol: JSON.stringify(seqProtocol),
        isInSequenceExecution: isInSequenceExecution,
        isPrevious: previous,
        caseProtocols: JSON.stringify(protocols)
    }
}

/** Sets up abort listener displaying a modal if user accidentally hits non execution controls. */
function initializeAbortListener() {
    enableAbortWarnings();
}

/** Turns on abort warnings if the user accidentally hits non execution controls. */
function enableAbortWarnings() {

    $("a, img")
        .not($(".No-Warning-On-Current-Action-Abort"))
        .not($("#tabTestCases a"))
        .addClass("Warning-On-Current-Action-Abort-Active")
        .on("click.execution-abort", event => showAbortModalWith(() => $(event.target)[0].click()));
}

/** Turns off abort warnings if the user accidentally hits non execution controls. */
function disableAbortWarnings() {

    $(".Warning-On-Current-Action-Abort-Active")
        .off("click.execution-abort")
        .removeClass("Warning-On-Current-Action-Abort-Active");
}

/**
 * Sets up and shows the abort modal
 * @param abortFunction {function} action when pressing "Abort"
 * @returns {boolean} always false to prevent event default action
 */
function showAbortModalWith(abortFunction) {

    const abortModal = $("#execution-abort-modal");
    const confirmAbortButton = abortModal.find("#buttonAbortConfirm");

    // on abort pressed
    confirmAbortButton.on("click", () => {
        // for back button functionality
        pressedBack = true;

        abortModal.on('hidden.bs.modal', abortFunction);
        disableAbortWarnings();
        sessionStorage.removeItem("caseProtocol");
        sessionStorage.removeItem("seqProtocol");
        caseProtocol = null;
        seqProtocol = null;
        return true;
    });

    abortModal
        .on('hidden.bs.modal', () => confirmAbortButton.off("click"))
        .modal("show");

    return false;
}

/**
 * Will be invoked when the user hints one of the precondition checkboxes
 * @param event - User press event
 * @param element - The element which got pressed
 */
function preconditionSelection(event, element) {
    switch (element.data('checked')) {

        // unchecked, going checked
        case 0:
            element.data('checked', 1);
            element.prop('indeterminate', false);
            newTitle = 'fulfilled';
            element.next().attr('data-original-title', newTitle)
                .tooltip('hide')
                .tooltip('show');
            break;

        // checked, going indeterminate
        case 1:
            element.data('checked', 2);
            element.prop('indeterminate', true);
            element.prop('checked', true);
            newTitle = 'partially fulfilled';
            element.next().attr('data-original-title', newTitle)
                .tooltip('hide')
                .tooltip('show');
            break;

        // indeterminate, going unchecked
        default:
            element.data('checked', 0);
            element.prop('indeterminate', false);
            element.prop('checked', false);
            newTitle = 'not fulfilled';
            element.next().attr('data-original-title', newTitle)
                .tooltip('hide')
                .tooltip('show');
            break;
    }
}

/**
 * Returns the precondition results.
 * @returns {string} - An array with preconditions as JSON string
 */
function getPreconditionResults() {

    const checkboxes = document.getElementsByClassName("preconditionCheckbox");
    const results = [];

    for (let i = 0; i < checkboxes.length; i++) {
        if (checkboxes[i].indeterminate)
            results.push("partially fulfilled");
        else if (checkboxes[i].checked)
            results.push("fulfilled");
        else
            results.push("not fulfilled");
    }

    return JSON.stringify(results)
}

/**
 * Stores the case protocol in the session storage.
 * @param protocol
 */
function storeCaseProtocol(protocol) {
    sessionStorage.removeItem("caseProtocol");
    sessionStorage.setItem("caseProtocol", JSON.stringify(protocol));
}

/**
 * Returns the test case protocol.
 * @returns {any}
 */
function retrieveCaseProtocol() {
    return JSON.parse(sessionStorage.getItem("caseProtocol"));
}

/**
 * Returns the test sequence protocol.
 * @returns {any}
 */
function retrieveSeqProtocol() {
    return JSON.parse(sessionStorage.getItem("seqProtocol"));
}

/**
 * Stores the sequences protocol in the session storage.
 * @param protocol
 */
function storeSeqProtocol(protocol) {
    sessionStorage.removeItem("seqProtocol");
    sessionStorage.setItem("seqProtocol", JSON.stringify(protocol));
}

/**
 * Transforms the given seconds into a {hours, minutes, seconds} object
 * @param seconds
 * @returns {{hours: number, minutes: number, seconds: number}}
 */
function getDuration(seconds) {
    const hours = Math.floor(seconds / 36000);
    seconds = seconds - hours * 3600;
    const minutes = Math.floor(seconds / 60);
    seconds = seconds - minutes * 60;

    return {
        hours: hours,
        minutes: minutes,
        seconds: seconds
    }
}


/**
 * converts @param time in seconds
 */
function getSeconds(time) {
    return time.hours * 3600 + time.minutes * 60 + time.seconds
}

/**
 * Gets the current shown time in seconds.
 * @returns {number}
 */
function getTimeInSeconds() {
    const hours = parseInt($('#timeHours').text());
    const minutes = parseInt($('#timeMinutes').text());
    const seconds = parseInt($('#timeSeconds').text());

    return hours * 3600 + minutes * 60 + seconds;
}

/**
 * Returns the duration in seconds of the currentStep.
 * @returns {number}
 */
function getInitTimeSeconds() {
    return initHours * 3600 + initMinutes * 60 + initSeconds;
}

/**
 * Processes upload
 * @param input
 */
function readUploadInput(input) {

    function displayWrongFileModal() {
        $('#errorModalTitle').html("File not supported");
        $('#errorModalBody').html("This file ist not supported. Please select a valid file");
        $('#modal-generic-error').modal('show');
    }

    function applyUpload(upload) {
        const reader = new FileReader();
        reader.onloadend = function () {
            let textArea = $('#inputTestStepActualResult');
            $.ajax({
                url: currentURL().toString() + "/upload",
                type: "POST",
                data: {
                    uploadSrc: reader.result,
                    uploadName: upload.name
                }

            }).done(response => {
                response = JSON.parse(response)
                textArea.val(textArea.val() + "![attachment](" + response + ")");
            }).fail(response => {
                $('#errorModalTitle').html("Upload Failed");
                $('#errorModalBody').html("Unfortunately the file upload failed");
                $('#modal-generic-error').modal('show');
            })
        };
        reader.readAsDataURL(upload);
    }

    if (input.files && input.files[0]) {
        let file = input.files[0];
        if (file.type.startsWith("image")) {
            applyUpload(file);
        } else {
            displayWrongFileModal();
        }
        $('#resultFileInput').val("");
    }
}

/**
 * Keyboard support
 */
$(document).off("keydown.event").on("keydown.event", keyboardSupport);

/**
 * keybindings
 * @param event
 */
function keyboardSupport(event) {
    //checks if focus is in textfields, areas, etc.
    switch (event.target.tagName) {
        case "INPUT":
        case "SELECT":
        case "TEXTAREA":
            return;
    }

    //Adds Keybindings
    let buttonString = "";
    switch (event.key) {
        case "Enter":
            buttonString = "buttomSummaryFinish";
            break;
        case "ArrowRight":
            if (document.getElementById("buttonExecuteFirstTestStep") != null) {
                buttonString = "buttonExecuteFirstTestStep";
            } else if (document.getElementById("buttonExecuteNextTestStep") != null) {
                buttonString = "buttonExecuteNextTestStep"
            }
            break;
        case "ArrowLeft":
            if (document.getElementById("buttonPreviousStep") != null)
                buttonString = "buttonPreviousStep";
            else if (document.getElementById("buttonPreviousStepFromStartPage") != null)
                buttonString = "buttonPreviousStepFromStartPage";
            else if (document.getElementById("buttonPreviousStepFromSummary") != null)
                buttonString = "buttonPreviousStepFromSummary";
            break;
        case "Escape":
            buttonString = "buttonAbort";
            break;
        case "Spacebar":
        case " ":
            event.preventDefault();
            buttonString = "buttonPause";
    }
    if (buttonString !== "" && document.getElementById(buttonString) != null && buttonString !== "") {
        document.getElementById(buttonString).click();
    }
}


$('.modal')
    .off("hide.bs.modal.keyboardsupport")
    .off("show.bs.modal.keyboardsupport")

    /* Adds key listeners when modals closes */
    .on('hide.bs.modal.keyboardsupport', () => $(document).on("keydown.event", keyboardSupport))

    /* Removes key listeners when modals open */
    .on('show.bs.modal.keyboardsupport', () => $(document).off("keydown.event"));

/**
 * Goes back to the previous Step
 * @param event
 */
function getPreviousStep(event) {
    if (isInSequenceExecution){
    seqProtocol = retrieveSeqProtocol();
    }
    caseProtocol = retrieveCaseProtocol();
    setStepProtocol(caseProtocol);
    caseProtocol.CurrentStep = caseProtocol.CurrentStep - 1;
    storeCaseProtocol(caseProtocol);
    ajaxRequestFragment(event, currentURL().toString(), getExecutionStepPageData(true), "POST");

}

function getPreviousStepFromSummary(event) {
    if (isInSequenceExecution){
    seqProtocol = retrieveSeqProtocol();
    }
    if (!isSequence){
        caseProtocol = retrieveCaseProtocol();
        caseProtocol.CurrentStep = caseProtocol.CurrentStep - 1;
        caseProtocol.Comment = $('#inputTestComment').val();
        caseProtocol.Result = parseInt($("input:radio[name ='testResults']:checked").attr('id'));
        saveOtherNeededTime(caseProtocol);
        storeCaseProtocol(caseProtocol);
        ajaxRequestFragment(event, currentURL().toString(), getSummaryPageData(true), "POST");
    }else{
        saveOtherNeededTime(seqProtocol);
        storeCaseProtocol(caseProtocol);
        ajaxRequestFragment(event, currentURL().toString(), getSummaryPageData(true), "POST");

    }
}

/**
 *
 * @param event
 */
function fillSummaryWithData() {
    caseProtocol = retrieveCaseProtocol();
    document.getElementById("inputTestComment").value = caseProtocol.Comment;
    document.getElementById(caseProtocol.Result.toString()).checked = true;
}

/**
 * fills start page with date. This is needed for previous button
 */
function fillStartPageWithData() {
    //Dont fill if there is no stepprotocol (startpage got called for the first time)
    if (caseProtocol == null) {
        return;
    }

    caseProtocol = retrieveCaseProtocol();

    //Dont fill anything if execution is new
    if (caseProtocol == null) {
        return;
    }

    if (!isSequence && (caseProtocol.StepProtocols == null || caseProtocol.StepProtocols.length === 0) && !isInSequenceExecution) {
        return;
    }

    if (isInSequenceExecution) {
        seqProtocol = retrieveSeqProtocol();
    }

    if (!isInSequenceExecution && !isSequence) {
        document.getElementById("optionAnonymous").checked = caseProtocol.IsAnonymous;
        document.getElementById("inputTestObjectSUTVersions").value = caseProtocol.SUTVersion;
        document.getElementById("inputTestObjectSUTVariants").value = caseProtocol.SUTVariant;

    } else if (isInSequenceExecution && isSequence) {
        document.getElementById("optionAnonymous").checked = seqProtocol.IsAnonymous;
        document.getElementById("inputTestObjectSUTVersions").value = seqProtocol.SUTVersion;
        document.getElementById("inputTestObjectSUTVariants").value = seqProtocol.SUTVariant;
    } else {
        /*
        document.getElementById("optionAnonymous").checked = seqProtocol.IsAnonymous;
        document.getElementById("sutVersText").innerText = seqProtocol.SUTVersion;
        document.getElementById("sutVarText").innerText = seqProtocol.SUTVariant;
        */
    }

    const checkboxes = document.getElementsByClassName("preconditionCheckbox");
    let protocol;
    if (isSequence) {
        protocol = seqProtocol
    } else {
        protocol = caseProtocol
    }

    for (let i = 0; i < protocol.PreconditionResults.length; i++) {
        if (protocol.PreconditionResults[i].Result === "partially fulfilled") {
            checkboxes[i].indeterminate = true;
        } else if (protocol.PreconditionResults[i].Result === "fulfilled") {
            checkboxes[i].checked = true;
        } else {
            checkboxes[i].checked = false;
        }
    }
}

/**
 * Saves input and send ajax for previous page
 * @param event
 */
function getPreviousStepFromStartPage(event) {
    seqProtocol = retrieveSeqProtocol();
    if (isInSequenceExecution) {
        initProtocol(caseProtocol);
        if (seqProtocol.caseProtocols == null) {
            caseProtocol.CurrentStep = 0;
            seqProtocol.caseProtocols = [];
            seqProtocol.caseProtocols.push(caseProtocol);
        } else {
            if (seqProtocol.caseProtocols[seqProtocol.CurrentCase-1] != null) {
                seqProtocol.caseProtocols[seqProtocol.CurrentCase-1] = caseProtocol
            } else {
                seqProtocol.caseProtocols.push(caseProtocol);
            }
        }
        storeCaseProtocol(caseProtocol);

            seqProtocol.CurrentCase--;

        storeSeqProtocol(seqProtocol)
    }
    ajaxRequestFragment(event, currentURL().toString(), getExecutionStartPageData(true), "POST");
}

/**
 * Saves other needed time for @param protocol
 */
function saveOtherNeededTime(protocol){
    const seconds = getTimeInSeconds() - getInitTimeSeconds();
    if (protocol.OtherNeededTime != null && !isNaN(getSeconds(protocol.OtherNeededTime))) {
        protocol.OtherNeededTime = getDuration(getSeconds(protocol.OtherNeededTime) + seconds);
    } else {
        protocol.OtherNeededTime = getDuration(seconds)
    }
}