use std::ops::Add;

use enum_dispatch::enum_dispatch;

/// 特殊量ID
#[derive(PartialEq, PartialOrd, Eq, Clone, Copy, Hash)]
pub struct ID(usize);

/// 实体
/// 性质：具有ID
#[enum_dispatch]
pub trait Entity {
    fn id(&self) -> ID;
}

/// 定义一些标量
/// 标量必须实现统一的trait
pub trait Scaler: Clone + Copy + Sized {}

/// 坐标
#[derive(Clone, Copy)]
pub struct Pos([f64; 3]);
impl Scaler for Pos {}
impl Add<Pos> for Pos {
    type Output = Pos;
    fn add(self, rhs: Self) -> Self::Output {
        let mut rtn = [0f64; 3];
        for i in 0..3 {
            rtn[i] = self.0[i] + rhs.0[i];
        }
        Pos(rtn)
    }
}
impl Add<Velo> for Pos {
    type Output = Pos;
    fn add(self, rhs: Velo) -> Self::Output {
        let mut rtn = [0f64; 3];
        for i in 0..3 {
            rtn[i] = self.0[i] + rhs.0[i];
        }
        Pos(rtn)
    }
}

/// 速度
#[derive(Clone, Copy)]
pub struct Velo([f64; 3]);
impl Scaler for Velo {}
impl Add<Velo> for Velo {
    type Output = Velo;
    fn add(self, rhs: Velo) -> Self::Output {
        let mut rtn = [0f64; 3];
        for i in 0..3 {
            rtn[i] = self.0[i] + rhs.0[i];
        }
        Velo(rtn)
    }
}
