precision mediump float;

varying vec2 v_geo;

uniform vec4 color;
uniform vec2 size;
uniform vec4 corner_radius;
uniform float border_width;
uniform float scale;

float rounding_alpha(vec2 coords, vec2 half_size, vec4 radii) {
	float radius;
	vec2 center;

	if (coords.x < half_size.x && coords.y < half_size.y) {
		radius = radii.x; // top-left
		center = vec2(radius, radius);
	} else if (coords.x >= half_size.x && coords.y < half_size.y) {
		radius = radii.y; // top-right
		center = vec2(size.x - radius, radius);
	} else if (coords.x >= half_size.x && coords.y >= half_size.y) {
		radius = radii.z; // bottom-right
		center = vec2(size.x - radius, size.y - radius);
	} else {
		radius = radii.w; // bottom-left
		center = vec2(radius, size.y - radius);
	}

	if (radius == 0.0)
		return 1.0;

	float dist = distance(coords, center);
	float half_px = 0.5 / scale;
	return 1.0 - smoothstep(radius - half_px, radius + half_px, dist);
}

void main() {
	vec2 half_size = size / 2.0;
	float outer_alpha = rounding_alpha(v_geo, half_size, corner_radius);

	float inner_alpha = 0.0;
	if (border_width > 0.0) {
		vec2 inner_coords = v_geo - vec2(border_width);
		vec2 inner_size = size - vec2(border_width * 2.0);
		vec2 inner_half = inner_size / 2.0;
		vec4 inner_radii = max(corner_radius - vec4(border_width), vec4(0.0));

		if (inner_coords.x >= 0.0 && inner_coords.y >= 0.0 &&
			inner_coords.x <= inner_size.x && inner_coords.y <= inner_size.y) {
			inner_alpha = rounding_alpha(inner_coords, inner_half, inner_radii);
		}
	}

	float a = outer_alpha * (1.0 - inner_alpha);
	gl_FragColor = color * a;
}
