#include "metalShaderTypes.h"

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

typedef struct
{
    float downsampleStep;
    float textureStep;
} fxVars;

typedef struct
{
    float4 position [[position]];
    float2 texMask;
    float2 normPos;
    float2 texSize;
    float2 tex0;
    float2 tex1;
    float2 tex2;
    float2 tex3;
} 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 pixelOffset=vec2(1.0/inputTex0.get_width(0),1.0/inputTex0.get_height(0));

    out.tex0=in[vertexID].tex1+pixelOffset*float2(0.,0.)*vars.downsampleStep;
    out.tex1=in[vertexID].tex1+pixelOffset*float2(1.,0.)*vars.downsampleStep;
    out.tex2=in[vertexID].tex1+pixelOffset*float2(1.,1.)*vars.downsampleStep;
    out.tex3=in[vertexID].tex1+pixelOffset*float2(0.,1.)*vars.downsampleStep;

    return out;
}

#if defined(__HAVE_BICUBIC_FILTERING__)

constexpr sampler reduceSampler(
                              mip_filter::none, mag_filter::bicubic, min_filter::bicubic, s_address::clamp_to_edge, t_address::clamp_to_edge);

#else

constexpr sampler reduceSampler(
                              mip_filter::none, mag_filter::linear, min_filter::linear, s_address::clamp_to_edge, t_address::clamp_to_edge);

#endif

#define getTexture(a,b) float4(a.sample(reduceSampler,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)]])
{
    float4 outColor=getTexture(inputTex,input.tex0);
    outColor+=getTexture(inputTex,input.tex1);
    outColor+=getTexture(inputTex,input.tex2);
    outColor+=getTexture(inputTex,input.tex3);
    outColor*=vec4(1.0/4.0,1.0/4.0,1.0/4.0,1.0/4.0);
    return outColor;
}
