/*

const int colortex0Format = R11F_G11F_B10F; // Solid
const int colortex1Format = RGBA16F; //translucent
const int colortex2Format = R11F_G11F_B10F; //translucent




//
const int colortex3Format = RGBA8; //water mask & sun
//
const int colortex4Format = R11F_G11F_B10F; //prev
//
const int colortex6Format = RGBA16F; //sky
//

const int colortex7Format = RG8F; //waternormals
const int colortex8Format = RGBA16F; //sky






///
const int colortex9Format = R11F_G11F_B10F; //Reflections
const int colortex5Format = RGBA16F; //DH
///


////
const int colortex10Format = R8;  // light & ao
const int colortex11Format = RGBA16; // normals
const int colortex12Format = RGBA8; // PBR



const int colortex13Format = RGBA16F; // PBR
const int colortex15Format = RGBA16F; // PBR







// no need to clear the buffers, saves a few fps
/*

const bool colortex1Clear = true;
const bool colortex2Clear = false;

const bool colortex4Clear = false;
const bool colortex6Clear = false;
const bool colortex9Clear = false;


const bool colortex10Clear = false;
const bool colortex11Clear = false;
const bool colortex12Clear = false;

const bool colortex15Clear = false;


*/

varying vec2 texcoord;
uniform sampler2D shadowcolor0;

uniform sampler2D colortex7;
uniform sampler2D colortex0;
uniform sampler2D colortex4;
uniform sampler2D colortex5;
uniform sampler2D colortex2;
uniform sampler2D colortex9;
uniform sampler2D colortex6;
uniform sampler2D colortex13;
uniform sampler2D colortex3;
uniform sampler2D colortex15;

#include "/lib/color_transforms.glsl"
#include "/lib/taa/res_params.glsl"
#include "/lib/uniforms.glsl"
#include "/lib/textrendering.glsl"

//
#define SHARPENING_AMOUNT 1.0 //[0.0 0.025 0.05 0.075 0.1 0.125 0.15 0.20 0.25 0.30 0.50 0.75 1.0 2.0 3.0 4.0 5.0]

//------------------------------------------------------------------------------------------------------------------------------

vec2 r = 1.0 / viewResolution;      //    1/texture_resolution
float strength = SHARPENING_AMOUNT; //  effect strength

vec4 sharp(sampler2D sampler, vec2 uv)
{
    vec4 c0 = texture(sampler, uv);
    vec4 c1 = texture(sampler, uv - vec2(r.x, .0));
    vec4 c2 = texture(sampler, uv + vec2(r.x, .0));
    vec4 c3 = texture(sampler, uv - vec2(.0, r.y));
    vec4 c4 = texture(sampler, uv + vec2(.0, r.y));
    vec4 c5 = c0 + c1 + c2 + c3 + c4;
    c5 *= 0.2;
    vec4 mi = min(c0, c1);
    mi = min(mi, c2);
    mi = min(mi, c3);
    mi = min(mi, c4);
    vec4 ma = max(c0, c1);
    ma = max(ma, c2);
    ma = max(ma, c3);
    ma = max(ma, c4);
    return clamp(mi, (strength + 1.0) * c0 - c5 * strength, ma);
}

//------------------------------------------------------------------------------------------------------------------------------

vec3 adjustVibrance(vec3 color, float userVibrance)
{
    float vibrance = (userVibrance + 100.0) / 100.0; // Normalize to 0 - 2
    float avg = (color.r + color.g + color.b) / 3.0;
    float mx = max(color.r, max(color.g, color.b));
    float baseVibrance = (1.0 - (mx - avg) / mx) * (vibrance - 1.0); // Adjust for user inp

    // Calculate the color's natural saturation to scale vibrance effect
    float colorSaturation = max(max(color.r, color.g), color.b) - min(min(color.r, color.g), color.b);
    float saturationScale = 1.0 - step(0.5, colorSaturation);
    float finalVibrance = baseVibrance * saturationScale;

    return mix(color, vec3(mx), finalVibrance);
}
// Normalize and adjust saturation in linear color space
vec3 adjustSaturation(vec3 color, float userSaturation)
{
    float saturation = (userSaturation + 100.0) / 100.0;        // Normalize to 0 - 2
    float luminance = dot(color, vec3(0.2126, 0.7152, 0.0722)); // Luminance in linear space
    return mix(vec3(luminance), color, saturation);             // Adjust saturation linearly
}

