using SFML.Audio;
using SFML.System;

namespace FluidSim.Audio
{
    public class AudioOutputStream : SoundStream
    {
        private readonly SimulationRingBuffer _sourceBuffer;
        private double _speed = 1.0;   // non‑volatile, accessed with Volatile.Read/Write

        public AudioOutputStream(SimulationRingBuffer sourceBuffer)
        {
            _sourceBuffer = sourceBuffer;
            // 2 channels, 44.1 kHz, stereo
            Initialize(2, 44100, new[] { SoundChannel.FrontLeft, SoundChannel.FrontRight });
        }

        /// <summary>Playback speed (0.01 … 1.0 or higher for catch‑up).</summary>
        public double Speed
        {
            get => Volatile.Read(ref _speed);
            set => Volatile.Write(ref _speed, value);
        }

        protected override bool OnGetData(out short[] samples)
        {
            const int monoBlockSize = 512;
            float[] temp = new float[monoBlockSize];

            int read = _sourceBuffer.ReadInterpolated(temp, monoBlockSize, Speed);
            samples = new short[monoBlockSize * 2];

            if (read > 0)
            {
                for (int i = 0; i < read; i++)
                {
                    float clamped = Math.Clamp(temp[i], -1f, 1f);
                    short final = (short)(clamped * short.MaxValue);
                    samples[i * 2] = final;      // left
                    samples[i * 2 + 1] = final;  // right
                }
            }
            // Fill rest with silence
            for (int i = read * 2; i < samples.Length; i++)
                samples[i] = 0;

            return true;
        }

        protected override void OnSeek(Time timeOffset) =>
            throw new NotSupportedException();
    }
}