// Shared confidence-aware temporal accumulation helpers.
#ifndef NOISE_TEMPORAL_GLSL
#define NOISE_TEMPORAL_GLSL

#include "/lib/noise_options.glsl"

// Metadata is stored in a normalized channel, so keep the encoding range
// stable even when the user selects a shorter temporal window.
#define NOISE_TEMPORAL_MAX_FRAMES 16.0

float noiseTemporalTargetSamples() {
    return clamp(float(TEMPORAL_FRAMES), 1.0, NOISE_TEMPORAL_MAX_FRAMES);
}

float noiseTemporalDecodeSamples(float encodedSamples) {
    return clamp(encodedSamples * NOISE_TEMPORAL_MAX_FRAMES,
        0.0, noiseTemporalTargetSamples());
}

float noiseTemporalEncodeSamples(float sampleCount) {
    return clamp(sampleCount / NOISE_TEMPORAL_MAX_FRAMES, 0.0, 1.0);
}

// Returns (history weight, encoded new sample count). Confidence discounts
// stale samples before adding the current one: stable pixels converge to the
// selected window, while motion and responsive surfaces forget history fast.
vec2 noiseTemporalAccumulate(float encodedPreviousSamples, float historyConfidence) {
    float targetSamples = noiseTemporalTargetSamples();
    float previousSamples = noiseTemporalDecodeSamples(encodedPreviousSamples);
    float retainedSamples = min(previousSamples * clamp(historyConfidence, 0.0, 1.0),
        targetSamples - 1.0);
    float accumulatedSamples = retainedSamples + 1.0;
    float historyWeight = retainedSamples / max(accumulatedSamples, 1.0);
    return vec2(historyWeight, noiseTemporalEncodeSamples(accumulatedSamples));
}

#endif
