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

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

void computeNinePatchBorders( vec2 _TEXTURE_PIXEL_SIZE, vec2 renderSize, vec4 pixelBorders, 
                             out vec4 uvBorders, out vec4 scaledBorders )
{
  vec2 texSize = vec2( 1.0 / _TEXTURE_PIXEL_SIZE.x, 1.0 / _TEXTURE_PIXEL_SIZE.y );

  vec2 scale = texSize / renderSize;
  scale = max( scale, vec2( 1, 1 ) );
  
  float scaling = max( scale.x, scale.y );
  
  uvBorders = vec4 
  ( 
    pixelBorders[ 0 ] / texSize.x,  ( texSize.x - pixelBorders[ 1 ] ) / texSize.x,
    
    pixelBorders[ 2 ] / texSize.y,  ( texSize.y - pixelBorders[ 1 ] ) / texSize.y
  );
  
  scaledBorders = pixelBorders / scaling;
  scaledBorders[ 1 ] = renderSize.x - scaledBorders[ 1 ];
  scaledBorders[ 3 ] = renderSize.y - scaledBorders[ 3 ];
}

float ninePatchBorderRemap( float value, float borderStart, float borderEnd, 
                   float uvStart, float uvEnd, float maxSize )
{
  float inMin = borderStart;
  float inMax = borderEnd;
  float outMin = uvStart;
  float outMax = uvEnd;
  
  
  if ( value < borderStart )
  {
    inMin = 0.0; inMax = borderStart;
    outMin = 0.0; outMax = uvStart;
  }
  else if ( value > borderEnd )
  {
    inMin = borderEnd; inMax = maxSize;
    outMin = uvEnd; outMax = 1.0;
  }
  
  return map( value, inMin, inMax, outMin, outMax );
  
}

vec2 computeNinePatchUV( vec2 _UV, vec2 renderSize, vec4 uvBorders, vec4 scaledBorders )
{
  vec2 pixelCoord = _UV * renderSize;
  
  float nU = ninePatchBorderRemap( 
    pixelCoord.x, scaledBorders[ 0 ], scaledBorders[ 1 ], 
    uvBorders[ 0 ], uvBorders[ 1 ], renderSize.x
  );
    
  float nV = ninePatchBorderRemap( 
    pixelCoord.y, scaledBorders[ 2 ], scaledBorders[ 3 ], 
    uvBorders[ 2 ], uvBorders[ 3 ], renderSize.y
  );
  
  return vec2( nU, nV ); 
}