#include <metal_stdlib>

using namespace metal;
struct tint_symbol_1 {
  float2 a_particlePos [[attribute(0)]];
  float2 a_particleVel [[attribute(1)]];
  float2 a_pos [[attribute(2)]];
};
struct tint_symbol_2 {
  float4 value [[position]];
};
struct tint_symbol_3 {
  float4 value [[color(0)]];
};
struct Particle {
  /* 0x0000 */ packed_float2 pos;
  /* 0x0008 */ packed_float2 vel;
};
struct SimParams {
  /* 0x0000 */ float deltaT;
  /* 0x0004 */ float rule1Distance;
  /* 0x0008 */ float rule2Distance;
  /* 0x000c */ float rule3Distance;
  /* 0x0010 */ float rule1Scale;
  /* 0x0014 */ float rule2Scale;
  /* 0x0018 */ float rule3Scale;
};
struct tint_array_wrapper {
  /* 0x0000 */ Particle arr[5];
};
struct Particles {
  /* 0x0000 */ tint_array_wrapper particles;
};

float4 vert_main_inner(float2 a_particlePos, float2 a_particleVel, float2 a_pos) {
  float angle = -(atan2(a_particleVel.x, a_particleVel.y));
  float2 pos = float2(((a_pos.x * cos(angle)) - (a_pos.y * sin(angle))), ((a_pos.x * sin(angle)) + (a_pos.y * cos(angle))));
  return float4((pos + a_particlePos), 0.0f, 1.0f);
}

vertex tint_symbol_2 vert_main(tint_symbol_1 tint_symbol [[stage_in]]) {
  float4 const inner_result = vert_main_inner(tint_symbol.a_particlePos, tint_symbol.a_particleVel, tint_symbol.a_pos);
  tint_symbol_2 wrapper_result = {};
  wrapper_result.value = inner_result;
  return wrapper_result;
}

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

fragment tint_symbol_3 frag_main() {
  float4 const inner_result_1 = frag_main_inner();
  tint_symbol_3 wrapper_result_1 = {};
  wrapper_result_1.value = inner_result_1;
  return wrapper_result_1;
}

void comp_main_inner(constant SimParams& params, device Particles& particlesA, device Particles& particlesB, uint3 gl_GlobalInvocationID) {
  uint index = gl_GlobalInvocationID.x;
  if ((index >= 5u)) {
    return;
  }
  float2 vPos = particlesA.particles.arr[index].pos;
  float2 vVel = particlesA.particles.arr[index].vel;
  float2 cMass = float2(0.0f, 0.0f);
  float2 cVel = float2(0.0f, 0.0f);
  float2 colVel = float2(0.0f, 0.0f);
  int cMassCount = 0;
  int cVelCount = 0;
  float2 pos = 0.0f;
  float2 vel = 0.0f;
  for(uint i = 0u; (i < 5u); i = (i + 1u)) {
    if ((i == index)) {
      continue;
    }
    pos = particlesA.particles.arr[i].pos.xy;
    vel = particlesA.particles.arr[i].vel.xy;
    if ((distance(pos, vPos) < params.rule1Distance)) {
      cMass = (cMass + pos);
      cMassCount = as_type<int>((as_type<uint>(cMassCount) + as_type<uint>(1)));
    }
    if ((distance(pos, vPos) < params.rule2Distance)) {
      colVel = (colVel - (pos - vPos));
    }
    if ((distance(pos, vPos) < params.rule3Distance)) {
      cVel = (cVel + vel);
      cVelCount = as_type<int>((as_type<uint>(cVelCount) + as_type<uint>(1)));
    }
  }
  if ((cMassCount > 0)) {
    cMass = ((cMass / float2(float(cMassCount), float(cMassCount))) - vPos);
  }
  if ((cVelCount > 0)) {
    cVel = (cVel / float2(float(cVelCount), float(cVelCount)));
  }
  vVel = (((vVel + (cMass * params.rule1Scale)) + (colVel * params.rule2Scale)) + (cVel * params.rule3Scale));
  vVel = (normalize(vVel) * clamp(length(vVel), 0.0f, 0.100000001f));
  vPos = (vPos + (vVel * params.deltaT));
  if ((vPos.x < -1.0f)) {
    vPos.x = 1.0f;
  }
  if ((vPos.x > 1.0f)) {
    vPos.x = -1.0f;
  }
  if ((vPos.y < -1.0f)) {
    vPos.y = 1.0f;
  }
  if ((vPos.y > 1.0f)) {
    vPos.y = -1.0f;
  }
  particlesB.particles.arr[index].pos = vPos;
  particlesB.particles.arr[index].vel = vVel;
}

kernel void comp_main(uint3 gl_GlobalInvocationID [[thread_position_in_grid]], constant SimParams& params [[buffer(0)]], device Particles& particlesA [[buffer(1)]], device Particles& particlesB [[buffer(2)]]) {
  comp_main_inner(params, particlesA, particlesB, gl_GlobalInvocationID);
  return;
}

