#version 440

layout(location = 0) in vec2 qt_TexCoord0;
layout(location = 0) out vec4 fragColor;

layout(std140, binding = 0) uniform buf {
    mat4 qt_Matrix;
    float qt_Opacity;
    float time;
    float warpStrength;
    float flowSpeed;
    float scale;
    float edgeReflectionStrength;
    float edgeReflectionWidth;
} ubuf;

layout(binding = 1) uniform sampler2D source;

// Smooth noise function for organic liquid movement
float noise(vec2 p) {
    return sin(p.x * 1.5) * sin(p.y * 1.5);
}

// Fractal noise for more complex patterns
float fbm(vec2 p) {
    float value = 0.0;
    float amplitude = 0.5;

    for(int i = 0; i < 4; i++) {
        value += amplitude * noise(p);
        p *= 2.0;
        amplitude *= 0.5;
    }
    return value;
}

void main() {
    vec2 uv = qt_TexCoord0;

    // Create flowing liquid-like distortion
    vec2 flowDir1 = vec2(
        fbm(uv * ubuf.scale + ubuf.time * ubuf.flowSpeed),
        fbm(uv * ubuf.scale + ubuf.time * ubuf.flowSpeed + 100.0)
    );

    vec2 flowDir2 = vec2(
        fbm(uv * ubuf.scale * 0.7 - ubuf.time * ubuf.flowSpeed * 0.8 + 200.0),
        fbm(uv * ubuf.scale * 0.7 - ubuf.time * ubuf.flowSpeed * 0.8 + 300.0)
    );

    // Combine flows for more organic movement
    vec2 finalFlow = (flowDir1 + flowDir2 * 0.5) * ubuf.warpStrength * 0.01;

    // Apply subtle chromatic aberration
    float aberration = length(finalFlow) * 0.5;

    vec2 distortedUV = uv + finalFlow;

    // Sample with slight chromatic separation for main glass effect
    float r = texture(source, distortedUV + vec2(aberration, 0.0)).r;
    float g = texture(source, distortedUV).g;
    float b = texture(source, distortedUV - vec2(aberration, 0.0)).b;

    vec4 glassColor = vec4(r, g, b, 1.0);

    // Simple edge reflection 
    float edgeWidth = ubuf.edgeReflectionWidth;

    // Calculate distance from edges
    float distFromLeft = uv.x;
    float distFromRight = 1.0 - uv.x;
    float distFromTop = uv.y;
    float distFromBottom = 1.0 - uv.y;

    // Find the minimum distance to any edge
    float minDistToEdge = min(min(distFromLeft, distFromRight), min(distFromTop, distFromBottom));

    // Create edge mask
    float edgeMask = smoothstep(edgeWidth, 0.0, minDistToEdge);

    if (edgeMask > 0.0) {
        vec2 reflectionUV = distortedUV;

        // Simple reflection logic
        if (minDistToEdge == distFromLeft) {
            // Left edge - flip horizontally
            reflectionUV.x = 0.5 - distortedUV.x;
        } else if (minDistToEdge == distFromRight) {
            // Right edge - keep as is but sample from further right
            reflectionUV.x = distortedUV.x + 0.1;
        } else if (minDistToEdge == distFromTop) {
            // Top edge - flip vertically
            reflectionUV.y = 0.5 - distortedUV.y;
        } else {
            // Bottom edge - flip vertically
            reflectionUV.y = 0.5 - distortedUV.y + 0.1;
        }

        // Clamp to valid range
        reflectionUV = clamp(reflectionUV, 0.0, 1.0);

        // Sample reflection with same chromatic aberration
        float rRefl = texture(source, reflectionUV + vec2(aberration, 0.0)).r;
        float gRefl = texture(source, reflectionUV).g;
        float bRefl = texture(source, reflectionUV - vec2(aberration, 0.0)).b;

        vec4 reflectionColor = vec4(rRefl, gRefl, bRefl, 1.0);

        // Blend reflection with glass effect
        glassColor = mix(glassColor, reflectionColor, edgeMask * ubuf.edgeReflectionStrength);
    }

    // Simple glass overlay enhancement
    vec2 centeredUV = (uv - 0.5) * 2.0;
    float fresnel = pow(1.0 - abs(dot(normalize(vec3(centeredUV, 1.0)), vec3(0.0, 0.0, 1.0))), 1.5);

    // Add subtle white tint and fresnel
    glassColor.rgb = mix(glassColor.rgb, vec3(1.0), 0.02 + fresnel * 0.03);

    fragColor = glassColor * ubuf.qt_Opacity;
}