#define VIBRANCE 40.0  // [-100.0 -80.0 -60.0 -40.0 -20.0 0.0 20.0 35.0 40.0 60.0 80.0 100.0]
#define SATURATION 1.0 // [-100.0 -80.0 -60.0 -40.0 -20.0 0.0 20.0 40.0 60.0 80.0 100.0]
#define HDR_MAX 16.0   // [8.0 10.0 12.0 14.0 16.0 18.0 20.0]

#define EXPOSURE 1.0  // [0.0 0.05 0.10 0.15 0.20 0.25 0.30 0.35 0.40 0.45 0.50 0.55 0.60 0.65 0.70 0.75 0.80 0.85 0.90 0.95 1.00 1.05 1.10 1.15 1.20 1.25 1.30 1.35 1.40 1.45 1.50 1.55 1.60 1.65 1.70 1.75 1.80 1.85 1.90 1.95 2.00]
#define CONTRAST 0.99 // [0.0 0.05 0.10 0.15 0.20 0.25 0.30 0.35 0.40 0.45 0.50 0.55 0.60 0.65 0.70 0.75 0.80 0.85 0.90 0.95 0.97 0.99 1.00 1.05 1.10 1.15 1.20 1.25 1.30 1.35 1.40 1.45 1.50 1.55 1.60 1.65 1.70 1.75 1.80 1.85 1.90 1.95 2.00]
#define SHOULDER 0.90 // [0.0 0.05 0.10 0.15 0.20 0.25 0.30 0.35 0.40 0.45 0.50 0.55 0.60 0.65 0.70 0.75 0.80 0.85 0.90 0.95 1.00 1.05 1.10 1.15 1.20 1.25 1.30 1.35 1.40 1.45 1.50 1.55 1.60 1.65 1.70 1.75 1.80 1.85 1.90 1.95 2.00]
#define MID_IN 0.3    // [0.0 0.05 0.10 0.15 0.20 0.25 0.30 0.35 0.40 0.45 0.50 0.55 0.60 0.65 0.70 0.75 0.80 0.85 0.90 0.95 1.00 1.05 1.10 1.15 1.20 1.25 1.30 1.35 1.40 1.45 1.50 1.55 1.60 1.65 1.70 1.75 1.80 1.85 1.90 1.95 2.00]
#define MID_OUT 0.25  // [0.0 0.05 0.10 0.15 0.20 0.25 0.30 0.35 0.40 0.45 0.50 0.55 0.60 0.65 0.70 0.75 0.80 0.85 0.90 0.95 1.00 1.05 1.10 1.15 1.20 1.25 1.30 1.35 1.40 1.45 1.50 1.55 1.60 1.65 1.70 1.75 1.80 1.85 1.90 1.95 2.00]

vec3 tonemap(vec3 color)
{

    // Tonemapping constants

    const float vibrance = VIBRANCE;
    const float saturation = SATURATION;

    const float exposure = EXPOSURE;
    const float Contrast = CONTRAST;
    const float Shoulder = SHOULDER;
    const float HdrMax = HDR_MAX;
    const float MidIn = MID_IN;
    const float MidOut = MID_OUT;

    // Apply exposure to the inp color
    color *= exposure;
    // Precompute parts of the tonemapping equation
    float A = pow(MidIn, Contrast);
    float D = pow(HdrMax, Contrast);
    float B = pow(HdrMax, Contrast * Shoulder);
    float C = pow(MidIn, Contrast * Shoulder);
    float b = (-A + D * MidOut) / ((B - C) * MidOut);
    float c = (B * A - D * C * MidOut) / ((B - C) * MidOut);

    // Apply the tonemapping curve
    color = pow(color, vec3(Contrast)) / (pow(color, vec3(Contrast * Shoulder)) * b + c);

    color = adjustVibrance(color, 1 - vibrance);
    color = adjustSaturation(color, saturation);

    // White balance adjustment

    return color;
}

//==============================================================

//==============================================================

