#version 330 core
// Stage 1h plate-model Overlay: RGBA sampling.
// Effect math (per-variant alpha curve + Light's 5x5 highlight
// extract + Blink's curved curtain) ported from transition_overlay.fs.
// The shader only samples plateA -- the legacy single-clip overlay
// behaviour where plateB aliases to plateA is preserved by the
// dispatch layer.

out vec4 FragColor;
in  vec2 TexCoord;

uniform sampler2D u_planeA;

uniform float u_progress;
uniform int   u_variant;

vec4 samplePlateClamped(sampler2D plate, vec2 uv) {
    if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) {
        return vec4(0.0);
    }
    return texture(plate, vec2(uv.x, 1.0 - uv.y));
}

float alphaForVariant(int variant, float p) {
    if (variant == 0 || variant == 1) {
        return 1.0 - abs(2.0 * p - 1.0);
    }
    if (variant == 2) {
        float dx = (p - 0.5) / 0.12;
        return exp(-0.5 * dx * dx);
    }
    if (variant == 3) {
        float close = smoothstep(0.0, 0.25, p);
        float open  = 1.0 - smoothstep(0.75, 1.0, p);
        return min(close, open);
    }
    return 0.0;
}

vec3 colorForVariant(int variant) {
    if (variant == 1 || variant == 2) {
        return vec3(1.0);
    }
    return vec3(0.0);
}

void main() {
    float p = clamp(u_progress, 0.0, 1.0);
    int variant = clamp(u_variant, 0, 3);

    vec4 aRgba = samplePlateClamped(u_planeA, TexCoord);

    vec3 rgb;
    if (variant == 2) {
        // Light: 12-tap Poisson disk highlight blur. Fully inlined —
        // no macros or const arrays to avoid driver compat issues.
        const float kPi2 = 1.5707963267948966;
        float cp = min(p, 1.0 - p) * 2.0;
        float thr = clamp(cos(cp * kPi2), 0.2, 1.0);
        float lo  = thr - 0.15;
        float D   = 0.045 * cp;
        vec2 uv = TexCoord;
        vec3 r0  = samplePlateClamped(u_planeA, uv).rgb;
        vec3 r1  = samplePlateClamped(u_planeA, uv + vec2(-0.326,-0.406)*D).rgb;
        vec3 r2  = samplePlateClamped(u_planeA, uv + vec2(-0.840,-0.074)*D).rgb;
        vec3 r3  = samplePlateClamped(u_planeA, uv + vec2(-0.696, 0.457)*D).rgb;
        vec3 r4  = samplePlateClamped(u_planeA, uv + vec2(-0.203, 0.621)*D).rgb;
        vec3 r5  = samplePlateClamped(u_planeA, uv + vec2( 0.962,-0.195)*D).rgb;
        vec3 r6  = samplePlateClamped(u_planeA, uv + vec2( 0.473,-0.480)*D).rgb;
        vec3 r7  = samplePlateClamped(u_planeA, uv + vec2( 0.519, 0.767)*D).rgb;
        vec3 r8  = samplePlateClamped(u_planeA, uv + vec2( 0.185,-0.893)*D).rgb;
        vec3 r9  = samplePlateClamped(u_planeA, uv + vec2( 0.507, 0.064)*D).rgb;
        vec3 r10 = samplePlateClamped(u_planeA, uv + vec2( 0.896, 0.412)*D).rgb;
        vec3 r11 = samplePlateClamped(u_planeA, uv + vec2(-0.322,-0.933)*D).rgb;
        vec3 r12 = samplePlateClamped(u_planeA, uv + vec2(-0.792,-0.598)*D).rgb;
        vec3 orig = (r0+r1+r2+r3+r4+r5+r6+r7+r8+r9+r10+r11+r12) / 13.0;
        vec3 hl   = (smoothstep(vec3(lo),vec3(thr),r0) +smoothstep(vec3(lo),vec3(thr),r1)
                    +smoothstep(vec3(lo),vec3(thr),r2) +smoothstep(vec3(lo),vec3(thr),r3)
                    +smoothstep(vec3(lo),vec3(thr),r4) +smoothstep(vec3(lo),vec3(thr),r5)
                    +smoothstep(vec3(lo),vec3(thr),r6) +smoothstep(vec3(lo),vec3(thr),r7)
                    +smoothstep(vec3(lo),vec3(thr),r8) +smoothstep(vec3(lo),vec3(thr),r9)
                    +smoothstep(vec3(lo),vec3(thr),r10)+smoothstep(vec3(lo),vec3(thr),r11)
                    +smoothstep(vec3(lo),vec3(thr),r12)) / 13.0;
        float ease = sin(cp * kPi2);
        rgb = clamp(orig + hl * 5.0 * ease, 0.0, 1.0);
    } else if (variant == 3) {
        // Blink: two black "eyelids" sweep in from the top and bottom
        // edges, meeting in a horizontal-lens (eye) shape -- the
        // opening is tallest at the centre column and tapers to the
        // L/R corners (bows OUTWARD). The lids reach FULL closure with
        // a brief hold at the midpoint before reopening. Matches the
        // Blink panel icon.
        const float kPi = 3.14159265358979323846;
        // closeAmt overshoots 0.5 around the midpoint so the lids fully
        // meet (and hold) at p = 0.5 instead of leaving a centre slit.
        float closeAmt = (0.5 - abs(p - 0.5)) * 1.15;
        float dx  = 2.0 * TexCoord.x - 1.0;
        float arc = 1.0 - dx * dx;          // 1 at centre, 0 at L/R edges
        // Eye-shape curve recesses the lids away from the centre so the
        // opening is tallest there. The sin envelope fades it to zero
        // at both fully-open and fully-closed, so the open state has no
        // stray edge bars and the closed state is solid black.
        float curveEnv = sin(clamp(closeAmt / 0.5, 0.0, 1.0) * kPi);
        float effDepth = closeAmt + 0.12 * (1.0 - arc) * curveEnv;
        float band = 0.02;
        float distToEdge = min(TexCoord.y, 1.0 - TexCoord.y);
        float inBar = 1.0 - smoothstep(effDepth - band, effDepth + band, distToEdge);
        rgb = mix(aRgba.rgb, vec3(0.0), inBar);
    } else {
        float alpha = alphaForVariant(variant, p);
        vec3  ovr   = colorForVariant(variant);
        rgb = mix(aRgba.rgb, ovr, alpha);
    }
    FragColor = vec4(rgb, aRgba.a);
}
