pub const MAX_JOINTS_PER_SKIN: usize = 256;
pub const INITIAL_MAX_SKINS: usize = 100;
pub const INITIAL_MAX_TOTAL_BONES: usize = 5_000;
pub const MAX_SPOTLIGHT_SHADOWS: usize = 16;
pub const SPOTLIGHT_ATLAS_SLOTS_PER_ROW: u32 = 4;

pub const NUM_SHADOW_CASCADES: usize = 4;
pub const CASCADE_ATLAS_SLOTS_PER_ROW: u32 = 2;
pub const CASCADE_SPLIT_DISTANCES: [f32; NUM_SHADOW_CASCADES] = [10.0, 40.0, 150.0, 500.0];

pub const MAX_POINT_LIGHT_SHADOWS: usize = 4;
pub const POINT_SHADOW_FACE_SIZE: u32 = 512;
pub const POINT_SHADOW_NUM_FACES: usize = 6;

#[repr(C)]
#[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
pub struct SkinnedShadowObjectData {
    pub transform_index: u32,
    pub mesh_id: u32,
    pub material_id: u32,
    pub joint_offset: u32,
}

#[repr(C)]
#[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
pub struct ShadowUniforms {
    pub light_view_projection: [[f32; 4]; 4],
    pub _padding: [[f32; 4]; 4],
    pub _padding2: [[f32; 4]; 4],
    pub _padding3: [[f32; 4]; 4],
    pub _padding4: [f32; 4],
}

#[repr(C)]
#[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
pub struct CascadeData {
    pub view_projections: [[[f32; 4]; 4]; NUM_SHADOW_CASCADES],
    pub split_distances: [f32; NUM_SHADOW_CASCADES],
    pub atlas_offsets: [[f32; 2]; NUM_SHADOW_CASCADES],
    pub atlas_scale: [f32; 2],
    pub _padding: [f32; 2],
}

#[derive(Debug, Clone)]
pub struct SpotlightShadowSlot {
    pub entity: crate::ecs::world::Entity,
    pub view_projection: nalgebra_glm::Mat4,
    pub slot_index: u32,
    pub bias: f32,
}

#[repr(C)]
#[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
pub struct SpotlightShadowData {
    pub view_projection: [[f32; 4]; 4],
    pub atlas_offset: [f32; 2],
    pub atlas_scale: [f32; 2],
    pub bias: f32,
    pub _padding: [f32; 3],
}

#[derive(Debug, Clone)]
pub struct PointLightShadowSlot {
    pub entity: crate::ecs::world::Entity,
    pub position: nalgebra_glm::Vec3,
    pub range: f32,
    pub slot_index: u32,
    pub bias: f32,
}

#[repr(C)]
#[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
pub struct PointLightShadowData {
    pub position: [f32; 3],
    pub range: f32,
    pub bias: f32,
    pub shadow_index: i32,
    pub _padding: [f32; 2],
}

#[repr(C, align(256))]
#[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
pub struct PointShadowUniforms {
    pub view_projection: [[f32; 4]; 4],
    pub light_position: [f32; 3],
    pub light_range: f32,
    pub _padding: [f32; 44],
}
