#include "metalShaderTypes.h"
#include "alpha.h"

typedef struct
{
    float speed;
    int numSides;
    float centerX;
    float centerY;
} fxVars;


vertex fxVertexOut vertexFunc(uint vertexID [[ vertex_id ]]
                              ,const device fxShaderVerts* in[[ buffer(0) ]]
                              ,texture2d<half> inputTex0 [[ texture(0) ]]
                              ,texture2d<half> inputTexMask [[ texture(1) ]]
                              ,constant fxGeneralUniforms& u[[ buffer(1) ]]
                              ,constant fxVars& vars[[ buffer(2)]])
{
    fxVertexOut out;

    out.normPos=in[vertexID].pos.xy;//*vec2(.5,.5f)+vec2(.5,.5);
    out.position=in[vertexID].pos;

    out.tex1=in[vertexID].tex1;
    out.texMask=in[vertexID].texMask;
    out.texSize=float2(inputTex0.get_width(),inputTex0.get_height());
    return out;
}

bool InBound(float x, float a, float b)
{
    return (x > a && x<=b);
}


fragment float4 fragmentFunc(fxVertexOut input [[stage_in]]
                             ,texture2d<half> inputTex [[ texture(0) ]]
                             ,texture2d<half> inputTexMask [[ texture(1) ]]
                             ,constant fxGeneralUniforms& u[[ buffer(0) ]]
                             ,constant fxVars& vars[[ buffer(1)]])
{

    float fsTime=fract(vars.speed*u.localTime*0.3);

    vec2 p=input.normPos-vec2(vars.centerX*2.,vars.centerY*2.);

    float r = length(p);
    float a = atan2(p.y, p.x);
    float tau = 2.0 * 3.1416;
    float sides=float(vars.numSides);
    a = mod(a, tau/sides);
    a = abs(a - tau/sides/2.0);

    vec2 uv;
    
    uv.x = r *cos(a) + 0.5+fsTime;
    uv.y = r *sin(a) + 0.5+fsTime;

    // uv = 0.5*uv*fsTextureSize;
    uv*=.5;
    //
    uv.x = InBound(uv.x, 0., 1.0)?uv.x:fsTexture.x;
    uv.y = InBound(uv.y, 0., 1.0)?uv.y:fsTexture.y;

    vec4 texel=getColor(inputTex,fsTexture);
    float4 outColor =  getColor(inputTex,uv);

    float blendValue=u.blendValue;
#ifdef USE_MASK
    blendValue*=getColor(inputTexMask,input.texMask).a;
#endif
    mixColor(outColor, texel, outColor, blendValue);
    return outColor;
}
