// #include "res://addons/rokojori_action_library/Runtime/Shading/Library/SDF.gdshaderinc"
#include "res://addons/rokojori_action_library/Runtime/Shading/Library/Colors.gdshaderinc"

void computeRectangleBounds( float in_offset, float in_radius, float in_maxRadius, vec2 size, out vec2 minP, out vec2 maxP, out float out_radius )
{
  out_radius = min( in_radius, in_maxRadius );
  float borderSize = out_radius + in_offset;
  minP = vec2( borderSize, borderSize );
  maxP = size - vec2( borderSize, borderSize );
}

float roundedRectangleDistance( vec2 minP, vec2 maxP, vec2 pos)
{
  vec2 leftTop     = minP - pos;
  vec2 bottomRight = pos - maxP;

  vec2 maximum = max( leftTop, bottomRight );
  maximum = max( maximum, vec2(0,0) );

  return length( maximum );
}

float roundedRectangle( vec2 minP, vec2 maxP, vec2 point, float borderSize, float sharp )
{
  float rectangleDistance = roundedRectangleDistance( minP, maxP, point );
  rectangleDistance -= borderSize;
  rectangleDistance *= sharp;

  rectangleDistance = clamp( rectangleDistance, 0.0, 1.0 );

  return 1.0 - rectangleDistance;
}


float sdf_fill( float sd )
{
  return 1.0 - clamp( sd, 0, 1 );
}

float sdf_stroke( float sd, float strokeWidth )
{
  return sdf_fill( abs( sd ) - strokeWidth );
}

vec2 sdf_shape( float sd, float strokeWidth )
{
  float fill   = sdf_fill( sd + strokeWidth );
  float stroke = sdf_stroke( sd, strokeWidth );

  return vec2( fill, stroke ); 
}

vec4 sdf_coloredShape( float _sd, float _strokeWidth, vec4 _fillColor, vec4 _strokeColor )
{
  vec2 _sdf_shape = sdf_shape( _sd, _strokeWidth );
  vec4 _fill = fade( _fillColor, _sdf_shape.x );
  vec4 _stroke = fade( _strokeColor, _sdf_shape.y );

  return blendMode_alpha( _fill, _stroke );
}

/*

TAKEN FROM 
[ Inigo Quilez ]
 
https://iquilezles.org/articles/distfunctions2d/

*/

float dot2( in vec2 v ) { return dot(v,v); }
float dot2( in vec3 v ) { return dot(v,v); }
float ndot( in vec2 a, in vec2 b ) { return a.x * b.x - a.y * b.y; }


float sdCircle( vec2 p, float r )
{
  return length(p) - r;
}

float sdRoundedBox( in vec2 p, in vec2 b, in vec4 r )
{
  r.xy = (p.x>0.0)?r.xy : r.zw;
  r.x  = (p.y>0.0)?r.x  : r.y;
  vec2 q = abs(p)-b+r.x;
  return min(max(q.x,q.y),0.0) + length(max(q,0.0)) - r.x;
}


float sdChamferBox( in vec2 p, in vec2 b, in float chamfer )
{
  p = abs(p)-b;

  p = (p.y>p.x) ? p.yx : p.xy;
  p.y += chamfer;
  
  const float k = 1.0-sqrt(2.0);

  if ( p.y<0.0 && p.y+p.x*k<0.0 )
  { 
    return p.x; 
  }
  
  if( p.x<p.y )
  {
    return (p.x+p.y) * sqrt(0.5) ;
  }
  
  return length(p);
}

float sdBox( in vec2 p, in vec2 b )
{
  vec2 d = abs(p)-b;
  return length(max(d,0.0)) + min(max(d.x,d.y),0.0);
}

float sdSegment( in vec2 p, in vec2 a, in vec2 b )
{
  vec2 pa = p-a, ba = b-a;
  float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );
  return length( pa - ba*h );
}

/*

TAKEN FROM 
[ Inigo Quilez ]
 
https://iquilezles.org/articles/distfunctions/

and changed

*/

float sdPoint( vec3 position, vec3 point )
{
  return length( position - point );
}

float sdSphere( vec3 position, vec3 sphereCenter, float shereRadius )
{
  return length( position - sphereCenter ) - shereRadius;
}

float sdBox( vec3 position, vec3 boxDimensions )
{
  vec3 p = position;
  vec3 b = boxDimensions;

  vec3 q = abs(p) - b;
  return length( max( q, 0.0 ) ) + min( max( q.x, max( q.y, q.z ) ), 0.0 );
}

float sdRoundBox( vec3 position, vec3 boxDimensions, float boxRadius )
{
  vec3 p = position;
  vec3 b = boxDimensions;
  float r = boxRadius;

  vec3 q = abs( p ) - b + r;
  return length( max(q , 0.0 )) + min( max( q.x, max( q.y, q.z ) ), 0.0 ) - r;
}

float sdLine( vec3 position, vec3 lineStart, vec3 lineEnd )
{
  vec3 pa = position - lineStart;
  vec3 ba = lineEnd - lineStart;

  float h = clamp( dot( pa, ba )/ dot( ba, ba ), 0.0, 1.0 );
  return length( pa - ba * h );
}

float sdCapsule( vec3 position, vec3 capsuleStart, vec3 capsuleEnd, float capsuleRadius )
{
  vec3 pa = position - capsuleStart;
  vec3 ba = capsuleEnd - capsuleStart;

  float h = clamp( dot( pa, ba )/ dot( ba, ba ), 0.0, 1.0 );
  return length( pa - ba * h ) - capsuleRadius;
}

float sdRoundCone( vec3 p, vec3 a, vec3 b, float r1, float r2 )
{
  vec3  ba = b - a;
  float l2 = dot( ba, ba );
  float rr = r1 - r2;
  float a2 = l2 - rr * rr;
  float il2 = 1.0 / l2;
    
  vec3 pa = p - a;
  float y = dot( pa, ba );
  float z = y - l2;
  float x2 = dot2( pa * l2 - ba * y );
  float y2 = y * y * l2;
  float z2 = z * z * l2;

  float k = sign( rr ) * rr * rr * x2;
  
  if ( sign( z ) * a2 * z2 > k ) 
  { 
    return sqrt( x2 + z2 ) * il2 - r2;
  }


  if ( sign( y ) * a2 * y2 < k ) 
  { 
    return sqrt( x2 + y2 ) * il2 - r1;
  }
  
  return ( sqrt( x2 * a2 * il2 ) + y * rr ) * il2 - r1;
}