#version 460

#extension GL_GOOGLE_include_directive : require
#extension GL_EXT_debug_printf : require

#define FRAG_SHADER

#include "gui.layout"

layout (location = 0) FragDataFlat
{
	vec2 atlas_size;
	uint has_texture;
} FDF;

layout (location = 2) FragData
{
	vec4  color;
	vec2  uv;
	vec2  dst_pos;
	vec2  dst_center;
	vec2  dst_half_size;
	vec2  sdf_sample_pos;
	float corner_radius;
	float softness;
	float raised;
	float border_thickness;
} FD;

layout (location = 0) out vec4 FragColor;

float 
RectSDF(vec2 pos, vec2 half_size, float radius)
{
	return length(max(abs(pos) - half_size + radius, 0.0)) - radius;
}

float 
ToSRGB(float col)
{
	return pow(col, 1.0/2.2);
}

vec4 
ToSRGB(vec4 col)
{
	return vec4(ToSRGB(col.r), ToSRGB(col.g), ToSRGB(col.b), col.a);
}

vec4 
ToLinear(vec4 col)
{
	return pow(col, vec4(vec3(2.2), 1.0));
}

float 
GradientNoise(vec2 uv)
{
	return fract(52.9829189 * fract(dot(uv, vec2(0.06711056, 0.00583715))));
}

float 
Median(vec3 v)
{
	return max(min(v.r, v.g), min(max(v.r, v.g), v.b));
}

vec2
Square(vec2 x)
{
	return x*x;
}

float 
ScreenPxRange()
{
	vec2 screen_tex_size = vec2(1.0)/fwidth(FD.uv);
	return max(0.5*dot(vec2(0.03125), screen_tex_size), 1.0);
}

void main()
{
	float softness = FD.softness;
	vec2 softness_padding = vec2(max(0, softness*2-1), max(0, softness*2-1));

	float border_factor = 1.0;
	if(FD.border_thickness > 0.0)
	{
		float border_sdf = RectSDF(FD.sdf_sample_pos, 
															 FD.dst_half_size - vec2(FD.softness*2.0f) - FD.border_thickness,
															 max(FD.corner_radius - FD.border_thickness, 0.0f));
		border_factor = smoothstep(0.0f, 2.0f * FD.softness, border_sdf);
	}

	if(border_factor < 0.001f)
	{
		discard;
	}

	float corner_factor = 1.0;
	if(FD.corner_radius > 0.0 || FD.softness > 0.0)
	{
		float corner_sdf = RectSDF(FD.sdf_sample_pos,
														   FD.dst_half_size - vec2(FD.softness * 2.0f),
														 	 FD.corner_radius);
		corner_factor = 1.0f - smoothstep(0.0, 2.0f * FD.softness, corner_sdf);
	}

	vec4 inv_gamma = vec4(1.4);
	vec4 gamma = vec4(1.0/1.4);

	vec4 tex_color = vec4(1.0); // ToLinear(FD.color);
	if(FDF.has_texture != 0)
	{
		tex_color = texture(SpriteAtlas, FD.uv);
	}

	vec4 color = FD.color * tex_color;

	color.a  *= corner_factor;
	color.a  *= border_factor;

	color    += (1.0 / 255.0) * GradientNoise(gl_FragCoord.xy);

	FragColor = color;
}
