#include <metal_stdlib>
using namespace metal;

struct SimParams {
  /* 0x0000 */ float deltaT;
  /* 0x0004 */ float rule1Distance;
  /* 0x0008 */ float rule2Distance;
  /* 0x000c */ float rule3Distance;
  /* 0x0010 */ float rule1Scale;
  /* 0x0014 */ float rule2Scale;
  /* 0x0018 */ float rule3Scale;
};

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 Particle {
  /* 0x0000 */ float2 pos;
  /* 0x0008 */ float2 vel;
};

struct Particles {
  /* 0x0000 */ tint_array<Particle, 5> particles;
};

struct tint_module_vars_struct {
  const constant SimParams* params;
  device Particles* particlesA;
  device Particles* particlesB;
};

#define TINT_ISOLATE_UB(VOLATILE_NAME) \
  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}

struct vert_main_outputs {
  float4 tint_symbol [[position]];
};

struct vert_main_inputs {
  float2 a_particlePos [[attribute(0)]];
  float2 a_particleVel [[attribute(1)]];
  float2 a_pos [[attribute(2)]];
};

struct frag_main_outputs {
  float4 tint_symbol_1 [[color(0)]];
};

float4 vert_main_inner(float2 a_particlePos, float2 a_particleVel, float2 a_pos) {
  float angle = -(atan2(a_particleVel[0u], a_particleVel[1u]));
  float2 pos = float2(((a_pos[0u] * cos(angle)) - (a_pos[1u] * sin(angle))), ((a_pos[0u] * sin(angle)) + (a_pos[1u] * cos(angle))));
  return float4((pos + a_particlePos), 0.0f, 1.0f);
}

float4 frag_main_inner() {
  return float4(1.0f);
}

void comp_main_inner(uint3 gl_GlobalInvocationID, tint_module_vars_struct tint_module_vars) {
  uint index = gl_GlobalInvocationID[0u];
  if ((index >= 5u)) {
    return;
  }
  float2 vPos = (*tint_module_vars.particlesA).particles[index].pos;
  float2 vVel = (*tint_module_vars.particlesA).particles[index].vel;
  float2 cMass = float2(0.0f);
  float2 cVel = float2(0.0f);
  float2 colVel = float2(0.0f);
  int cMassCount = 0;
  int cVelCount = 0;
  float2 pos = 0.0f;
  float2 vel = 0.0f;
  {
    uint i = 0u;
    while(true) {
      TINT_ISOLATE_UB(tint_volatile_false)
      if ((i < 5u)) {
      } else {
        break;
      }
      if ((i == index)) {
        {
          i = (i + 1u);
        }
        continue;
      }
      pos = (*tint_module_vars.particlesA).particles[i].pos.xy;
      vel = (*tint_module_vars.particlesA).particles[i].vel.xy;
      if ((distance(pos, vPos) < (*tint_module_vars.params).rule1Distance)) {
        cMass = (cMass + pos);
        cMassCount = as_type<int>((as_type<uint>(cMassCount) + as_type<uint>(1)));
      }
      if ((distance(pos, vPos) < (*tint_module_vars.params).rule2Distance)) {
        colVel = (colVel - (pos - vPos));
      }
      if ((distance(pos, vPos) < (*tint_module_vars.params).rule3Distance)) {
        cVel = (cVel + vel);
        cVelCount = as_type<int>((as_type<uint>(cVelCount) + as_type<uint>(1)));
      }
      {
        i = (i + 1u);
      }
      continue;
    }
  }
  if ((cMassCount > 0)) {
    float2 const v = cMass;
    float const v_1 = float(cMassCount);
    float2 const v_2 = (v / float2(v_1, float(cMassCount)));
    cMass = (v_2 - vPos);
  }
  if ((cVelCount > 0)) {
    float2 const v_3 = cVel;
    float const v_4 = float(cVelCount);
    cVel = (v_3 / float2(v_4, float(cVelCount)));
  }
  vVel = (((vVel + (cMass * (*tint_module_vars.params).rule1Scale)) + (colVel * (*tint_module_vars.params).rule2Scale)) + (cVel * (*tint_module_vars.params).rule3Scale));
  vVel = (normalize(vVel) * clamp(length(vVel), 0.0f, 0.10000000149011611938f));
  vPos = (vPos + (vVel * (*tint_module_vars.params).deltaT));
  if ((vPos[0u] < -1.0f)) {
    vPos[0u] = 1.0f;
  }
  if ((vPos[0u] > 1.0f)) {
    vPos[0u] = -1.0f;
  }
  if ((vPos[1u] < -1.0f)) {
    vPos[1u] = 1.0f;
  }
  if ((vPos[1u] > 1.0f)) {
    vPos[1u] = -1.0f;
  }
  (*tint_module_vars.particlesB).particles[index].pos = vPos;
  (*tint_module_vars.particlesB).particles[index].vel = vVel;
}

vertex vert_main_outputs vert_main(vert_main_inputs inputs [[stage_in]]) {
  vert_main_outputs tint_wrapper_result = {};
  tint_wrapper_result.tint_symbol = vert_main_inner(inputs.a_particlePos, inputs.a_particleVel, inputs.a_pos);
  return tint_wrapper_result;
}

fragment frag_main_outputs frag_main() {
  frag_main_outputs tint_wrapper_result = {};
  tint_wrapper_result.tint_symbol_1 = frag_main_inner();
  return tint_wrapper_result;
}

kernel void comp_main(uint3 gl_GlobalInvocationID [[thread_position_in_grid]], const constant SimParams* params [[buffer(0)]], device Particles* particlesA [[buffer(1)]], device Particles* particlesB [[buffer(2)]]) {
  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.params=params, .particlesA=particlesA, .particlesB=particlesB};
  comp_main_inner(gl_GlobalInvocationID, tint_module_vars);
}
