#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;
}

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)]])
{
    vec4 color = getColor(inputTex, fsTexture);
    float fsTime=(vars.speed+0.01)*u.localTime*10.0;
    
    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 = sides*a/3.1416;
    uv.y = sin(sides*r+fsTime) + sides/10.0*cos(fsTime+7.0*a);
    uv.x = 0.5*(uv.x+1.0);
    uv.y = 0.5*(uv.y+1.0);

    float4 outColor = getColor(inputTex, uv);
    float w = .5+.5*(sin(fsTime+sides*r) + sides/10.0*cos(fsTime+sides*a));
    multiplyOpacity(outColor, w);

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

    return outColor;
}
