use std::any::Any;
use crate::core::Component;
use crate::math::Vec2;

#[derive(Debug, Clone, PartialEq)]
pub struct Transform {
    pub position: Vec2,
    pub rotation: f32,
    pub scale: Vec2,
}

impl Transform {
    pub fn new(x: f32, y: f32) -> Self {
        Self {
            position: Vec2::new(x, y),
            rotation: 0.0,
            scale: Vec2::one(),
        }
    }
    
    pub fn default() -> Self {
        Self::new(0.0, 0.0)
    }
    
    /// 위치만 지정한 Transform
    pub fn at_position(position: Vec2) -> Self {
        Self {
            position,
            rotation: 0.0,
            scale: Vec2::one(),
        }
    }
    
    pub fn set_position(&mut self, x: f32, y: f32) {
        self.position = Vec2::new(x, y);
    }
    
    pub fn translate(&mut self, dx: f32, dy: f32) {
        self.position = self.position + Vec2::new(dx, dy);
    }
    
    pub fn set_rotation(&mut self, rotation: f32) {
        self.rotation = rotation;
    }
    
    pub fn rotate(&mut self, delta_rotation: f32) {
        self.rotation += delta_rotation;
    }
    
    pub fn set_rotation_degrees(&mut self, degrees: f32) {
        self.rotation = degrees.to_radians();
    }
    
    pub fn rotate_degrees(&mut self, degrees: f32) {
        self.rotation += degrees.to_radians();
    }
    
    pub fn set_scale(&mut self, x: f32, y: f32) {
        self.scale = Vec2::new(x, y);
    }
    
    pub fn set_uniform_scale(&mut self, scale: f32) {
        self.scale = Vec2::new(scale, scale);
    }
    
    pub fn forward(&self) -> Vec2 {
        Vec2::new(self.rotation.cos(), self.rotation.sin())
    }
    
    pub fn right(&self) -> Vec2 {
        Vec2::new(-self.rotation.sin(), self.rotation.cos())
    }
}

impl Component for Transform {
    fn as_any(&self) -> &dyn Any {
        self
    }
    
    fn as_any_mut(&mut self) -> &mut dyn Any {
        self
    }
    
    fn clone_box(&self) -> Box<dyn Component> {
        Box::new(self.clone())
    }
}