Skip to content
Snippets Groups Projects
scenari.js 33.8 KiB
Newer Older
Alfredo Chissotti's avatar
Alfredo Chissotti committed
"use strict";
// import Antifurto from './antifurto.js';
Alfredo Chissotti's avatar
Alfredo Chissotti committed
import { scenariToggleListener } from "./toggles.js";
Alfredo Chissotti's avatar
Alfredo Chissotti committed
import { showAlert, makeElementBounce } from "./alerts.js";
Alfredo Chissotti's avatar
Alfredo Chissotti committed
import Api from "./mqtt/api.js";
Alfredo Chissotti's avatar
Alfredo Chissotti committed
import Sensori from './sensori.js';
Alfredo Chissotti's avatar
Alfredo Chissotti committed

// JSON templeate for scenario
const scenarioTemplate = {
    nome: "",
    data: "",
    id: "",
    stato: false,
Alfredo Chissotti's avatar
Alfredo Chissotti committed
};
Alfredo Chissotti's avatar
Alfredo Chissotti committed

class Scenari {
Alfredo Chissotti's avatar
Alfredo Chissotti committed
    static antifurtoINbtn = null;
    /**
     * the div where everything related to the Scenari is stored
     */
    static scenariContainer = null;//document.getElementById('scenariContainer');
    /**
     * this is the select element where to add all the scenarios
     */
    static addNameHere = null;//document.getElementById('p');
    /**
     * contains the toggle that is currently active
     */
    static scenarioAttivoToggle = null;
     * counts how many scenarios have been added
Alfredo Chissotti's avatar
Alfredo Chissotti committed
    static index = 0;
    /**
     * the array where all of the user's scenari are stored
     */
Alfredo Chissotti's avatar
Alfredo Chissotti committed
    static scenariBucket = [];
Alfredo Chissotti's avatar
Alfredo Chissotti committed

    static antifurtoStatus = null;

    static isAntifurtoAvailable = null;
    static antifurtoClass = null;

