use binrw::BinRead;

/// On-disk size of a [`Shape`] entry in bytes.
pub const SHAPE_SIZE: usize = 16;

/// On-disk size of a [`ShapeMesh`] entry in bytes.
pub const SHAPE_MESH_SIZE: usize = 12;

/// On-disk size of a [`ShapeValue`] entry in bytes.
pub const SHAPE_VALUE_SIZE: usize = 4;

/// Morph target (shape key) descriptor — links a name to per-LOD mesh ranges.
///
/// The name is stored in the model string table; resolve it with
/// [`Mdl::shape_name`](crate::mdl::parser::Mdl::shape_name).
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, BinRead)]
#[br(little)]
pub struct Shape {
    /// Byte offset of the shape name in the string table.
    pub string_offset: u32,
    /// Per-LOD start index into the [`ShapeMesh`] array.
    pub shape_mesh_start_index: [u16; 3],
    /// Per-LOD count of [`ShapeMesh`] entries.
    pub shape_mesh_count: [u16; 3],
}

/// Links a shape to a contiguous range of [`ShapeValue`] entries for a specific mesh.
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, BinRead)]
#[br(little)]
pub struct ShapeMesh {
    /// Byte offset into the mesh's index buffer that this shape targets.
    pub mesh_index_offset: u32,
    /// Number of [`ShapeValue`] entries for this mesh.
    pub shape_value_count: u32,
    /// Start index into the global [`ShapeValue`] array.
    pub shape_value_offset: u32,
}

/// A single morph-target displacement: one base index replaced by a displaced vertex.
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, BinRead)]
#[br(little)]
pub struct ShapeValue {
    /// Index into the mesh's base index buffer that this value affects.
    pub base_indices_index: u16,
    /// Index of the replacement vertex in the morph-target vertex buffer.
    pub replacing_vertex_index: u16,
}
