// Copyright (C) 2025 Christian Mauduit <ufoot@ufoot.org>

#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use shortestpath::mesh_2d::Index2D;
use shortestpath::mesh_3d::Index3D;
use shortestpath::Mesh;

use crate::{Place, Place2D, Place3D};

#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Battlefield<P: Place> {
    places: Vec<P>,
}

impl<P: Place> Battlefield<P> {
    pub fn new(places: Vec<P>) -> Self {
        Self { places }
    }

    pub fn places(&self) -> &[P] {
        &self.places
    }

    pub fn get_place(&self, index: usize) -> Option<&P> {
        self.places.get(index)
    }

    pub fn place_count(&self) -> usize {
        self.places.len()
    }
}

impl Battlefield<Place2D> {
    pub fn from_mesh_2d<M: Index2D + Mesh>(mesh: &M) -> Result<Self, shortestpath::Error> {
        let mut places = Vec::new();
        for index in 0..mesh.len() {
            places.push(Place2D::from_index(mesh, index)?);
        }
        Ok(Self { places })
    }
}

impl Battlefield<Place3D> {
    pub fn from_mesh_3d<M: Index3D + Mesh>(mesh: &M) -> Result<Self, shortestpath::Error> {
        let mut places = Vec::new();
        for index in 0..mesh.len() {
            places.push(Place3D::from_index(mesh, index)?);
        }
        Ok(Self { places })
    }
}
