@group(0) @binding(0)
var<storage, read> positions : array<vec4<f32>>;

@group(0) @binding(1)
var<storage, read> colors : array<vec4<f32>>;

@group(0) @binding(2)
var<uniform> viewProjectionMatrix : mat4x4<f32>;

@group(0) @binding(3)
var<uniform> aspectRatio : f32;

@group(0) @binding(4)
var<uniform> mousePos : vec2<f32>;

@group(0) @binding(5)
var<uniform> hoverRadius : f32;

struct VertexOutput {
  @builtin(position) Position : vec4<f32>,
  @location(0) color : vec4<f32>,
};

fn smoothStep(edge0: f32, edge1: f32, x: f32) -> f32 {
  let t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
  return t * t * (3.0 - 2.0 * t);
}

@vertex
fn vertex_main(@builtin(vertex_index) vertexIndex : u32) -> VertexOutput {
  var output : VertexOutput;

  let pos = positions[vertexIndex];
  var color = colors[vertexIndex];

  let correctedPosition = vec4<f32>(
    pos.x * aspectRatio,
    pos.y,
    pos.z,
    pos.w
  );

  // Change color if near mousePos:
  // mousePos is passed as uniform vec2<f32> in clip space (-aspectRatio..aspectRatio, -1..1)
  let dist = distance(vec2<f32>(pos.x* aspectRatio, pos.y), mousePos);
  if (dist < hoverRadius) {
    color = vec4<f32>(1.0, 0.0, 0.0, 1.0); // Red highlight
  }

  output.Position = viewProjectionMatrix * correctedPosition;

  output.color = color;

  return output;
}

@fragment
fn fragment_main(input : VertexOutput) -> @location(0) vec4<f32> {
  return input.color;
}
