use nalgebra_glm as glm;

use crate::model::Model;

pub struct Node {
    pub name: String,
    pub gameobject: GameObject,
    pub children: Vec<Node>,
}

impl Node {
    pub fn new(name: String, gameobject: GameObject) -> Self {
	Node {
	    name,
	    gameobject,
	    children: Vec::new(),
	}
    }
    pub fn add_child(&mut self, child: Node) {
	self.children.push(child)
    }
    pub fn find_node(&mut self, name: &str) -> Option<&mut Node> {
	self.children.iter_mut().find(|node| node.name == name)
    }
}

pub enum GameObject {
    Null,
    Mesh(Box<Mesh>),
}

#[derive(Clone, Copy)]
pub struct Transform {
    pub position: glm::Vec3,
    pub rotation: glm::Vec3,
    pub scale: glm::Vec3,
}

impl Default for Transform {
    fn default() -> Self {
	Transform {
	    position: glm::zero(),
	    rotation: glm::zero(),
	    scale: glm::vec3(1.0, 1.0, 1.0),
	}
    }
}

pub trait Spatial {
    fn get_transform(&self) -> Transform;
    fn set_transform(&mut self, transform: Transform);
}

pub struct Mesh {
    pub model: Model,
    transform: Transform,
}

impl Mesh {
    pub fn new(model: Model) -> Self {
	Mesh {
	    model,
	    transform: Default::default(),
	}
    }
}

impl Spatial for Mesh {
    fn get_transform(&self) -> Transform {
	self.transform
    }
    fn set_transform(&mut self, transform: Transform) {
	self.transform = transform;
    }
}
