Skip to content
Snippets Groups Projects
luci.ts 7.25 KiB
"use strict";
import Antifurto from "./antifurto.js";
import Scenari from "./scenari.js";
import { luciToggleListener } from "./toggles.js";
import { makeElementBounce } from "./alerts.js";

export interface luceTemplate {
    "luogo": String,
    "stato": Boolean,
    "id": String
};

class Luci {
    /**
     * the div where everything related to the Luci is stored
     */
    static luciContainer = document.getElementById('luciContainer')!;
    /**
     * the array where all of the user's luci are stored
     */
    static luciBucket: luceTemplate[] = [];
    /**
     * describes how many lights have already been added
     */
    static index: number = 0;

    constructor() {
        Luci.init();
        Luci.modalListener();
    }

    static init(): void {
        Luci.fillTable();

        const luciBtn = document.getElementById('mainButtonContainer')!.children[0];
        luciBtn.addEventListener('click', () => {
            Luci.toggleContainer(true);
            Scenari.toggleContainer(false);
            Antifurto.toggleContainer(false);
        }, false);

        // listen for the closing modal
        const cancelBtn = document.querySelector('#luci-modal .btn.btn-secondary')!;
        cancelBtn.addEventListener('click', () => {
            // delay 0.5s to allow the modal to close (otherwise it's not pretty)
            setTimeout(() => {
                Luci.selectReset();
            }, 500);
        }, false);
    }
    /**
     * shows and listens for the modal that allows the user to add a new light
     */
    static modalListener(): void {
        const select = document.getElementById('luogoLuce')! as HTMLSelectElement;
        const altroInput = document.getElementById('nuovaStanzaDIV')!;
        const altroClassList = altroInput.classList;
        const form = document.getElementById('search-form')!;
        const inputField = altroInput.querySelector('input')!;

        // show or hide the text input for the new room
        select.addEventListener('change', event => {
            event.preventDefault();
            const selected = (event.target! as HTMLSelectElement).value;

            if (selected === "altro") {
                altroClassList.remove('invisible');
                // set altroInput to required
                inputField.setAttribute('required', 'required');
            } else {
                altroClassList.add('invisible');
                // remove required from altroInput
                inputField.removeAttribute('required');
            }
        }, false);

        form.addEventListener('submit', event => {
            event.preventDefault();

            const selectedValue = select.value;
            if (selectedValue === "unselected") {
                alert("Selezionare una stanza nel menu a tendina.");
                return;
            }
            var stanza = select.options[select.selectedIndex].text.trim(); // get selected option text

            if (selectedValue === "altro") {
                const nuovaStanza = altroInput.querySelector('input')!.value.trim();
                if (nuovaStanza == null || nuovaStanza == "" || nuovaStanza.toLowerCase() === "altro") {
                    alert("Inserire un nome valido per la stanza.");
                    return;
                }
                for (const stanza of Luci.luciBucket)
                    if (stanza.luogo === nuovaStanza) {
                        alert("Stanza già esistente");
                        return;
                    }
                stanza = nuovaStanza;
                // reset the select
                Luci.selectReset();
            }
            stanza = stanza[0].toUpperCase() + stanza.substring(1, stanza.length);
            // TODO server send stanza

            // add stanza to table
            const luceJSON = Luci.createLight(stanza, false);
            Luci.showNewLight(luceJSON);

            // close modal
            const closeBtn = document.querySelector('#luci-modal .btn.btn-secondary')! as HTMLButtonElement;
            closeBtn.click();
        }, false);
    }
    /**
     * creates a new light and adds it to the bucket
     * @param {String} luogo the name of the room
     * @param {Boolean} stato the status of the light
     * @returns {luceTemplate} the new light
     */
    static createLight(luogo: String, stato: Boolean): luceTemplate {
        const luce: luceTemplate = {
            "luogo": luogo,
            "stato": stato,
            "id": `luce-${Luci.index}`,
        };
        Luci.luciBucket.push(luce);
        Luci.index++;
        return luce;
    }
    /**
     * shows a new light in the table after creating it
     * @param {luceTemplate} luceJSON the light to show
     */
    static showNewLight(luceJSON: luceTemplate): void {
        const luce = luceJSON.id == null ? Luci.createLight(luceJSON.luogo,luceJSON.stato) : luceJSON;
        const table = document.getElementById('table-row-luci')!;
        const row = document.createElement('tr');
        row.innerHTML = `
        <th scope="row" id="${luce.id}">${luce.luogo}</th>
        <td>
            <div class="switch-container no-box-sizing">
                <div class="toggle-button no-box-sizing ${luce.stato ? 'active' : ''}">
                    <div class="inner-circle no-box-sizing" />
                </div>
            </div>
        </td>`;
        const lastRow = table.lastElementChild;
        table.insertBefore(row, lastRow);
        // add listener for switch
        const toggle: HTMLElement = row.querySelector('.toggle-button')!;
        luciToggleListener(toggle, luce);
        // remove options from the select
        const select = document.getElementById('luogoLuce')! as HTMLSelectElement;
        const options = select.options;
        const luogoLowercase = luce.luogo.toLowerCase();
        for (const option of options) {
            if (option.text.toLowerCase() === luogoLowercase) {
                select.removeChild(option);
                break;
            }
        }
    }
    /**
     * resets the select menu used to add a new light
     */
    static selectReset(): void {
        const select = document.getElementById('luogoLuce') as HTMLSelectElement;
        const altroInput = document.getElementById('nuovaStanzaDIV')!;
        const inputField = altroInput.querySelector('input')!;

        select.selectedIndex = 0;
        altroInput.classList.add('invisible');
        inputField.removeAttribute('required');
        inputField.value = "";
    }
    /**
     * fills the table with the user's luci from the server
     */
    static fillTable(): void {
        // TODO server get all lights
        const luci = [];
        // for each, add to table and to luciBucket
        for (const luce of luci) {
            Luci.showNewLight(luce);
        }
    }
    /**
     * toggle the visibility of the luci container
     * @param {Boolean} visible 
     */
    static toggleContainer(visible: boolean): void {
        if (visible) {
            Luci.luciContainer.classList.remove('invisible');
            if (Luci.luciBucket.length === 0) {
                // make the + button bounce
                const plusBtn = document.querySelector('.fa-circle-plus');
                makeElementBounce(plusBtn);
            }
        } else {
            Luci.luciContainer.classList.add('invisible');
        }
    }
}

export default Luci;