using System.Collections.Generic;
using UnityEngine;
namespace MazeGen
{
///
/// The single source of truth for "is the maze simulation running right now".
///
/// Everything that advances maze state (agent decision timers, fight muster countdowns,
/// the level's elapsed-time clock) must tick on rather than
/// , so that one pause freezes the whole simulation coherently.
///
/// Deliberately does NOT touch : real Unity time has to keep
/// flowing while the maze is frozen, because that's what drives the watched-fight playback
/// animation and its coroutines.
///
/// Pausing is ref-counted by reason string (/) so
/// several independent things - three fights breaking out at once, plus an arena playback -
/// can each hold the simulation without stomping on each other's resume. The user's own
/// pause button is separate () and always wins.
///
public static class SimulationClock
{
private static readonly HashSet _holds = new HashSet();
private static bool _userPaused;
private static float _timeScale = 1f;
/// The observer's manual pause. Independent of, and additive with, any holds.
public static bool UserPaused
{
get => _userPaused;
set => _userPaused = value;
}
/// Fast-forward / slow-motion multiplier for maze simulation time.
public static float TimeScale
{
get => _timeScale;
set => _timeScale = Mathf.Clamp(value, 0.1f, 8f);
}
public static bool IsPaused => _userPaused || _holds.Count > 0;
/// Human-readable list of what's currently holding the simulation (null if nothing is).
public static string HoldSummary => _holds.Count == 0 ? null : string.Join(", ", _holds);
/// Scaled simulation delta for this frame - zero while paused.
public static float DeltaTime => IsPaused ? 0f : Time.deltaTime * _timeScale;
public static void PushHold(string reason) => _holds.Add(reason ?? "hold");
public static void PopHold(string reason) => _holds.Remove(reason ?? "hold");
public static bool HasHold(string reason) => _holds.Contains(reason ?? "hold");
///
/// Clears all state. Called from MazeSceneBuilder.Awake because this is static state and
/// the editor can be configured to skip domain reload between Play sessions, which would
/// otherwise leave a stale pause hold from the previous run holding the new one frozen.
///
public static void Reset()
{
_holds.Clear();
_userPaused = false;
_timeScale = 1f;
}
}
}