#version 410

#pragma include "filter_common.glsl"
#pragma include "spect.glsl"

//#define SPECT

uniform sampler2D u_SpectrogramTex;
uniform float u_Time;
uniform bool u_Waveform;
uniform sampler2D u_WaveformTex;

// Author Attribution:
// This tone mapping function is inspired by the Uncharted 2 video game's tone mapping curve.
// The Uncharted 2 tone mapping formula is well-known for its ability to produce realistic high dynamic range (HDR) lighting effects
// while preserving image details, even in very bright scenes.
// This function is based on the work of John Hable, who developed this approach for Naughty Dog’s Uncharted 2.
// - Reference: John Hable's blog "Filmic Tonemapping" (http://filmicworlds.com/blog/filmic-tonemapping-operators/)
vec3 applyToneMapUncharted2(vec3 color) {
    // Constants derived from John Hable's tone mapping curve
    const float A = 0.15;
    const float B = 0.50;
    const float C = 0.10;
    const float D = 0.20;
    const float E = 0.02;
    const float F = 0.30;
    const float W = 11.2;

    // Apply the Uncharted 2 tone mapping formula
    vec3 mapped_color = ((color * (A * color + C * B) + D * E) / (color * (A * color + B) + D * F)) - E / F;

    // Normalize by white point
    vec3 white_scale = vec3(1.0) / ((W * (A * W + C * B) + D * E) / (W * (A * W + B) + D * F) - E / F);

    return mapped_color * white_scale;
}


void main() {
//    p3d_FragColor = texture(p3d_Texture0, uv);
    p3d_FragColor = vec4(texture(p3d_Texture0, uv).rgb, 1.0);

    // Tone mapping
    p3d_FragColor.rgb = applyToneMapUncharted2(p3d_FragColor.rgb) * u_MasterFade;

    #ifdef SPECT
        #define BOT 0.0
        #define TOP 1.0
        #define RANGE (TOP - BOT)
        if (uv.y > BOT && uv.y < TOP) {
            vec4 spectColor = textureSpect(u_SpectrogramTex, vec2(uv.x, (uv.y - BOT) / RANGE), u_Time);
            p3d_FragColor = vec4(mix(p3d_FragColor.rgb, spectColor.rgb, spectColor.a * 0.9), 1.0);
        }
    #endif

    bool u_Waveform = false;
    if (u_Waveform) {
        #define DIAMETER 16.0
        #define LENGTH 50.0
//        uv.x = round(uv.x * LENGTH) / LENGTH;
//        uv.y = round(uv.y * (DIAMETER * 2.)) / (DIAMETER * 2.);
        uv.x *= 1.0;
        vec2 waveSize = textureSize(u_WaveformTex, 0);
        float waveformAmp = texture(u_WaveformTex, vec2(uv.x * 1.0, 1.0 - (u_Time * 60.0) / waveSize.y)).r;
        waveformAmp /= 2.;
        if (abs(uv.y - 0.5) <=  waveformAmp) {
            p3d_FragColor = mix(p3d_FragColor, vec4(1.0, 0.0, 0.0, 1.0), 0.5);
        }

    }

//    p3d_FragColor.rgb = 1.0 - p3d_FragColor.rgb;

}