#define Purkinje_strength 2.0
#define Purkinje_R 0.2
#define Purkinje_G 0.5
#define Purkinje_B 1.0
#define Purkinje_Multiplier 4.0
////
#ifdef BLOOM

const bool colortex6MipmapEnabled = true;

vec4 apply_vertical_blur(sampler2D t0, vec2 tex_coord, ivec2 size, float bloom_spread, float weights[9])
{
    float uv_x = tex_coord.x * size.x;
    float uv_y = tex_coord.y * size.y;

    vec4 v_sum = vec4(0.0);

    for (int n = 0; n < 9; ++n)
    {
        float offset = float(n - 4) * bloom_spread;
        v_sum += texture(t0, vec2(uv_x, uv_y + offset) / size) * weights[n];
    }

    return v_sum;
}

vec4 apply_bloom_v(sampler2D t0, vec2 tex_coord)
{
    const float bloom_spread = 16.0;
    const float bloom_intensity = 1.0;
    ivec2 size = ivec2(viewResolution);

    // Gaussian weights
    float weights[9] = float[](0.05, 0.09, 0.12, 0.15, 0.18, 0.15, 0.12, 0.09, 0.05);

    vec4 v_blur = apply_vertical_blur(t0, tex_coord, size, bloom_spread, weights);

    return v_blur * bloom_intensity;
}

#endif
uniform float aspectRatio;

#include "/lib/sky_gradient.glsl"
const vec4 colortex1ClearColor = vec4(0, 0, 0, 0);
uniform mat4 gbufferProjection;
void main()
{

#ifdef DOF

#ifdef TAA
    // vec3 color = sharp(colortex0, texcoord).rgb;
    vec3 color = texture(colortex0, texcoord.xy).rgb;

#else
    vec3 color = texture(colortex0, texcoord.xy).rgb;
#endif

#else
#ifdef TAA
    vec3 color = sharp(colortex4, texcoord).rgb;
#else
    vec3 color = texture(colortex4, texcoord.xy).rgb;
#endif
#endif
#ifdef BLOOM

    vec3 sum = apply_bloom_v(colortex6, texcoord).rgb;

    color += sum * 0.025;
#endif

#ifdef SHADOW_DEBUG

    color = texture(shadowcolor0, texcoord).rgb;
#endif
    // color = texture(colortex13, texcoord).rgb;

    color = tonemap(color);
    float lum = dot(color, vec3(0.15, 0.3, 0.55));
    float rodLum = dot(color, vec3(0.85, 0.7, 0.45)) * 200.0;
    float rodCurve = mix(1.0, rodLum / (2.5 + rodLum), 1.0 / (2.0 * Purkinje_strength));
    color = mix(clamp(lum, 0.0, 0.05) * Purkinje_Multiplier * vec3(Purkinje_R, Purkinje_G, Purkinje_B) + 1.5e-3, color,
                rodCurve);

    color = clamp(LinearTosRGB(color), 0, 1);


/*
    beginText(ivec2(gl_FragCoord.xy * 0.25), ivec2(viewWidth * 0.25 * 0.5, viewHeight * 0.25));
    printString((_L, _u, _m, _a, _space));
    printLine();
    printString((_L, _u, _m, _a, _space));

    printFloat(focalLength.x);
    endText(color);

    // To start a new line, use
    printLine();

    // You can print various data types
    printBool(false);
    printLine();
    printFloat(sqrt(-1.0)); // Prints "NaN"
    printLine();
    printInt(42);
    printLine();
    printVec3(color);
    printLine();
    // ...or arbitrarily long strings
    printString((_H, _e, _l, _l, _o, _comma, _space, _w, _o, _r, _l, _d));

    // You can also configure the text color on the fly
    text.fgCol = vec4(1.0, 0.0, 0.0, 1.0);
    text.bgCol = vec4(0.0, 0.0, 0.0, 1.0);

    // ...as well as the number base and number of decimal places to print
    text.base = 16;
    text.fpPrecision = 4;

    // Finally, call endText to blend the current fragment color with the text
    endText(color);
*/
    gl_FragData[0] = vec4(color, 1);
    // gl_FragData[0] = vec4(atmosphereUp,1);
}