using System.Collections.Generic;
using Cthangover.Core.Battle;
using Cthangover.Core.Settings;
using Cthangover.Core.UI.Theming;
using Godot;
namespace Cthangover.TurnBattle
{
///
/// In-battle speed toggle bar (x1/x4/x8). Directly sets
/// Godot.Engine.TimeScale to globally accelerate the entire game loop —
/// not just animations. Persists the choice to GameData.Settings
/// so it survives scene reloads. restores 1x
/// without saving and is the part the core scene consumes through
/// when battle ends.
///
public partial class BattleSpeedControl : Control, IBattleSpeedControl
{
private readonly Dictionary _buttons = new();
private int _activeSpeed;
///
/// Builds the speed bar in the constructor. Godot never runs a
/// _Ready override declared in a mod assembly, so the buttons and the
/// saved-speed restore must happen here. Anchors are used instead of a
/// viewport-size lookup because the viewport is unavailable before the node
/// enters the tree.
///
public BattleSpeedControl()
{
CthangoverTheme.Apply(this);
var speeds = new[] { 1, 4, 8 };
var hbox = new HBoxContainer { Name = "SpeedButtons" };
hbox.Alignment = BoxContainer.AlignmentMode.Begin;
foreach (var speed in speeds)
{
var btn = new Button
{
Text = $"x{speed}",
CustomMinimumSize = new Vector2(48, 32)
};
btn.Pressed += () => OnSpeedSelected(speed);
hbox.AddChild(btn);
_buttons[speed] = btn;
}
AddChild(hbox);
AnchorLeft = 1f;
AnchorRight = 1f;
AnchorTop = 0f;
AnchorBottom = 0f;
OffsetLeft = -200f;
OffsetRight = -20f;
OffsetTop = 20f;
OffsetBottom = 52f;
ApplySavedSpeed();
}
///
/// Restores the speed from .
/// Called on _Ready to reapply the saved preference.
///
public void ApplySavedSpeed()
{
var speed = GameData.Instance.Settings.BattleSpeed;
if (speed < 1 || speed > 8)
speed = 1;
_activeSpeed = speed;
Godot.Engine.TimeScale = speed;
UpdateHighlight();
}
///
/// Resets to 1.0x without
/// persisting to settings. Used when battle ends so the lobby
/// and menus run at normal speed regardless of the player's
/// in-battle preference.
///
public void ResetToNormal()
{
Godot.Engine.TimeScale = 1.0f;
}
private void OnSpeedSelected(int speed)
{
_activeSpeed = speed;
Godot.Engine.TimeScale = speed;
var settings = GameData.Instance.Settings;
settings.BattleSpeed = speed;
settings.Save();
UpdateHighlight();
}
private void UpdateHighlight()
{
foreach (var kv in _buttons)
{
var isActive = kv.Key == _activeSpeed;
kv.Value.Modulate = isActive ? UiTokens.Success : UiTokens.White;
}
}
}
}