#include "metalShaderTypes.h"

// Fragment shader for doing blur for source of blurred background effects

typedef struct
{
    float blurAmount;
} fxVars;

typedef struct
{
    float4 position [[position]];
    float2 texMask;
    float2 normPos;
    float2 texSize;
    float2 tex0;
    float2 tex1;
    float2 tex2;
    float2 tex3;
    float2 tex4;
    float2 tex5;
    float2 tex6;
    float2 tex7;
} fsVertexOut;

vertex fsVertexOut 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)]])
{
    fsVertexOut out;

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

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

    float2 center = in[vertexID].tex1;
    vec2 halfpixel = vec2(1.0/inputTex0.get_width(0),1.0/inputTex0.get_height(0)) * vec2(.5,.5);

    float offset = 3.;

    out.tex0 = center + vec2(-halfpixel.x * offset, 0.0);
    out.tex1 = center + vec2(-halfpixel.x, halfpixel.y);
    out.tex2 = center + vec2(0.0, halfpixel.y * offset);
    out.tex3 = center + vec2(halfpixel.x, halfpixel.y);
    out.tex4 = center + vec2(halfpixel.x * offset, 0.0);
    out.tex5 = center + vec2(halfpixel.x, -halfpixel.y);
    out.tex6 = center + vec2(0.0, -halfpixel.y * offset);
    out.tex7 = center + vec2(-halfpixel.x, -halfpixel.y);

    return out;
}

constexpr sampler blurSampler(
                              mip_filter::nearest, mag_filter::linear, min_filter::linear, s_address::clamp_to_edge, t_address::clamp_to_edge);

#define getTexture(a,b) float4(a.sample(blurSampler,b))

fragment float4 fragmentFunc(fsVertexOut input [[stage_in]]
                             ,texture2d<half> inputTex [[ texture(0) ]]
                             ,texture2d<half> inputTexMask [[ texture(1) ]]
                             ,constant fxGeneralUniforms& u[[ buffer(0) ]]
                             ,constant fxVars& vars[[ buffer(1)]])
{
    float weight = 3.;

    vec4 sum = getTexture(inputTex, input.tex0);
    sum += getTexture(inputTex, input.tex1) * weight;
    sum += getTexture(inputTex, input.tex2);
    sum += getTexture(inputTex, input.tex3) * weight;
    sum += getTexture(inputTex, input.tex4);
    sum += getTexture(inputTex, input.tex5) * weight;
    sum += getTexture(inputTex, input.tex6);
    sum += getTexture(inputTex, input.tex7) * weight;

    return sum / 12.0;
}
