struct VertexInput {
    @location(0) pos: vec3<f32>,
    @location(1) tex_coord: vec2<f32>,
    @location(2) color: vec4<f32>,
};

struct VertexOutput {
    @builtin(position) pos: vec4<f32>,
    @location(0) tex_coord: vec2<f32>,
    @location(1) color: vec4f,
};

struct CameraUniform {
    view_proj: mat4x4<f32>,
};

struct CircleUniform {
    center: vec3<f32>,
    radius: f32,
};

@group(0) @binding(0)
var<uniform> camera: CameraUniform;

@group(1) @binding(0)
var<uniform> circle_data: CircleUniform;

@vertex
fn vs_main(in: VertexInput) -> VertexOutput {
    var output: VertexOutput;
    output.pos = camera.view_proj * vec4<f32>(in.pos, 1.0);
    output.tex_coord = in.tex_coord;
    output.color = in.color;
    return output;
}

@fragment
fn fs_circle(input: VertexOutput) -> @location(0) vec4<f32> {
    // Convert texture coordinates to world space for circle distance calculation
    // The bounding box is a square around the circle, so we need to map
    // from [0,1] texture coordinates to the actual circle area

    // Calculate bounding box for the circle
    let bounding_min = circle_data.center.xy - vec2(circle_data.radius);
    let bounding_max = circle_data.center.xy + vec2(circle_data.radius);
    let bounding_size = bounding_max - bounding_min;

    // Convert texture coordinates to world position within bounding box
    // Note: texture Y is flipped (0=top, 1=bottom), so we flip it
    let tex_coord_corrected = vec2(input.tex_coord.x, 1.0 - input.tex_coord.y);
    let world_pos = bounding_min + tex_coord_corrected * bounding_size;

    // Calculate distance to circle center
    let distance_to_center = length(world_pos - circle_data.center.xy);

    // Anti-aliased circle edge
    let alpha = 1.0 - smoothstep(circle_data.radius - 1.0, circle_data.radius, distance_to_center);

    return vec4(input.color.rgb, input.color.a * alpha);
}
