#pragma once

#include "GameWorldView.h"

// RAII guard for the "pause the game while a modal is open" idiom (REQ-UI-SPEED).
// Constructing it snapshots the current game speed and pauses the game; on scope
// exit it restores the snapshotted speed and rebases the render frame timer, so the
// wall time the player spent in the dialog is not converted into simulation ticks.
//
// Pairs with ModalLayer, which the same call sites use to show the modal itself.
//
// Two escape hatches for the paths that must not simply restore at scope exit:
//   restore() — restore now instead of at scope exit, for when more work has to run
//               at the player's real speed before the scope ends (e.g. a follow-up
//               dialog that snapshots the speed itself).
//   release() — abandon the restore entirely, for when the game is about to be
//               reset or the window closed and the old speed is meaningless.
// Both are idempotent and the destructor does nothing once either has run.
class ModalPauseScope
{
public:
    explicit ModalPauseScope(GameWorldView& view)
        : m_view(view)
        , m_previousGameSpeed(view.getGameSpeed())
        , m_restorePending(true)
    {
        m_view.setGameSpeed(0.0);
    }

    ~ModalPauseScope()
    {
        restore();
    }

    void restore()
    {
        if (!m_restorePending) { return; }
        m_restorePending = false;
        m_view.setGameSpeed(m_previousGameSpeed);
        m_view.resetFrameTimer();
    }

    void release()
    {
        m_restorePending = false;
    }

    ModalPauseScope(const ModalPauseScope&) = delete;
    ModalPauseScope& operator=(const ModalPauseScope&) = delete;

private:
    GameWorldView& m_view;
    double         m_previousGameSpeed;
    bool           m_restorePending;
};
