// Copyright 2013-2025, University of Colorado Boulder
/**
 * Game timer, keeps track of the elapsed time in the game using "wall clock" time. The frame rate of this clock is
 * sufficient for displaying a game timer in "seconds", but not for driving smooth animation.
 *
 * @author Chris Malley (PixelZoom, Inc.)
 */
import { string_vegas_pattern_0hours_1minutes_2seconds_StringProperty } from './strings/pattern/0hours/1minutes/2seconds.js';
import { string_vegas_pattern_0minutes_1seconds_StringProperty } from './strings/pattern/0minutes/1seconds.js';
import '../../globals.js';
import BooleanProperty from '../../axon/js/BooleanProperty.js';
import NumberProperty from '../../axon/js/NumberProperty.js';
import stepTimer from '../../axon/js/stepTimer.js';
import StringUtils from '../../phetcommon/js/util/StringUtils.js';
import Tandem from '../../tandem/js/Tandem.js';
import vegas from './vegas.js';
import PhetioObject from '../../tandem/js/PhetioObject.js';
export default class GameTimer extends PhetioObject {
    constructor(tandem = Tandem.OPT_OUT) {
        super({
            phetioState: false
        });
        this.isRunningProperty = new BooleanProperty(false, {
            tandem: tandem.createTandem('isRunningProperty'),
            phetioFeatured: true,
            phetioReadOnly: true // Sims use start(), stop(), or restart() to change isRunningProperty.
        });
        this.elapsedTimeProperty = new NumberProperty(0, {
            numberType: 'Integer',
            units: 's',
            isValidValue: elapsedTime => (elapsedTime >= 0),
            tandem: tandem.createTandem('elapsedTimeProperty'),
            phetioFeatured: true,
            phetioReadOnly: true
        });
        this.intervalId = null;
    }
    reset() {
        this.isRunningProperty.reset();
        this.elapsedTimeProperty.reset();
        if (this.intervalId) {
            stepTimer.clearInterval(this.intervalId);
            this.intervalId = null;
        }
    }
    get isRunning() {
        return this.isRunningProperty.value;
    }
    /**
     * Starts the timer. This is a no-op if the timer is already running.
     */
    start() {
        if (!this.isRunningProperty.value) {
            this.elapsedTimeProperty.value = 0;
            this.intervalId = stepTimer.setInterval(() => {
                this.elapsedTimeProperty.value = this.elapsedTimeProperty.value + 1;
            }, 1000); // fire once per second
            this.isRunningProperty.value = true;
        }
    }
    /**
     * Stops the timer. This is a no-op if the timer is already stopped.
     */
    stop() {
        if (this.isRunningProperty.value) {
            stepTimer.clearInterval(this.intervalId);
            this.intervalId = null;
            this.isRunningProperty.value = false;
        }
    }
    /**
     * Convenience function for restarting the timer.
     */
    restart() {
        this.stop();
        this.start();
    }
    /**
     * Formats a value representing seconds into H:MM:SS (localized).
     */
    static formatTime(time) {
        const hours = Math.floor(time / 3600);
        const minutes = Math.floor((time - (hours * 3600)) / 60);
        const seconds = Math.floor(time - (hours * 3600) - (minutes * 60));
        const minutesString = (minutes > 9 || hours === 0) ? minutes : (`0${minutes}`);
        const secondsString = (seconds > 9) ? seconds : (`0${seconds}`);
        // Factor out patternStringProperty here, because [...].value confuses the chipper build process.
        if (hours > 0) {
            const patternStringProperty = string_vegas_pattern_0hours_1minutes_2seconds_StringProperty;
            return StringUtils.format(patternStringProperty.value, hours, minutesString, secondsString);
        }
        else {
            const patternStringProperty = string_vegas_pattern_0minutes_1seconds_StringProperty;
            return StringUtils.format(patternStringProperty.value, minutesString, secondsString);
        }
    }
}
vegas.register('GameTimer', GameTimer);
