#version 330

in vec2 fragTexCoord;
in vec4 fragColor;

uniform sampler2D texture0;
uniform sampler2D distanceFieldTex;
uniform vec2 resolution;
uniform vec2 mousePos;
uniform float ballRadius;
uniform float shapeInfluence;

out vec4 finalColor;

float getBallInfluence(vec2 pos, vec2 center, float radius) {
    vec2 diff      = pos - center;
    float distSq   = dot(diff, diff);
    float radiusSq = radius * radius;
    if (distSq > radiusSq) return 0.0;
    float dist = sqrt(distSq);
    return 1.0 - (dist / radius);
}

float getShapeInfluence(vec2 pos) {
    vec2 uv = pos / resolution;
    uv.y = 1.0 - uv.y;

    if (any(lessThan(uv, vec2(0.0))) || any(greaterThan(uv, vec2(1.0)))) return 0.0;

    float signedDistance = texture(distanceFieldTex, uv).r * 255.0 - 128.0;

    float isInside  = step(signedDistance, 0.0);
    float isOutside = 1.0 - isInside;

    // inside calculation
    float normalizedDist  = abs(signedDistance) * 0.015625; // 1/64
    float insideInfluence = shapeInfluence * exp(-normalizedDist * 0.5) * 3.0;

    // outside calculation
    float adjustedDistance = signedDistance * 0.5;
    float shapeInfluenceSq = shapeInfluence * shapeInfluence;
    float outsideInfluence = shapeInfluenceSq / (adjustedDistance * adjustedDistance + shapeInfluence) +
                             shapeInfluence * 0.8 * exp(-signedDistance * 0.025); // 1/40

    return isInside * insideInfluence + isOutside * outsideInfluence;
}

void main() {
    vec2 pixelPos = fragTexCoord * resolution;

    float ballValue  = getBallInfluence(pixelPos, mousePos, ballRadius);
    float shapeValue = getShapeInfluence(pixelPos);
    float totalValue = ballValue + shapeValue * 0.01;

    float mask = step(0.75, totalValue);
    finalColor = vec4(mask, mask, mask, 1.0);
}