    constructor(servicesArray) {
        Scenari.isAntifurtoAvailable = servicesArray[0];
        Scenari.scenariContainer = document.getElementById('scenariContainer');
        Scenari.addNameHere = document.getElementById('p');
        Scenari.antifurtoModalLauncherListener();
Alfredo Chissotti's avatar
Alfredo Chissotti committed
        Scenari.anyModalListener();
    }
    /**
     * sets up the listener for the button in the top of the page
     * i'm also leaving here what I haven't yet implemented
     */
    static async init(servicesArray) {
Alfredo Chissotti's avatar
Alfredo Chissotti committed
        Scenari.fillTable();
Alfredo Chissotti's avatar
Alfredo Chissotti committed

Alfredo Chissotti's avatar
Alfredo Chissotti committed
        const scenariBtn = document.getElementById('mainButtonContainer').children[1];
        scenariBtn.addEventListener('click', async () => {
            if(servicesArray[0]){
                try{
                    Scenari.antifurtoClass.toggleContainer(false);
                } catch (error) {
                    if(error.message !== "Antifurto.toggleContainer is not a function" && error.message !== "Cannot read properties of null (reading 'classList')")
            if(servicesArray[1]){
                try {
                    const luci = await import('./luci.js');
                    luci.default.toggleContainer(false);
                } catch (error) {
                    if(error.message !== "Luci.toggleContainer is not a function" && error.message !== "Cannot read properties of null (reading 'classList')")
                        throw error;
                }
Alfredo Chissotti's avatar
Alfredo Chissotti committed
        }, false);
        if(servicesArray[0]){
            const antifurto = await import('./antifurto.js');
            Scenari.antifurtoClass = antifurto.default;
        }
    /**
     * used for the antitheft button (ON/OFF): before opening the connected modal, change its text then open it
     * @see Scenari.antifurtoModalSubmitListener
     */
    static antifurtoModalLauncherListener() {
Alfredo Chissotti's avatar
Alfredo Chissotti committed
        const antifurtoBtn = document.getElementById('scenari-stato-antifurto');
        const okBtn = document.getElementById('attiva-antifurto-btn');
        const modalBody = document.querySelector('#antifurto-modal .modal-body');
        const modalLauncher = document.getElementById('lancia-antifurto-modal');

        antifurtoBtn.addEventListener('click', () => {
            /*if (registerBtn.innerText !== "Registra") {
                // sono nella fase di registrazione, devo smettere la registrazione
                const endRecordingModalLauncher = document.getElementById('termina-registrazione-launcher');
                Scenari.recordScenario(false,endRecordingModalLauncher,registerBtn);
                // turn on modal to change name of the recorded scenario
                modalLauncher.click();
                // activate antitheft
                Scenari.correctlySetAntifurto(false);
Alfredo Chissotti's avatar
Alfredo Chissotti committed
                return;
Alfredo Chissotti's avatar
Alfredo Chissotti committed
            if (Scenari.scenariBucket.length === 0) {
Alfredo Chissotti's avatar
Alfredo Chissotti committed
                showAlert('Nessuno scenario disponibile', 'Registrare uno o più scenari per poter attivarne uno', false);
Alfredo Chissotti's avatar
Alfredo Chissotti committed
                // make the registerBtn bounce for 3 seconds
                const registerBtn = document.getElementById('scenari-registra');
                makeElementBounce(registerBtn);
Alfredo Chissotti's avatar
Alfredo Chissotti committed
            const children = modalBody.children;
            // p, p
            /*
            <p>Stai per abilitare l'antifurto.</p>
            <p>Vuoi continuare?</p>
            */

            if (antifurtoBtn.innerText === 'ON') {
                // the antitheft is on
                children[0].innerText = "Stai per disabilitare l'antifurto.";
                okBtn.innerText = 'Disattiva';
            } else {
                // the antitheft is off
                children[0].innerText = "Stai per abilitare l'antifurto.";
                okBtn.innerText = 'Attiva';
            }
            // launch the modal
            modalLauncher.click();
            // related: Scenari.antifurtoModalSubmitListener();
Alfredo Chissotti's avatar
Alfredo Chissotti committed
        }, false);

        // toggleAntifurto(response);
Alfredo Chissotti's avatar
Alfredo Chissotti committed
    }
Alfredo Chissotti's avatar
Alfredo Chissotti committed
    /**
     * sets up various listeners for the modals
     * @see Scenari.attivaScenarioModal
     * @see Scenari.registraModal
     * @see Scenari.antifurtoModalSubmitListener
     */
    static anyModalListener() {
        Scenari.attivaScenarioModal();
        Scenari.registraModal();
        Scenari.antifurtoModalSubmitListener();
    }
    /**
     * listens to the submit button in the modal for the antitheft and activates/deactivates the antitheft
     * this modal is shown when the user clicks on the antitheft button
     * @see Scenari.antifurtoModalLauncherListener
     */
    static antifurtoModalSubmitListener() {
Alfredo Chissotti's avatar
Alfredo Chissotti committed
        const antifurtoOkBtn = document.getElementById('attiva-antifurto-btn');
        const closeBtn = document.querySelector('#antifurto-modal .btn.btn-danger');
        const antifurtoBtn = document.getElementById('scenari-stato-antifurto');
        antifurtoOkBtn.addEventListener('click', () => {
            // close modal
            closeBtn.click();


            const registerBtn = document.getElementById('scenari-registra');
            if (registerBtn.innerText !== "Registra") {
                // sono nella fase di registrazione, devo smettere la registrazione
                const endRecordingModalLauncher = document.getElementById('termina-registrazione-launcher');
                Scenari.recordScenario(false);
                const modalLauncher = document.getElementById('lancia-antifurto-modal');
                // turn on modal to change name of the recorded scenario
                modalLauncher.click();
                // activate antitheft
                Scenari.correctlySetAntifurto(false);
                // return;
            }


Alfredo Chissotti's avatar
Alfredo Chissotti committed
            // switch the antitheft status button
            const isActivatingAntitheft = antifurtoBtn.innerText === 'OFF';
            // Scenari.toggleAntifurto(isActivatingAntitheft);
            isActivatingAntitheft ? Scenari.activateRandomScenario() : Scenari.deactivateActiveScenario();//cannot use toggleScenario because I don't have the scenarioID
            // Antifurto.activate(isActivatingAntitheft);
            Scenari.correctlySetAntifurto(isActivatingAntitheft);
        }, false);
    }
    /**
     * listenes for the submit button in the modal for activating/deactivating a scenario when chosen from the toggles
     * @see scenariToggleListener
     */
Alfredo Chissotti's avatar
Alfredo Chissotti committed
    static attivaScenarioModal() {
        const modalBtn = document.getElementById('attiva-scenari-btn');
        const closeBtn = document.querySelector('#attiva-scenari-modal .btn.btn-danger');

        modalBtn.addEventListener('click', () => {
            // close the modal by clicking on the close button
            closeBtn.click();
Alfredo Chissotti's avatar
Alfredo Chissotti committed
            // I have to get to the toggle and activate it from the value of the select
            const scenarioID = Scenari.addNameHere.value;
            const toggle = document.querySelector(`#${scenarioID} .toggle-button`);
Alfredo Chissotti's avatar
Alfredo Chissotti committed
            // has the user chosen to activate the scenario?
            Scenari.toggleScenario(scenarioID, toggle !== Scenari.scenarioAttivoToggle);
        }, false);
    }
    /**
     * this is for the button "registra"/"termina" and the related modals
     * @see Scenari.registraBtnListener
     * @see Scenari.submitRecordModalListener
     * @see Scenari.endRecordingListener
     */
Alfredo Chissotti's avatar
Alfredo Chissotti committed
    static registraModal() {
        const scenariModal = document.getElementById('scenari-modal');

        const registraBtn = document.getElementById('scenari-registra');
        const okBtn = scenariModal.querySelector('.btn.btn-info');
        const modalBody = scenariModal.querySelector('.modal-body');
        const htmlForModalBody = `<p>Stai per attivare la registrazione dei comandi.</p>
        <p>Dal momento in cui premerai sul bottone azzurro, inizierai a registrare tutte le interazioni con le tue luci.</p>
        <p>Inoltre disabiliterai eventuali scenari attivi.</p>
        <p>Una volta che sarai soddisfatto del risultato, torna su questa pagina per terminare la registrazione.</p>
        <p>Inizare la registrazione?</p>`
        const modalLauncher = document.getElementById('registra-modal-launcer');
        const closeScenariModalBtn = scenariModal.querySelector('.btn.btn-danger');
        const endRecordingModalLauncher = document.getElementById('termina-registrazione-launcher');

        const endRecordingForm = document.getElementById('termina-registrazione-form');
        const closeRecordingBtn = document.getElementById('termina-registrazione-modal').querySelector('.btn.btn-danger');
        const campoNome = document.getElementById('nome-nuovo-scenario');


        Scenari.registraBtnListener(registraBtn, okBtn, modalBody, htmlForModalBody, modalLauncher);
        Scenari.submitRecordModalListener(okBtn, registraBtn, closeScenariModalBtn);
Alfredo Chissotti's avatar
Alfredo Chissotti committed
        Scenari.endRecordingListener(endRecordingForm, modalBody, htmlForModalBody, closeRecordingBtn, campoNome);
Alfredo Chissotti's avatar
Alfredo Chissotti committed
    }
    /**
     * listens for the actual "registra"/"termina" button on the page and edits the related modal accordingly
     * @param {HTMLButtonElement} registraBtn the button on the page
     * @param {HTMLButtonElement} okBtn the submit button in the modal
     * @param {HTMLElement} modalBody the body of the modal which is to be changed
     * @param {string} htmlForModalBody a string containing the html to be inserted in the modal body
     * @param {HTMLButtonElement} modalLauncher the button which launches the modal
     * @see Scenari.registraModal
     */
Alfredo Chissotti's avatar
Alfredo Chissotti committed
    static registraBtnListener(registraBtn, okBtn, modalBody, htmlForModalBody, modalLauncher) {
        registraBtn.addEventListener('click', () => {
            const isAboutToRecord = registraBtn.innerText === 'Registra';
            // change text of okBtn
            okBtn.innerText = isAboutToRecord ? 'Registra' : 'Termina';
            // change inner text of the modal

            if (isAboutToRecord) {
                modalBody.innerHTML = htmlForModalBody;
            } else {
Alfredo Chissotti's avatar
Alfredo Chissotti committed
                modalBody.innerHTML = `
                <p>Stai per terminare la registrazione dei comandi.</p>
                <p>Terminare la registrazione?</p>`;
Alfredo Chissotti's avatar
Alfredo Chissotti committed
            }
            // launch the modal
            modalLauncher.click();
            // related: Scenari.submitRecordModalListener
        }, false);
Alfredo Chissotti's avatar
Alfredo Chissotti committed
    }
    /**
     * listens for the submit of the modal which is launched when the user clicks on the "registra"/"termina" button
     * @param {HTMLButtonElement} okBtn the submit button in the modal
     * @param {HTMLButtonElement} registraBtn the button on the page (to understand if the user is about to record or not)
     * @param {HTMLButtonElement} closeScenariModalBtn the button used to close the modal
     * @param {HTMLButtonElement} endRecordingModalLauncher the button which launches the next modal (used if the user has finished recording)
     * @see Scenari.registraModal
     */
    static submitRecordModalListener(okBtn, registraBtn, closeScenariModalBtn) {
Alfredo Chissotti's avatar
Alfredo Chissotti committed
        okBtn.addEventListener('click', () => {
            const isAboutToRecord = registraBtn.innerText === 'Registra';
            // close modal
            closeScenariModalBtn.click();
            // tell the server to start/stop recording
            Scenari.recordScenario(isAboutToRecord);
Alfredo Chissotti's avatar
Alfredo Chissotti committed
        }, false);
    }
            setTimeout(Api.recordScenario(isRecording,Scenari.learnINbtn), 1500);
        } catch (error) {
            if(error.error)
                showAlert("Errore", error.error,false);
            else if(error.message)
                showAlert("Errore", error.message,false);
        }
    }
    static apiCallbackRecordScenario(isRecording){
        const endRecordingModalLauncher = document.getElementById('termina-registrazione-launcher');
        const registraBtn = document.getElementById('scenari-registra');
        const rec = isRecording != null ? isRecording : registraBtn.innerText === 'Registra';
        if(rec){
            Scenari.correctlySetAntifurto(false,undefined,true);
            Scenari.deactivateActiveScenario(true,true)
            showAlert("Registrazione","Inizio registrazione",true);
            registraBtn.innerText = 'Termina'
        } else {
            endRecordingModalLauncher.click();
            showAlert("Registrazione","Fine registrazione",true);
            registraBtn.innerText = 'Registra';
        }
    /**
     * listens for the submit of the modal which is launched when the user is done recording a scenario
     * @param {HTMLFormElement} endRecordingForm the form used to submit the name of the scenario
     * @param {HTMLElement} modalBody the body of the modal which is to be changed
     * @param {string} htmlForModalBody a string containing the html to be inserted in the modal body
     * @param {HTMLButtonElement} closeRecordingBtn the button used to close the modal
     * @param {HTMLInputElement} campoNome the input field used to insert the name of the scenario by the user
     * @see Scenari.registraModal
     * @see Scenari.mostraNuovoScenario
     */
Alfredo Chissotti's avatar
Alfredo Chissotti committed
    static endRecordingListener(endRecordingForm, modalBody, htmlForModalBody, closeRecordingBtn, campoNome) {
        endRecordingForm.addEventListener('submit', event => {
            event.preventDefault();
Alfredo Chissotti's avatar
Alfredo Chissotti committed
            // reset the other modal and button
            modalBody.innerHTML = htmlForModalBody;
            // close the modal
            closeRecordingBtn.click();

            const name = campoNome.value;
            // clear the field for the next use
            campoNome.value = '';
            Scenari.saveScenario(name);
Alfredo Chissotti's avatar
Alfredo Chissotti committed
        }, false);
Alfredo Chissotti's avatar
Alfredo Chissotti committed
    }
    static saveScenario(nome) {
            Api.saveScenario(nome);
        } catch (error) {
            if(error.error)
                showAlert("Errore", error.error,false);
            else if(error.message)
                showAlert("Errore", error.message,false);
        }
    }

    static saveScenarioCallback(scenario){
        showAlert("Salvataggio", "Scenario salvato",true);
        const scenarioJSON = Scenari.createScenarioFromName(scenario.nome,scenario.data)
        Scenari.mostraNuovoScenario(scenarioJSON,undefined,true);
    }
    // utilility functions
    /**
     * displays the given scenario on the screen (below every other one) and hooks up the listeners; then it increments the index
     * @param {scenarioTemplate} scenario the JSON scenario to be displayed
     * @param {Boolean} isActive if the scenario is active or not
     * @see Scenari.createScenarioRow
     * @see scenariToggleListener
     */
Alfredo Chissotti's avatar
Alfredo Chissotti committed
    static mostraNuovoScenario(scenarioJSON, isActive, fromServer = false) {
        const scenario = scenarioJSON.id == null || scenarioJSON.id == '' ? Scenari.createScenarioFromName(scenarioJSON.nome,scenarioJSON.data,scenarioJSON.stato) : scenarioJSON;
        const row = Scenari.createScenarioRow(scenario);
        const scenarioID = scenario.id;
        const tableBody = document.getElementById('table-row-scenari');
Alfredo Chissotti's avatar
Alfredo Chissotti committed
        tableBody.appendChild(row);

        // add the name of the scenario as option in the select of the modal
        const option = document.createElement('option');
        option.value = scenarioID;
        option.innerText = scenario.nome;
        Scenari.addNameHere.appendChild(option);
Alfredo Chissotti's avatar
Alfredo Chissotti committed

        const toggle = row.querySelector('.toggle-button');
        scenariToggleListener(toggle, scenarioID);
Alfredo Chissotti's avatar
Alfredo Chissotti committed
        Scenari.toggleScenario(scenarioID,isActive,fromServer);
Alfredo Chissotti's avatar
Alfredo Chissotti committed
    }
    /**
     * creates a table entry for the given scenario and returns it
     * @param {scenarioTemplate} scenario the JSON scenario to be displayed
     * @returns {HTMLTableRowElement} the row containing the given scenario
     */
Alfredo Chissotti's avatar
Alfredo Chissotti committed
    static createScenarioRow(scenario) {
        const row = document.createElement('tr');
        row.id = scenario.id;
        row.innerHTML = `
        <th scope="row">${scenario.nome.trim()}</th>
        <td>
            <span>${scenario.data}</span>
        </td>
        <td>
            <div class="switch-container no-box-sizing">
                <div id="toggle-${scenario.id}" class="toggle-button no-box-sizing ${scenario.stato ? 'active' : ''}">
                    <div class="inner-circle no-box-sizing"></div>
                </div>
            </div>
            <span id="launch-modal-${scenario.id}" data-bs-toggle="modal" data-bs-target="#attiva-scenari-modal"></span>
        </td>`;
        // the span is used by the toggle to launch the modal
        return row;
Alfredo Chissotti's avatar
Alfredo Chissotti committed
    }
    /**
     * changes the antifurto button to the given state
Alfredo Chissotti's avatar
Alfredo Chissotti committed
     * @param {Boolean} newStatus true if the antitheft is being activated, false otherwise
     * @param {Boolean} fromAntifurto usually false or undefined; true only if the function is called from the scenari
Alfredo Chissotti's avatar
Alfredo Chissotti committed
    static correctlySetAntifurto(newStatus, fromAntifurto = false,fromServer = false) {
        let antifurtoIsWorking = false;
        if (fromAntifurto === false && Scenari.isAntifurtoAvailable){
                Scenari.antifurtoClass.activate(newStatus, true,fromServer);
                antifurtoIsWorking = true;
            } catch (error) {
                // the antifurto isn't available
                if(error.message !== "Antifurto.activate is not a function")
                    throw error;
            }
Alfredo Chissotti's avatar
Alfredo Chissotti committed
        }
        if(antifurtoIsWorking || fromServer)
            Scenari.showChangeAntifurtoStatus(newStatus,fromServer);
        else{
            // server send click of IN0
            Api.setAntifurtoStatus({ previousStatus: Scenari.antifurtoStatus, fromScenari:true, fromServer });
        }
    }

    static showChangeAntifurtoStatus(newStatus,fromServer = false) {
            // Scenari.activateRandomScenario(fromServer);
            // check if the user was recording a scenario
            // Scenari.apiCallbackRecordScenario(false);
        }
        else
            Scenari.deactivateActiveScenario(undefined,fromServer);
        const previousStatus = Scenari.antifurtoStatus;
        Scenari.antifurtoStatus = newStatus;
        const antifurtoBtn1 = document.getElementById('antifurto-stato-antifurto');
        const antifurtoBtn2 = document.getElementById('scenari-stato-antifurto');
        if(newStatus === previousStatus)
            return;
        if (newStatus) {
            if(antifurtoBtn1.innerText === 'ON' && antifurtoBtn2.innerText === 'ON')
                return;
            antifurtoBtn1.innerText = 'ON';
            antifurtoBtn1.classList.remove('btn-danger');
            antifurtoBtn1.classList.add('btn-success');
            antifurtoBtn2.innerText = 'ON';
            antifurtoBtn2.classList.remove('btn-danger');
            antifurtoBtn2.classList.add('btn-success');
        } else {
            if(antifurtoBtn1.innerText === 'OFF' && antifurtoBtn2.innerText === 'OFF')
                return;
            antifurtoBtn1.innerText = 'OFF';
            antifurtoBtn1.classList.remove('btn-success');
            antifurtoBtn1.classList.add('btn-danger');
            antifurtoBtn2.innerText = 'OFF';
            antifurtoBtn2.classList.remove('btn-success');
            antifurtoBtn2.classList.add('btn-danger');
        }
    }
    /**
     * turns off the active scenario if there is one; useful if you don't have the scenarioID
     */
    static deactivateActiveScenario(aboutToRecord = false,fromServer = false) {
        if (Scenari.scenarioAttivoToggle == null)
            return;
        // Scenari.scenarioAttivoToggle.classList.remove('active');
        // Scenari.scenarioAttivoToggle = null;
        const toggleID = Scenari.scenarioAttivoToggle.id;
        const scenarioID = toggleID.substring(toggleID.indexOf('-') + 1);
        Scenari.toggleScenario(scenarioID, false,fromServer,aboutToRecord);
     * activates/deactivates the scenario with the given name also sets server side and updates antifurto
     * @param {string} scenarioID the ID of the scenario to be activated/deactivated
     * @param {Boolean} activating true if the scenario should be activated, false otherwise
    static toggleScenario(scenarioID, activating,fromServer = false,aboutToRecord = false) {
        // server toggle the scenario
        const scenario = Scenari.scenariBucket.filter(sc => sc.id === scenarioID)[0];
        if(!fromServer && !aboutToRecord){
Alfredo Chissotti's avatar
Alfredo Chissotti committed
            Scenari.setScenarioStatusServer(scenario, activating);
            Scenari.showScenarioAfterToggling(scenario, activating,fromServer);
    static setScenarioStatusServer(scenario, activating = false) {
        scenario.stato = activating;
Alfredo Chissotti's avatar
Alfredo Chissotti committed
        // isActivatingNewScenario = true  when a scenario is already turned on
            Api.setScenarioStatus(scenario, activating);
        } catch (error) {
            if (error.error){
                showAlert("Errore di comunicazione.",error.error,false);
            }
        }
    static showScenarioAfterToggling(scenarioJSON,activating,fromServer = false){
        let scenario;
        if(scenarioJSON?.stato != null) {
            scenarioJSON.stato = activating;
            scenario = scenarioJSON;
        } else {
            scenario = Scenari.scenariBucket.filter(sc => sc.nome === scenarioJSON)[0];
            scenario.stato = activating;
        }
Alfredo Chissotti's avatar
Alfredo Chissotti committed
        // find the scenario's row on the page
        const scenarioRow = document.getElementById(`${scenario.id}`);
        const toggle = scenarioRow.querySelector('.toggle-button');
        Scenari.correctlySetToggle(toggle,activating,fromServer);//this updates the active toggle
     * sets the active scenario toggle and takes care of activating or deactivating the scenario's toggle based on the given boolean
     * @param {HTMLElement} toggle the toggle to be activated or deactivated
     * @param {Boolean} activating true if the scenario should be activated, false otherwise
     * @see Scenari.correctlySetAntifurto
     */
    static correctlySetToggle(toggle, isActivating,fromServer = false) {
        if (isActivating) {
            Scenari.scenarioAttivoToggle?.classList.remove('active');
            toggle.classList.add('active');
            Scenari.scenarioAttivoToggle = toggle;
        } else {
            toggle.classList.remove('active');
            if(!fromServer)
                Scenari.scenarioAttivoToggle = null;
Alfredo Chissotti's avatar
Alfredo Chissotti committed
    }
    /**
     * activates a random scenario from the ones available
     */
    static activateRandomScenario(fromServer = false,retries = 0) {
Alfredo Chissotti's avatar
Alfredo Chissotti committed
        if (Scenari.scenariBucket.length === 0) {
            if(retries > 0){
                showAlert('Nessuno scenario disponibile', 'Registrare uno o più scenari per poter attivarne uno', false);
                // make the registerBtn bounce for 3 seconds
                const registerBtn = document.getElementById('scenari-registra');
                makeElementBounce(registerBtn);
            } else {
                setTimeout(() => {
                    const r = retries + 1;
                    Scenari.activateRandomScenario(fromServer,r);
                }, 2000);
            }
Alfredo Chissotti's avatar
Alfredo Chissotti committed
            return;
        }
        const randomIndex = Math.floor(Math.random() * Scenari.index);
        const scenarioID = `scenario-${randomIndex}`;
        Scenari.toggleScenario(scenarioID, true,fromServer);
    }
    /**
     * creates the scenario and updates index
     * @param {string} scenarioName the string of the scenario to create
     * @param {string} scenarioDate (optional) the string of the scenario's date
     * @param {Boolean} scenarioStato (optional) if the scenario is active or not
     * @returns {scenarioTemplate} the JSON scenario
    static createScenarioFromName(scenarioName,scenarioDate,scenarioStato) {
        const scenario = Object.assign({}, scenarioTemplate);
        scenario.nome = scenarioName;
        scenario.data = scenarioDate != null ? scenarioDate : new Date().toLocaleDateString();// assign at scenario.data the string YYYY/MM/DD from the current date
        scenario.id = `scenario-${Scenari.index}`;
        scenario.stato = scenarioStato != null ? scenarioStato : false;
        Scenari.index++;
Alfredo Chissotti's avatar
Alfredo Chissotti committed
        Scenari.scenariBucket.push(scenario);
        return scenario;
    }
    /**
     * fills the table with the scenarios available for the user in the server
     * @see Scenari.mostraNuovoScenario
     */
        // server get all scenarios
Alfredo Chissotti's avatar
Alfredo Chissotti committed
                setTimeout(() => Scenari.fillTable(), 2500);
            Api.getScenari();
            // also set Scenari.scenarioAttivoToggle to its toggle
        } catch (error) {
            if(error.error)
                showAlert("Errore di comunicazione",error.error,false);
            else if(error.message)
                showAlert("Errore", error.message,false);
    static mostraScenariServer(statoScenariJSON){
    +    "scenari-disponibili": [
    +        {
    +        "data": "2022-07-13",
    +        "nome": "scenario-2022-07-13T12-39-36"
    +        },
    +        {
    +        "data": "2022-07-13",
    +        "nome": "scenario-2022-07-13T15-37-31"
    +        }, [...]
    +    ],
    +    "learn": false,
    +    "attiva-scenari": "IN5",
    +    "learn-trigger": "IN4",
    +    "scenario-attivo": {
    +        "data": "2022-07-13",
    +        "nome": "scenario-2022-07-13T15-37-31"
    +    },
    +    "antifurto": true
        "luce-antifurto": "OUT1" // => outputLuceAntifurto
        }
        */
        //imposta learn e antifurto correttamente
Alfredo Chissotti's avatar
Alfredo Chissotti committed
        const sensoreINLearn = statoScenariJSON["learn-trigger"];
        const sinL = Sensori.claimSensore(sensoreINLearn);
        if(sinL != null){
        if(Scenari.isAntifurtoAvailable){
            if(Scenari.antifurtoClass?.attivaAntifurtoINbtn == null){
                const sensoreINAntifurto = statoScenariJSON["attiva-scenari"];
                const sinA = Sensori.claimSensore(sensoreINAntifurto);
                if(sinA != null){
                    Scenari.antifurtoINbtn = sinA;
                    Scenari.updateTooltipINbtnAntifurto();

                    // Antifurto.attivaAntifurtoINbtn = Scenari.antifurtoINbtn;
                }
            } else
                Scenari.antifurtoINbtn = Scenari.antifurtoClass.attivaAntifurtoINbtn;
        } else {
            // antifurto is not available
Alfredo Chissotti's avatar
Alfredo Chissotti committed
            const sensoreINAntifurto = statoScenariJSON["attiva-scenari"];
            const sinA = Sensori.claimSensore(sensoreINAntifurto);
            if(sinA != null)
        if (Scenari.isAntifurtoAvailable && Scenari.antifurtoClass?.outputAntifurtoStato == null) {
            const sensoreOUT = statoScenariJSON["luce-antifurto"];
            const sout = Sensori.claimSensore(sensoreOUT);
            if (sout != null) {
                Scenari.updateTooltipOUTbtnAntifurto();
                if(Scenari.isAntifurtoAvailable)
                    Scenari.antifurtoClass.outputAntifurtoStato = Scenari.outputLuceAntifurto;
        } else if(Scenari.isAntifurtoAvailable)
            Scenari.outputLuceAntifurto = Scenari.antifurtoClass.outputAntifurtoStato;
        if(statoScenariJSON.learn != null){
            document.getElementById('scenari-registra').innerText = statoScenariJSON.learn ? 'Termina' : 'Registra';
        }
        if(statoScenariJSON.antifurto != null){
            Scenari.correctlySetAntifurto(statoScenariJSON.antifurto,false,true);
        }
        //mostra gli scenari
        const scenariDisponibili = statoScenariJSON["scenari-disponibili"];
        const scenarioAttivo = statoScenariJSON["scenario-attivo"];
        for(const scenario of scenariDisponibili){
            const scen = Object.assign({}, scenarioTemplate);
            scen.nome = scenario.nome;
            scen.data = scenario.data;
            scen.stato = Scenari.compareScenarios(scenario,scenarioAttivo);
            Scenari.mostraNuovoScenario(scen,scen.stato,true);
        }
Alfredo Chissotti's avatar
Alfredo Chissotti committed

        Sensori.initializaTooltips();
    }

    static updateINbtnAntifurto(newINbtn){
        if(Scenari.isAntifurtoAvailable && Scenari.antifurtoClass.attivaAntifurtoINbtn === Scenari.antifurtoINbtn) return;
        if(Scenari.antifurtoINbtn != null)
            Sensori.liberaSensore(Scenari.antifurtoINbtn);

        if(newINbtn.nome == null){//this function wasn't called from the antifurto class but from the api
            Scenari.antifurtoINbtn = Sensori.claimSensore(newINbtn);
Alfredo Chissotti's avatar
Alfredo Chissotti committed
        }
        Scenari.antifurtoINbtn = newINbtn;
        //server send newINbtn
        Api.setAntifurtoINbtnFromScenari(newINbtn);//this is necessary as this function may be called from the antifurto class. It updates the in btn for the scenari microservice
    }

    static compareScenarios(scenario1,scenario2){
        if(scenario1 == null || scenario2 == null)
            return false;
        return scenario1.nome === scenario2.nome && scenario1.data === scenario2.data;
    }
    /**
     * toggle the visibility of the scenari container
     * @param {Boolean} visible true if the container should be shown, false otherwise
Alfredo Chissotti's avatar
Alfredo Chissotti committed
    static toggleContainer(visible) {
        if (visible) {
Alfredo Chissotti's avatar
Alfredo Chissotti committed
            Scenari.scenariContainer.classList.remove('invisible');
Alfredo Chissotti's avatar
Alfredo Chissotti committed
            if (Scenari.scenariBucket.length === 0) {
Alfredo Chissotti's avatar
Alfredo Chissotti committed
                // make the register button bounce
                const registerBtn = document.getElementById('scenari-registra');
                makeElementBounce(registerBtn);
            }
Alfredo Chissotti's avatar
Alfredo Chissotti committed
        } else {
Alfredo Chissotti's avatar
Alfredo Chissotti committed
            Scenari.scenariContainer.classList.add('invisible');
Alfredo Chissotti's avatar
Alfredo Chissotti committed
        }
    }

    static updateConfiguration(conf) {
        console.log(conf);
        if (conf == null) return;
        if (conf.learnINbtn != null && conf.learnINbtn != Scenari.learnINbtn) {
            Scenari.updateINbtnLearn(conf.learnINbtn);
        }
        if (conf.antifurtoINbtn != null && conf.antifurtoINbtn != Scenari.antifurtoINbtn) {
            Scenari.updateINbtnAntifurto(conf.antifurtoINbtn);
            if(Scenari.isAntifurtoAvailable)
                Scenari.antifurtoClass.updateINbtnAntifurto(Scenari.antifurtoINbtn);
        if (conf.outputAntifurtoStato != null && conf.outputAntifurtoStato != Scenari.outputLuceAntifurto) {
            Scenari.updateOUTbtn(conf.outputAntifurtoStato);
            if(Scenari.isAntifurtoAvailable)
                Scenari.antifurtoClass.updateOUTbtn(Scenari.outputLuceAntifurto);
        }
        Sensori.initializaTooltips();
    }

    static updateINbtnLearn(newINbtn) {
        if (Scenari.learnINbtn != null)
            Sensori.liberaSensore(Scenari.learnINbtn);

        if(newINbtn.nome == null){
            Scenari.learnINbtn = Sensori.claimSensore(newINbtn);
        Scenari.learnINbtn = newINbtn;
    }

    static updateOUTbtn(newOUTbtn) {
        if(Scenari.isAntifurtoAvailable && Scenari.antifurtoClass.outputAntifurtoStato === Scenari.outputLuceAntifurto) return;
        if (Scenari.outputLuceAntifurto != null)
            Sensori.liberaSensore(Scenari.outputLuceAntifurto);

        if(newOUTbtn.nome == null){
            Scenari.outputLuceAntifurto = Sensori.claimSensore(newOUTbtn);
        Scenari.outputLuceAntifurto = newOUTbtn;
    }

    static updateTooltipINbtnLearn() {
        if(Scenari.learnINbtn == null) return;
        Scenari.learnINbtn.utilizzo = `Modalità di apprendimento [${Scenari.learnINbtn.nome.toUpperCase()}]`;
        document.getElementById('scenari-modal-recordbtn').setAttribute('title',Scenari.learnINbtn.utilizzo);
    }

    static updateTooltipINbtnAntifurto(){
        if(Scenari.antifurtoINbtn == null) return;
        Scenari.antifurtoINbtn.utilizzo = `Cambia stato dell'antifurto [${Scenari.antifurtoINbtn.nome.toUpperCase()}]`;
        document.getElementById('attiva-antifurto-btn').setAttribute('title',Scenari.antifurtoINbtn.utilizzo);
        document.getElementById('toggle-antifurto-btn').setAttribute('title',Scenari.antifurtoINbtn.utilizzo);
    }

    static updateTooltipOUTbtnAntifurto(){
        if(Scenari.outputLuceAntifurto == null) return;
        Scenari.outputLuceAntifurto.utilizzo = `Stato dell'antifurto [${Scenari.outputLuceAntifurto.nome.toUpperCase()}]`;
        document.getElementById('scenari-stato-antifurto').setAttribute('title', Scenari.outputLuceAntifurto.utilizzo);
        document.getElementById('antifurto-stato-antifurto').setAttribute('title', Scenari.outputLuceAntifurto.utilizzo);
    }
Alfredo Chissotti's avatar
Alfredo Chissotti committed
}

export default Scenari;