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

typedef struct
{
    int direction;
} fxVars;

constant float2 directionTable[9] = {
    float2( 1,  1),
    float2( 0,  1),
    float2(-1,  1),
    float2( 1,  0),
    float2( 0,  0),
    float2(-1,  0),
    float2( 1, -1),
    float2( 0, -1),
    float2(-1, -1)
};

constant float2 center = float2(0.5, 0.5);

vertex vertexOut vertexFunc(uint vertexID [[vertex_id]],
                            const device txShaderVers *in [[buffer(0)]],
                            constant txShaderUniforms &uniforms [[buffer(3)]],
                            constant fxVars &vars [[buffer(2)]])
{
    vertexOut out;
    out.position = in[vertexID].pos * uniforms.worldViewProj;
    out.tex1 = in[vertexID].tex1;
    out.tex2 = in[vertexID].tex2;
    out.texMask = in[vertexID].texMask;
    out.normPos = in[vertexID].pos.xy * 0.5 + center;
    return out;
}

fragment float4 fragmentFunc(vertexOut input [[stage_in]],
                             texture2d<half> inputTex0 [[texture(0)]],
                             texture2d<half> inputTex1 [[texture(1)]],
                             texture2d<half> inputTexMask [[texture(2)]],
                             constant txShaderUniforms &u [[buffer(2)]],
                             constant subFXVars &subVars [[buffer(3)]],
                             constant fxVars &vars [[buffer(1)]])
{
    float2 p = input.normPos;
    float2 dir = normalize(directionTable[vars.direction]);
    float diagonalScale = abs(dir.x) + abs(dir.y);
    if (diagonalScale > 0)
        dir /= diagonalScale;
    float offset = 1.0;
    float prog = dot(dir, p) - dot(dir, center) + 0.5 - u.transitionProgressLinear * (1.0 + offset);
    float pr = smoothstep(-offset, 0.0, prog) * 0.5;
    float2 squares = float2(10, 10);
    float2 squarep = fract(p * squares);
    float2 squaremin = float2(pr);
    float2 squaremax = float2(1.0 - pr);
    float which = all(squaremin <= squarep) && all(squarep <= squaremax) ? 1.0 : 0.0;
    float4 texelA = getColor(inputTex0, input.tex1);
    float4 texelB = getColor(inputTex1, input.tex2);
    float4 outColor = mix(texelB, texelA, which);
    float alpha = u.baseAlpha;

#ifdef USE_MASK
    alpha *= float(inputTexMask.sample(linearSampler, input.texMask).a);
#endif

    multiplyOpacity(outColor, alpha);
    return outColor;
}
