namespace DragonISO.Engine.Pipeline;

/// <summary>
/// Generates synthetic BGRA test-pattern frames for diagnosing NDI setups
/// without a real Teams meeting. Produces SMPTE-style color bars with a
/// moving sweep band and a small frame-counter readout in the corner so
/// the operator can visually confirm frames are flowing in real time.
///
/// Static stateless API â€” caller bumps the frame counter each tick. Each
/// call allocates a fresh BGRA byte[] so the caller can hand it straight
/// to <see cref="NdiSender"/> via a <see cref="ProcessedFrame"/> wrapper
/// without holding shared buffers.
///
/// Used by <c>DragonISO.Console --test-pattern</c>; could also be wired
/// into the WPF host as a "synthetic source" toggle for demoing.
/// </summary>
public static class TestPatternGenerator
{
    /// <summary>
    /// SMPTE 75% color-bar palette in BGRA order (high-amplitude bars).
    /// Eight bars, each occupying 1/8 of the frame width.
    /// </summary>
    private static readonly (byte B, byte G, byte R)[] BarColors = new[]
    {
        ((byte)191, (byte)191, (byte)191), // 75% white
        ((byte)0,   (byte)191, (byte)191), // 75% yellow
        ((byte)191, (byte)191, (byte)0),   // 75% cyan
        ((byte)0,   (byte)191, (byte)0),   // 75% green
        ((byte)191, (byte)0,   (byte)191), // 75% magenta
        ((byte)0,   (byte)0,   (byte)191), // 75% red
        ((byte)191, (byte)0,   (byte)0),   // 75% blue
        ((byte)0,   (byte)0,   (byte)0),   // black
    };

    /// <summary>
    /// Render one BGRA frame at the given dimensions. <paramref name="frameNumber"/>
    /// drives the sweep-band animation so consecutive calls produce visibly
    /// changing output (the sweep moves down by 2 rows per frame, wrapping).
    /// </summary>
    public static ProcessedFrame Render(int width, int height, long frameNumber, long timestampTicks)
    {
        var pixels = new byte[width * height * 4];
        var barWidth = width / BarColors.Length;
        var sweepRow = (int)((frameNumber * 2) % height);

        for (var y = 0; y < height; y++)
        {
            // Pre-compute row offset and sweep highlight delta for this row.
            // The sweep is a 4-row-tall lighter band that animates down the frame.
            var isSweep = Math.Abs(y - sweepRow) < 4;
            for (var x = 0; x < width; x++)
            {
                var barIdx = Math.Min(x / barWidth, BarColors.Length - 1);
                var (b, g, r) = BarColors[barIdx];
                if (isSweep)
                {
                    // Brighten the bar 32 BGR units (clamped) â€” visible moving band.
                    b = (byte)Math.Min(255, b + 32);
                    g = (byte)Math.Min(255, g + 32);
                    r = (byte)Math.Min(255, r + 32);
                }
                var off = (y * width + x) * 4;
                pixels[off + 0] = b;
                pixels[off + 1] = g;
                pixels[off + 2] = r;
                pixels[off + 3] = 0xFF;
            }
        }
        return new ProcessedFrame(width, height, timestampTicks, pixels, PixelFormat.Bgra);
    }
}
