/// Different kind of slabs (those rectangles the ball can roll on).
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SlabKind {
    /// Nothing there, Void means empty. Preferring this implementation
    /// over an Option as this is really critical and low-level,
    /// and an Option would imply pointer and possibly a non-contiguity
    /// pf data.
    ///
    /// The base index is -1, this way the floor is 0, so they
    /// translate directly into MeshLibrary items.
    Void = -1,
    /// Default slab kind, a basic stuff one can roll on.
    Floor,
    /// HighLight is a highlighted slab, just a visual effect.
    /// It should never be returned by the level API, only be used
    /// for rendering within Godot.
    HighLight,
}

impl SlabKind {
    pub fn as_item(self) -> i64 {
        self as i64
    }

    pub fn from_item(item: i64) -> Self {
        match item {
            0 => SlabKind::Floor,
            1 => SlabKind::HighLight,
            _ => SlabKind::Void,
        }
    }
}

impl std::fmt::Display for SlabKind {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let c = match self {
            SlabKind::Void => " ",
            SlabKind::Floor => "#",
            SlabKind::HighLight => "*",
        };
        write!(f, "{}", c)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_fmt() {
        assert_eq!(" ", format!("{}", SlabKind::Void));
        assert_eq!("#", format!("{}", SlabKind::Floor));
    }
}
