#include <metal_stdlib>
using namespace metal;

template<typename T, size_t N>
struct tint_array {
  const constant T& operator[](size_t i) const constant { return elements[i]; }
  device T& operator[](size_t i) device { return elements[i]; }
  const device T& operator[](size_t i) const device { return elements[i]; }
  thread T& operator[](size_t i) thread { return elements[i]; }
  const thread T& operator[](size_t i) const thread { return elements[i]; }
  threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
  const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
  T elements[N];
};

struct OutputBuf {
  /* 0x0000 */ tint_array<uint, 1> result;
};

struct Uniforms {
  /* 0x0000 */ uint dstTextureFlipY;
  /* 0x0004 */ uint channelCount;
  /* 0x0008 */ uint2 srcCopyOrigin;
  /* 0x0010 */ uint2 dstCopyOrigin;
  /* 0x0018 */ uint2 copySize;
};

struct tint_module_vars_struct {
  texture2d<float, access::sample> src;
  texture2d<float, access::sample> dst;
  device OutputBuf* output;
  const constant Uniforms* uniforms;
};

bool aboutEqual(float value, float expect) {
  return (abs((value - expect)) < 0.00100000004749745131f);
}

void tint_symbol_inner(uint3 GlobalInvocationID, tint_module_vars_struct tint_module_vars) {
  uint const v = tint_module_vars.src.get_width(0u);
  uint2 const srcSize = uint2(v, tint_module_vars.src.get_height(0u));
  uint const v_1 = tint_module_vars.dst.get_width(0u);
  uint2 const dstSize = uint2(v_1, tint_module_vars.dst.get_height(0u));
  uint2 const dstTexCoord = uint2(GlobalInvocationID.xy);
  float4 const nonCoveredColor = float4(0.0f, 1.0f, 0.0f, 1.0f);
  bool success = true;
  bool v_2 = false;
  if ((dstTexCoord[0u] < (*tint_module_vars.uniforms).dstCopyOrigin[0u])) {
    v_2 = true;
  } else {
    v_2 = (dstTexCoord[1u] < (*tint_module_vars.uniforms).dstCopyOrigin[1u]);
  }
  bool v_3 = false;
  if (v_2) {
    v_3 = true;
  } else {
    v_3 = (dstTexCoord[0u] >= ((*tint_module_vars.uniforms).dstCopyOrigin[0u] + (*tint_module_vars.uniforms).copySize[0u]));
  }
  bool v_4 = false;
  if (v_3) {
    v_4 = true;
  } else {
    v_4 = (dstTexCoord[1u] >= ((*tint_module_vars.uniforms).dstCopyOrigin[1u] + (*tint_module_vars.uniforms).copySize[1u]));
  }
  if (v_4) {
    bool v_5 = false;
    if (success) {
      v_5 = all((tint_module_vars.dst.read(uint2(int2(dstTexCoord)), 0) == nonCoveredColor));
    } else {
      v_5 = false;
    }
    success = v_5;
  } else {
    uint2 srcTexCoord = ((dstTexCoord - (*tint_module_vars.uniforms).dstCopyOrigin) + (*tint_module_vars.uniforms).srcCopyOrigin);
    if (((*tint_module_vars.uniforms).dstTextureFlipY == 1u)) {
      srcTexCoord[1u] = ((srcSize[1u] - srcTexCoord[1u]) - 1u);
    }
    float4 const srcColor = tint_module_vars.src.read(uint2(int2(srcTexCoord)), 0);
    float4 const dstColor = tint_module_vars.dst.read(uint2(int2(dstTexCoord)), 0);
    if (((*tint_module_vars.uniforms).channelCount == 2u)) {
      bool v_6 = false;
      if (success) {
        v_6 = aboutEqual(dstColor[0u], srcColor[0u]);
      } else {
        v_6 = false;
      }
      bool v_7 = false;
      if (v_6) {
        v_7 = aboutEqual(dstColor[1u], srcColor[1u]);
      } else {
        v_7 = false;
      }
      success = v_7;
    } else {
      bool v_8 = false;
      if (success) {
        v_8 = aboutEqual(dstColor[0u], srcColor[0u]);
      } else {
        v_8 = false;
      }
      bool v_9 = false;
      if (v_8) {
        v_9 = aboutEqual(dstColor[1u], srcColor[1u]);
      } else {
        v_9 = false;
      }
      bool v_10 = false;
      if (v_9) {
        v_10 = aboutEqual(dstColor[2u], srcColor[2u]);
      } else {
        v_10 = false;
      }
      bool v_11 = false;
      if (v_10) {
        v_11 = aboutEqual(dstColor[3u], srcColor[3u]);
      } else {
        v_11 = false;
      }
      success = v_11;
    }
  }
  uint const outputIndex = ((GlobalInvocationID[1u] * dstSize[0u]) + GlobalInvocationID[0u]);
  if (success) {
    (*tint_module_vars.output).result[outputIndex] = 1u;
  } else {
    (*tint_module_vars.output).result[outputIndex] = 0u;
  }
}

kernel void tint_symbol(uint3 GlobalInvocationID [[thread_position_in_grid]], texture2d<float, access::sample> src [[texture(0)]], texture2d<float, access::sample> dst [[texture(1)]], device OutputBuf* output [[buffer(1)]], const constant Uniforms* uniforms [[buffer(0)]]) {
  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.src=src, .dst=dst, .output=output, .uniforms=uniforms};
  tint_symbol_inner(GlobalInvocationID, tint_module_vars);
}
