#ifndef PRIMITIVES_H
#define PRIMITIVES_H

#include <stdbool.h>

// Waveform data structure (mirrors AudioSignal for scope rendering)
typedef struct {
    float* samples;
    int numSamples;
    int sampleRate;
} WaveformData;

// Per-bucket amplitude extremes, the unit of the envelope summary below.
typedef struct { float mn, mx; } WaveMinMax;

// Precomputed min/max summary of the signal so drawing the waveform costs
// O(pixels) instead of O(visible samples).
//
// Without it the scope rescanned every visible sample every frame: on a
// multi-hour capture that is hundreds of millions of reads (~1 GB of memory
// traffic) to produce a few hundred pixel columns, measured at ~60 ms/frame —
// a 16 fps ceiling before anything else drew. Bucketing collapses that to a
// few reads per column. Keeping the true min AND max per bucket is what lets
// a one-sample transient still show at full zoom-out; plain decimation would
// drop it, which matters when the whole point is spotting brief bursts.
//
// Used only when a pixel column spans at least one whole bucket. Zoomed in
// past that the scope reads raw samples, which is cheap precisely because few
// are visible. `samples`/`numSamples` record what the summary was built from,
// so a new file (or re-decoded buffer) invalidates it automatically.
typedef struct {
    WaveMinMax* buckets;
    int bucketCount;
    int bucketSize;          // samples per bucket
    const float* samples;    // provenance: buffer this was built from
    int numSamples;
} WaveEnvelope;

// Build (or rebuild, if the source buffer changed) the envelope summary.
// Safe to call every frame: returns immediately when already current.
void BuildWaveEnvelope(WaveEnvelope* env, const float* samples, int numSamples);
void FreeWaveEnvelope(WaveEnvelope* env);

// Scope view state for time/amplitude waveform display
typedef struct {
    WaveformData data;
    WaveEnvelope envelope;   // cached min/max summary; rebuilt when data changes
    
    // View bounds (in pixels)
    int x, y;
    int width, height;
    
    // Time view (0-1 normalized within the signal)
    float viewStart;      // start of visible time
    float viewEnd;        // end of visible time
    
    // Amplitude view
    float ampMin;         // minimum visible amplitude (-1.0 to 1.0)
    float ampMax;         // maximum visible amplitude
    
    // Cursor/selection
    float cursorT;        // 0-1 normalized time position of cursor
    
    // Display settings
    bool showGrid;
    float gridAlpha;      // 0-1 alpha for grid lines
    
    // Background color
    int bgColorR, bgColorG, bgColorB, bgColorA;
    
    // Grid color
    int gridR, gridG, gridB, gridA;
} ScopeView;

// Initialize a scope view with bounds and waveform
void InitScopeView(ScopeView* view, WaveformData data, int x, int y, int width, int height);

// Draw the scope view with optional cursor/playhead
void DrawScopeView(ScopeView* view, float cursorT);

#endif // PRIMITIVES_H
