// Note: SDF by Iñigo Quilez is licensed under MIT License

#version 330

// Input vertex attributes (from vertex shader)
in vec2 fragTexCoord;
in vec4 fragColor;

// Input uniform values
uniform sampler2D texture0;
uniform vec4 colDiffuse;

// Output fragment color
out vec4 finalColor;

uniform vec4 rectangle; // Rectangle dimensions (x, y, width, height)
uniform vec4 radius; // Corner radius (top-left, top-right, bottom-left, bottom-right)
uniform vec4 color;

// Shadow parameters
uniform float shadowRadius;
uniform vec2 shadowOffset;
uniform float shadowScale;
uniform vec4 shadowColor;

// Border parameters
uniform float borderThickness;
uniform vec4 borderColor;

// Create a rounded rectangle using signed distance field
// Thanks to Iñigo Quilez (https://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm)
// And thanks to inobelar (https://www.shadertoy.com/view/fsdyzB) for shader
// MIT License
float RoundedRectangleSDF(vec2 fragCoord, vec2 center, vec2 halfSize, vec4 radius)
{
    vec2 fragFromCenter = fragCoord - center;

    // Determine which corner radius to use
    radius.xy = (fragFromCenter.y > 0.0) ? radius.xy : radius.zw;
    radius.x  = (fragFromCenter.x < 0.0) ? radius.x  : radius.y;

    // Calculate signed distance field
    vec2 dist = abs(fragFromCenter) - halfSize + radius.x;
    return min(max(dist.x, dist.y), 0.0) + length(max(dist, 0.0)) - radius.x;
}

void main()
{
    // Texel color fetching from texture sampler
    vec4 texelColor = texture(texture0, fragTexCoord);

    // Requires fragment coordinate in pixels
    vec2 fragCoord = gl_FragCoord.xy;

    // Calculate signed distance field for rounded rectangle
    vec2 halfSize = rectangle.zw*0.5;
    vec2 center = rectangle.xy + halfSize;
    float recSDF = RoundedRectangleSDF(fragCoord, center, halfSize, radius);

    // Calculate signed distance field for rectangle shadow
    vec2 shadowHalfSize = halfSize*shadowScale;
    vec2 shadowCenter = center + shadowOffset;
    float shadowSDF = RoundedRectangleSDF(fragCoord, shadowCenter, shadowHalfSize, radius);

    // Caculate alpha factors
    float recFactor = smoothstep(1.0, 0.0, recSDF);
    float shadowFactor = smoothstep(shadowRadius, 0.0, shadowSDF);
    float borderFactor = smoothstep(0.0, 1.0, recSDF + borderThickness)*recFactor;

    // Multiply each color by its respective alpha factor
    vec4 recColor = vec4(color.rgb, color.a*recFactor);
    vec4 shadowCol = vec4(shadowColor.rgb, shadowColor.a*shadowFactor);
    vec4 borderCol = vec4(borderColor.rgb, borderColor.a*borderFactor);

    // Combine the colors in the order (shadow, rectangle, border)
    finalColor = mix(mix(shadowCol, recColor, recColor.a), borderCol, borderCol.a);
}