use bytemuck::{Pod, Zeroable};
use glam::{Mat4, Vec3};

use crate::components::CameraComponent;
use crate::entity::EntityHandle;
use crate::render;
use crate::world::{Transform, World};

#[repr(C)]
#[derive(Clone, Copy, Pod, Zeroable)]
pub struct CameraUniforms
{
    pub model: [[f32; 4]; 4],
    pub view: [[f32; 4]; 4],
    pub projection: [[f32; 4]; 4],
    pub light_direction: [f32; 3],
    pub _padding: f32,
}

impl CameraUniforms
{
    pub fn new(model: Mat4, view: Mat4, projection: Mat4, light_direction: Vec3) -> Self
    {
        Self {
            model: model.to_cols_array_2d(),
            view: view.to_cols_array_2d(),
            projection: projection.to_cols_array_2d(),
            light_direction: light_direction.to_array(),
            _padding: 0.0,
        }
    }
}

pub struct Camera;

impl Camera
{
    pub fn spawn(world: &mut World, position: Vec3) -> EntityHandle
    {
        let camera_entity = world.spawn();

        let camera_component = CameraComponent::new(render::aspect_ratio());

        let transform = Transform::from_position(position);

        world.cameras.insert(camera_entity, camera_component);
        world.transforms.insert(camera_entity, transform);

        camera_entity
    }
}
