#version 330 core
// Stage 1i plate-model Shake: RGBA sampling, no YUV/orient.
// Effect math (single-direction bezier displacement + directional
// motion blur + edge reflection + hard A/B cut) ported verbatim from
// transition_shake.fs. The signed `u_translateUV` displacement and
// `u_motionBlurOffsetUV` are computed CPU-side by `shakePlatePhase()`
// exactly as the legacy single-pass path did, so both Shake1
// (diagonal) and Shake2 (axis) are byte-faithful.
//
// Plate sampling: plates are FBO-backed RGBA8 (Y-up) while TexCoord is
// Y-down, so each sample flips Y. Premultiplied alpha is preserved
// through the mix / blur average.

out vec4 FragColor;
in  vec2 TexCoord;

uniform sampler2D u_planeA;
uniform sampler2D u_planeB;

uniform float u_progress;
uniform vec2  u_translateUV;          // signed displacement, Y already flipped to UV-down
uniform vec2  u_motionBlurOffsetUV;   // blur direction * magnitude in UV space

// Edge reflection: maps any real UV to [0, 1] via a period-2 triangle
// wave. f(0)=0, f(1)=1, f(2)=0, f(-0.3)=0.3, etc.
vec2 reflectUv(vec2 uv) {
    uv = mod(uv, 2.0);
    return 1.0 - abs(uv - 1.0);
}

vec4 samplePlateReflect(sampler2D plate, vec2 uv) {
    uv = reflectUv(uv);
    return texture(plate, vec2(uv.x, 1.0 - uv.y));
}

// 41-tap motion blur along `offset`, triangular weighting.
vec4 motionBlur(sampler2D plate, vec2 uv, vec2 offset) {
    const int kHalfTaps = 20;    // 41 total samples, ~24 px/tap at 1920w peak
    vec4 acc = vec4(0.0);
    float total = 0.0;
    for (int i = -kHalfTaps; i <= kHalfTaps; ++i) {
        float t = float(i) / float(kHalfTaps);
        float w = 1.0 - abs(t);
        acc   += w * samplePlateReflect(plate, uv + t * offset);
        total += w;
    }
    return acc / total;
}

void main() {
    vec2 uv = TexCoord;
    float p = clamp(u_progress, 0.0, 1.0);

    vec2 uvA = uv + u_translateUV;
    vec2 uvB = uv + u_translateUV;

    vec4 aRgba = motionBlur(u_planeA, uvA, u_motionBlurOffsetUV);
    vec4 bRgba = motionBlur(u_planeB, uvB, u_motionBlurOffsetUV);

    // Hard cut at progress = 0.5; the percussive moment is visually
    // masked by the peak displacement + motion blur.
    float cut = smoothstep(0.48, 0.52, p);
    FragColor = mix(aRgba, bRgba, cut);
}
