// ==================
// Standard simplices
// ==================

use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize, Deserialize)]
pub struct Simplex2 {
    /// The `neighbours` and `vertices` must be stored in counter-clockwise (positive) direction.
    /// The relative ordering must be such that the vertex corresponding to a neighbouring triangle
    /// is the vertex opposite the triangle.
    pub neighbours: [usize; 3],
    /// See notes on `neighbours`
    pub vertices: [usize; 3],
}
pub type Triangle = Simplex2;

// ================
// Causal simplices
// ================

/// Kind/type/variant specification of a triangle/2-simplex.
///
/// Variant `S21` refers to a triangle with 2 vertices at the previous time-slice
/// to the other one, where variant `S12` is the opposite.
#[derive(
    Debug, Clone, Copy, PartialEq, Eq, Hash, Default, PartialOrd, Ord, Serialize, Deserialize,
)]
pub enum CausalSimplex2Kind {
    #[default]
    S21 = 0,
    S12 = 1,
}
pub type CausalTriangleKind = CausalSimplex2Kind;

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize, Deserialize)]
pub struct CausalSimplex2 {
    pub t: u16,
    pub kind: CausalTriangleKind,
    /// The `neighbours` and `vertices` must be stored in counter-clockwise (positive) direction.
    /// The relative ordering must be such that the vertex corresponding to a neighbouring triangle
    /// is the vertex opposite the triangle.
    /// Additionally, to fix the possible cyclic permutations, the first (element 0) neighbour
    /// must be the time-like neighbour, i.e. the one that is on the next or previous time-slice.
    pub neighbours: [usize; 3],
    /// See notes on `neighbours`
    pub vertices: [usize; 3],
}
pub type CausalTriangle = CausalSimplex2;

// =======================================
// Causal to non-causal simplex conversion
// =======================================

impl From<CausalSimplex2> for Simplex2 {
    /// Convert [`CausalTriangle`] to [`Triangle`] by simply dropping `time` and `kind` information.
    fn from(value: CausalSimplex2) -> Self {
        Simplex2 {
            neighbours: value.neighbours,
            vertices: value.vertices,
        }
    }
}

impl From<&CausalSimplex2> for Simplex2 {
    /// Convert [`&CausalTriangle`](CausalTriangle) to [`Triangle`] by copying
    /// only the neighbour and vertex information.
    fn from(value: &CausalSimplex2) -> Self {
        Simplex2 {
            neighbours: value.neighbours,
            vertices: value.vertices,
        }
    }
}
