export class GameTime {
    constructor() {
        const now = Date.now();
        this.realNow = now;
        this.lastRealNow = now;
        this.deltaMs = 0;
        this.scaledDeltaMs = 0;
        this.gameNow = 0;
        this.timeScale = 2; // base is 2
        this.paused = false;
    }

    update() {
        this.realNow = Date.now();
        this.deltaMs = this.realNow - this.lastRealNow;
        this.lastRealNow = this.realNow;

        if (this.paused) {
            this.scaledDeltaMs = 0;
            return;
        }

        this.scaledDeltaMs = this.deltaMs * this.timeScale;
        this.gameNow += this.scaledDeltaMs;
    }

    now() {
        return this.gameNow;
    }

    pause() {
        this.paused = true;
    }

    resume() {
        this.paused = false;
        this.lastRealNow = Date.now();
        this.deltaMs = 0;
        this.scaledDeltaMs = 0;
    }

    setTimeScale(scale) {
        this.timeScale = Math.max(0, scale);
    }

    isPaused() {
        return this.paused;
    }
}

export class Timer {
    constructor() {
        this.startTime = null;
    }

    start() {
        this.startTime = gameTime.now();
    }

    reset() {
        this.start();
    }

    restart() {
        this.start();
    }

    elapsedMs() {
        if (this.startTime === null) {
            return Infinity;
        }

        return gameTime.now() - this.startTime;
    }

    hasElapsed(durationMs) {
        return this.elapsedMs() >= durationMs;
    }

    remainingMs(durationMs) {
        if (this.startTime === null) {
            return 0;
        }

        return Math.max(0, durationMs - this.elapsedMs());
    }
}

export const gameTime = new GameTime();