use bevy::prelude::*;

use crate::util::Vector3;

pub type Vector3D = Vector3<f64>;

impl Vector3D {
    pub const ZERO: Self = Self {
        x: 0.0,
        y: 0.0,
        z: 0.0,
    };
    pub const ONE: Self = Self {
        x: 1.0,
        y: 1.0,
        z: 1.0,
    };
    pub const UP: Self = Self {
        x: 0.0,
        y: 1.0,
        z: 0.0,
    };
    pub const DOWN: Self = Self {
        x: 0.0,
        y: -1.0,
        z: 0.0,
    };
    pub const LEFT: Self = Self {
        x: -1.0,
        y: 0.0,
        z: 0.0,
    };
    pub const RIGHT: Self = Self {
        x: 1.0,
        y: 0.0,
        z: 0.0,
    };
    pub const FORWARD: Self = Self {
        x: 0.0,
        y: 0.0,
        z: -1.0,
    };
    pub const BACK: Self = Self {
        x: 0.0,
        y: 0.0,
        z: 1.0,
    };

    pub fn rotate_around_axis(&self, axis: &Self, angle: f64) -> Self {
        *self * angle.cos()
            + axis.cross(self) * angle.sin()
            + *axis * axis.dot(self) * (1.0 - angle.cos())
    }
}

impl From<Vec3> for Vector3D {
    fn from(vec: Vec3) -> Self {
        Self {
            x: vec.x as f64,
            y: vec.y as f64,
            z: vec.y as f64,
        }
    }
}

impl From<Vector3D> for Vec3 {
    fn from(vec: Vector3D) -> Self {
        Vec3 {
            x: vec.x as f32,
            y: vec.y as f32,
            z: vec.z as f32,
        }
    }
}
