#pragma once
// tail_control — the REAPER-free logic behind the docked bank_panel's tail-mode
// toggle. The panel shell owns the SWELL window, LICE drawing, and click
// hit-testing; the cycle order, manual-length clamp, and label text live here.

#include <optional>
#include <string>

#include "core/capture/render_settings.h"  // TailMode (pure enum) — the three-state tail contract

namespace reasampler::capture {

// The Manual-mode starting length: 2s, a musically useful default (a bar of
// reverb throw at moderate tempo), well under the 8s cap. Also the fallback
// for a project with no stored tail setting.
inline constexpr double kDefaultManualTailMs = 2000.0;

// Fine-adjust step per scroll-wheel notch in Manual mode. Daniel-set.
inline constexpr double kManualStepMs = 250.0;

// The panel's current tail setting: mode + the length used only when Manual.
// Default None so a capture with no explicit choice stays exact-bounds.
// `manualMs` is clamped to kMaxTailMs before it ever reaches a CaptureRequest.
struct TailSetting {
    TailMode mode     = TailMode::None;
    double   manualMs = kDefaultManualTailMs;
};

// Cycles the tail mode: None -> Auto -> Manual -> None.
TailMode cycleTailMode(TailMode current);

// The effective manual length a Manual capture uses: clamped to [0, kMaxTailMs].
// Exposed so the panel can show the clamped value. Meaningful only for Manual.
double clampManualMs(double manualMs);

// Applies `notches` scroll-wheel steps of `stepMs` each to `current`, clamped
// to [0, kMaxTailMs]. Meaningful only for TailMode::Manual.
double adjustManualMs(double current, int notches, double stepMs);

// The toggle's label, e.g. "Tail: Off", "Tail: Auto", or (Manual, clamped
// length to one decimal) "Tail: Manual 2.0s".
std::string tailToggleLabel(const TailSetting& setting);

// JSON round-trip of a TailSetting, for persist to store per-project. Pure/
// testable here, mirroring bank_model's serialize/deserialize; deserialize
// returns nullopt on malformed input so the caller falls back to a default.
std::string serializeTailSetting(const TailSetting& setting);
std::optional<TailSetting> deserializeTailSetting(const std::string& json);

} // namespace reasampler::capture
