#version 450
layout(location = 0) in  vec2 v_uv;
layout(location = 0) out vec4 out_color;

layout(set = 2, binding = 0) uniform sampler2D source;

layout(set = 3, binding = 0) uniform DownscaleUniforms {
    int algorithm;  // 0 = Lanczos2 (ventana 2, ±2 taps), 1 = Lanczos3 (ventana 3, ±3 taps)
    float pad0;
    float pad1;
    float pad2;
} u;

// Kernel Lanczos normalizado: sinc(t) * sinc(t/a) para |t| < a, 0 fuera.
float lanczos(float t, float a) {
    t = abs(t);
    if (t < 0.0001) { return 1.0; }
    if (t >= a) { return 0.0; }
    const float PI = 3.14159265358979;
    float pt = PI * t;
    return (a * sin(pt) * sin(pt / a)) / (pt * pt);
}

void main() {
    vec2 src_size = vec2(textureSize(source, 0));
    // Posición en coordenadas de texel (centros de texel en N+0.5)
    vec2 p = v_uv * src_size;
    vec2 p_floor = floor(p);

    float a = (u.algorithm == 0) ? 2.0 : 3.0;
    int win = int(a);

    vec4 color = vec4(0.0);
    float weight_sum = 0.0;

    for (int j = -win; j <= win; j++) {
        for (int i = -win; i <= win; i++) {
            // Centro del texel (i,j) relativo a p_floor
            vec2 tap_center = p_floor + vec2(float(i), float(j)) + 0.5;
            vec2 offset = tap_center - p;
            float w = lanczos(offset.x, a) * lanczos(offset.y, a);
            color += texture(source, tap_center / src_size) * w;
            weight_sum += w;
        }
    }

    out_color = (weight_sum > 0.0) ? (color / weight_sum) : vec4(0.0, 0.0, 0.0, 1.0);
}
