mod royale;
mod standard;

use blanket::blanket;
use enum_dispatch::enum_dispatch;
use rand::Rng;
use royale::Royale;
use standard::Standard;

use crate::types::wire::Game;

use super::Board;

#[blanket(derive(Ref, Arc, Mut, Box))]
#[enum_dispatch(Maps)]
pub trait Map {
    /// Called before the board is updated
    fn pre_update(&self, board: &mut Board, rng: &mut impl Rng);

    /// Called after the board is updated
    fn post_update(&self, board: &mut Board, rng: &mut impl Rng);
}

#[enum_dispatch]
#[derive(Debug, Clone, Copy)]
pub enum Maps {
    Standard,
    Royale,
}

pub trait MapId {
    /// ID of the map for detection
    const ID: &str;
}

impl From<&Game> for Maps {
    fn from(value: &Game) -> Self {
        match value.map.as_ref() {
            Royale::ID => Royale::from(&value.ruleset.settings).into(),
            _ => Standard::from(&value.ruleset.settings).into(),
        }
    }
}
