#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 */ float2 pos;
  /* 0x0008 */ 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[0], a_particleVel[1]));
  float2 pos = float2(((a_pos[0] * cos(angle)) - (a_pos[1] * sin(angle))), ((a_pos[0] * sin(angle)) + (a_pos[1] * 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[0];
  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 = float2(particlesA.particles.arr[i].pos).xy;
    vel = float2(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[0] < -1.0f)) {
    vPos[0] = 1.0f;
  }
  if ((vPos[0] > 1.0f)) {
    vPos[0] = -1.0f;
  }
  if ((vPos[1] < -1.0f)) {
    vPos[1] = 1.0f;
  }
  if ((vPos[1] > 1.0f)) {
    vPos[1] = -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;
}

