import Timer from '../components/Timer.js';
import { System } from '../System.js';


class TimerSystem extends System {
    /**
     *
     * @type {number}
     */
    #timeDelta = 0;
    /**
     *
     * @type {EntityComponentDataset|null}
     */
    #dataset = null;

    dependencies = [Timer];


    /**
     *
     * @param {Timer} timer
     * @param {number} entity
     */
    #visit(timer, entity) {
        if (!timer.active) {
            return;
        }

        const timeDelta = this.#timeDelta;
        const dataset = this.#dataset;

        let budget = timer.counter + timeDelta;
        const timeout = timer.timeout;

        while (budget > timeout) {
            budget -= timeout;

            const functions = timer.actions;

            const n = functions.length;

            for (let i = 0; i < n; i++) {
                const action = functions[i];

                try {
                    action();
                } catch (e) {
                    console.error(`entity '${entity}' Timer action[${i}] exception:`, e);
                }

            }

            dataset.sendEvent(entity, "timer-timeout", timer);
            if (++timer.ticks > timer.repeat) {
                //already performed too many cycles
                timer.active = false;
                return; //bail out
            }

            if (timeout === 0) {
                // prevent infinite loop
                break;
            }
        }
        timer.counter = budget;
    }

    update(timeDelta) {
        const entityManager = this.entityManager;
        const dataset = entityManager.dataset;

        if (dataset === null) {
            return;
        }

        this.#dataset = dataset;
        this.#timeDelta = timeDelta;

        dataset.traverseComponents(Timer, this.#visit, this);

    }
}


export default TimerSystem;
