// @include 'util.wgsl'
// ----------------------------------------------------------------------------
// Vertex shader
// ----------------------------------------------------------------------------

struct VertexInput {
  @location(0) position : vec3<f32>,
  @location(1) tex_coords : vec2<f32>,
};

struct InstanceInput {
  @location(5) center: vec2<f32>,
  @location(6) radius: f32,
  @location(7) stroke_width: f32,
  @location(8) stroke_color: vec4<f32>,
  @location(9) fill_color: vec4<f32>,
};

struct VertexOutput {
  @builtin(position) clip_position : vec4<f32>,
  @location(0) tex_coords : vec2<f32>,
  @location(1) inner_r2: f32,
  @location(2) stroke_color: vec4<f32>,
  @location(3) fill_color: vec4<f32>,  
};

@vertex fn vs_main(vertex : VertexInput, instance : InstanceInput)->VertexOutput {
  var out : VertexOutput;
  out.stroke_color = instance.stroke_color;
  out.fill_color = instance.fill_color;

  // The circle's coordinate system goes from (-1,-1) to (1,1) but by
  // convention we provide ourselves texture coordinates that go from (0,0)
  // to (1,1).
  out.tex_coords = (vertex.tex_coords * vec2f(2.0,2.0)) - vec2f(1.0,1.0);

  // Compute the squared radius of the inner circle, so we don't do it
  // per-pixel.
  //
  // The radius of the inner circle goes from 0 (no inner circle) to 1 (no
  // stroke), because the radius of the outer circle is implicitly 1 (the
  // circle in the square we're rendering.
  //
  // (Honestly I don't even need to do this per-vertex, this is per-instance,
  // I can pre-calculate this if I need this to be faster somehow.)
  let delta = instance.radius - instance.stroke_width; //, 0, instance.radius);
  let inner_radius = delta / instance.radius;
  out.inner_r2 = inner_radius * inner_radius;

  let radius = vec2f(instance.radius, instance.radius);
  let in_pos = instance.center + mix(-radius, radius, vec2f(vertex.position.x, vertex.position.y));

  let position = adjust_for_resolution(in_pos);
  out.clip_position = vec4f(position.x, position.y, vertex.position.z, 1.0);
  return out;
}

// ----------------------------------------------------------------------------
// Fragment shader
// ----------------------------------------------------------------------------

@fragment fn fs_main(in : VertexOutput)->@location(0) vec4<f32> {
  let tc2 = in.tex_coords * in.tex_coords;
  if (tc2.x + tc2.y <= in.inner_r2) {
     return in.fill_color;
  } else if (tc2.x + tc2.y <= 1.0) {
     return in.stroke_color;
  } else {
    return vec4<f32>(0.0, 0.0, 0.0, 0.0);
  }
}
