// DragonX Wallet - ImGui Edition
// Copyright 2024-2026 The Hush Developers
// Released under the GPLv3
//
// ConsoleScrollController — the console's auto-scroll state machine.
//
// It owns three coupled pieces of state that were previously loose fields on the god-class:
//   - auto_scroll_ : whether output is pinned to the bottom (follows new lines)
//   - a cooldown   : a short grace period after a wheel-up so smooth-scroll can animate away
//                    from the bottom before the "am I at the bottom?" re-enable check runs
//   - new_lines_   : how many lines arrived while scrolled up (drives the jump-to-bottom pill)
//
// It is ImGui-free: the view measures scroll positions and hands in a plain `atBottom` bool
// and a frame delta; the controller decides when to re-pin. That keeps the interplay
// (wheel-up pauses, cooldown gates the re-enable, new-line counting only while scrolled up)
// unit testable.

#pragma once

namespace dragonx {
namespace ui {

class ConsoleScrollController {
public:
    // Seconds to ignore the at-bottom re-enable check after a user wheel-up, so an in-flight
    // smooth-scroll can move away from the bottom first.
    static constexpr float kScrollUpCooldownSeconds = 0.5f;

    bool autoScroll() const { return auto_scroll_; }
    int  newLines()   const { return new_lines_; }

    // User toggled the "auto-scroll" checkbox. Enabling re-pins to the bottom.
    void setAutoScroll(bool on);

    // User scrolled up with the wheel — stop following output and start the cooldown.
    void onUserScrolledUp();

    // Advance the cooldown timer by one frame.
    void tickCooldown(float dt);

    // The view reports whether the viewport is currently at the bottom. If auto-scroll is off
    // and the cooldown has elapsed, reaching the bottom re-enables auto-scroll.
    void considerReenable(bool atBottom);

    // `n` new lines were appended to the model this frame; count them only while scrolled up.
    void onLinesAdded(int n);

    // Called each frame while pinned to the bottom (the view issues the actual scroll).
    void resetNewLines() { new_lines_ = 0; }

    // User clicked the jump-to-bottom pill.
    void jumpToBottom() { pinToBottom(); }

private:
    void pinToBottom() { auto_scroll_ = true; new_lines_ = 0; }

    bool  auto_scroll_ = true;
    float cooldown_    = 0.0f;
    int   new_lines_   = 0;
};

} // namespace ui
} // namespace dragonx
