#include <metal_stdlib>
using namespace metal;

struct SimParams {
  float deltaT;
  float rule1Distance;
  float rule2Distance;
  float rule3Distance;
  float rule1Scale;
  float rule2Scale;
  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 {
  float2 pos;
  float2 vel;
};

struct Particles {
  tint_array<Particle, 5> particles;
};

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

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]));
  float const v = (a_pos[0u] * cos(angle));
  float const v_1 = (v - (a_pos[1u] * sin(angle)));
  float const v_2 = (a_pos[0u] * sin(angle));
  float2 pos = float2(v_1, (v_2 + (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) {
      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;
      float const v_3 = distance(pos, vPos);
      if ((v_3 < (*tint_module_vars.params).rule1Distance)) {
        cMass = (cMass + pos);
        cMassCount = (cMassCount + 1);
      }
      float const v_4 = distance(pos, vPos);
      if ((v_4 < (*tint_module_vars.params).rule2Distance)) {
        colVel = (colVel - (pos - vPos));
      }
      float const v_5 = distance(pos, vPos);
      if ((v_5 < (*tint_module_vars.params).rule3Distance)) {
        cVel = (cVel + vel);
        cVelCount = (cVelCount + 1);
      }
      {
        i = (i + 1u);
      }
      continue;
    }
  }
  if ((cMassCount > 0)) {
    float2 const v_6 = cMass;
    float const v_7 = float(cMassCount);
    float2 const v_8 = (v_6 / float2(v_7, float(cMassCount)));
    cMass = (v_8 - vPos);
  }
  if ((cVelCount > 0)) {
    float2 const v_9 = cVel;
    float const v_10 = float(cVelCount);
    cVel = (v_9 / float2(v_10, float(cVelCount)));
  }
  vVel = (((vVel + (cMass * (*tint_module_vars.params).rule1Scale)) + (colVel * (*tint_module_vars.params).rule2Scale)) + (cVel * (*tint_module_vars.params).rule3Scale));
  float2 const v_11 = normalize(vVel);
  vVel = (v_11 * 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]]) {
  return vert_main_outputs{.tint_symbol=vert_main_inner(inputs.a_particlePos, inputs.a_particleVel, inputs.a_pos)};
}

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

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);
}
