// Mawida unlit sprite shader, instanced (v0.2 step 10).
//
// Vertex layout matches `drawable::Vertex` v2 (buffer slot 0, per VERTEX):
//   location 0: position (vec3)
//   location 1: normal   (vec3)  - unused here; the LIT shader consumes it
//   location 2: uv       (vec2)
//   location 3: color    (vec4)
//
// Instance layout matches WgpuBackend's `Instance` (buffer slot 1, per
// INSTANCE). WGSL has no mat4x4 vertex attribute, so the model matrix
// travels as four vec4 columns, one location each:
//   locations 4..7: model matrix columns
//   location  8:    tint
//   location  9:    uv_rect (min.x, min.y, size.x, size.y) into the atlas
//
// Bind groups:
//   group(0) binding(0): Camera uniform (view_proj). Matches gfx::backend::CameraUniform.
//   group(1) binding(0): texture_2d
//   group(1) binding(1): sampler
// The old group(1) binding(2) Model uniform is GONE: everything it carried
// now rides per instance, which is what makes one draw call per texture run
// possible.

struct Camera {
    view_proj: mat4x4<f32>,
};
@group(0) @binding(0) var<uniform> camera: Camera;

@group(1) @binding(0) var t_diffuse: texture_2d<f32>;
@group(1) @binding(1) var s_diffuse: sampler;

struct VertexInput {
    @location(0) position: vec3<f32>,
    // location(1) is the normal: a pipeline need not consume every
    // attribute, so the unlit shader simply does not declare it.
    @location(2) uv: vec2<f32>,
    @location(3) color: vec4<f32>,
};

// NEW: one record per sprite, fetched per instance, not per vertex.
struct InstanceInput {
    @location(4) model_0: vec4<f32>,   // model matrix, column 0
    @location(5) model_1: vec4<f32>,   // column 1
    @location(6) model_2: vec4<f32>,   // column 2
    @location(7) model_3: vec4<f32>,   // column 3
    @location(8) tint: vec4<f32>,
    @location(9) uv_rect: vec4<f32>,   // (min.x, min.y, size.x, size.y)
};

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

@vertex
fn vs_main(in: VertexInput, inst: InstanceInput) -> VertexOutput {
    // Reassemble the matrix from its four columns.
    let model = mat4x4<f32>(inst.model_0, inst.model_1, inst.model_2, inst.model_3);
    var out: VertexOutput;
    let world = model * vec4<f32>(in.position, 1.0);
    out.clip_position = camera.view_proj * world;
    // The atlas remap: quad uv (0..1) -> this sprite's rectangle of the atlas.
    out.uv = inst.uv_rect.xy + in.uv * inst.uv_rect.zw;
    out.color = in.color * inst.tint;
    return out;
}

// fs_main is untouched by batching: sample and multiply, as always.
@fragment
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
    let tex = textureSample(t_diffuse, s_diffuse, in.uv);
    return tex * in.color;
}
