#include "metalShaderTypes.h"
#include "alpha.h"
#include "commonMLDX.h"
#include "outputColorHelper.h"

constant float4 std709X = float4(  0.183,   0.614,  0.062, 0.0  );
constant float4 std709Y = float4( -0.101,  -0.338,  0.439, 0.0  );
constant float4 std709Z = float4(  0.439,  -0.399, -0.040, 0.0  );

constexpr sampler nearestSampler(
    mip_filter::nearest,
    mag_filter::nearest,
    min_filter::nearest,
    address::clamp_to_border,
    border_color::transparent_black);

vertex vertexOut vertexFunc(uint vertexID [[ vertex_id ]],
                            const device pixCopyVertexFormat* in[[ buffer(0) ]])
{
    vertexOut out;

    out.position = in[vertexID].pos;

    out.tex1 = in[vertexID].tc;
    out.tex2 = in[vertexID].tc;
    out.tex2.x += 1.0;

    return out;
}

fragment float4 fragmentFunc(vertexOut input [[stage_in]],
                             texture2d<half> inputTex0 [[ texture(0) ]],
                             texture2d<half> inputTex1 [[ texture(1) ]])
{
    float2 texSize = float2(inputTex0.get_width(), inputTex0.get_height());

    float4 texColor0 = float4(inputTex0.sample(nearestSampler, input.tex1 / texSize));
    float4 texColor1 = float4(inputTex0.sample(nearestSampler, input.tex2 / texSize));

    float4 texColor01 = float4(inputTex1.sample(nearestSampler, input.tex1 / texSize));
    float4 texColor11 = float4(inputTex1.sample(nearestSampler, input.tex2 / texSize));

    float isOddLine = floor(fract(input.tex1.y * 0.5) * 2.0);
    texColor0 = mix(texColor01, texColor0, isOddLine);
    texColor1 = mix(texColor11, texColor1, isOddLine);

    texColor0 = toOutput(texColor0);
    texColor1 = toOutput(texColor1);

    float4 yuv0 = float4(dot(std709X, texColor0) + 0.0625,
                         dot(std709Y, texColor0) + 0.5,
                         dot(std709Z, texColor0) + 0.5,
                         1.0 );

    float4 yuv1 = float4(dot(std709X, texColor1) + 0.0625,
                         dot(std709Y, texColor1) + 0.5,
                         dot(std709Z, texColor1) + 0.5,
                         1.0 );

    float4 outColor;

    outColor.a = yuv1.r;
    outColor.r = (yuv0.b + yuv1.b) * 0.5;
    outColor.b = (yuv0.g + yuv1.g) * 0.5;
    outColor.g = yuv0.r;

    return outColor;
}
