/*
    Hurry Curry! - a game about cooking
    Copyright 2024 metamuffin
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, version 3 of the License only.
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.
    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see .
*/
pub mod conveyor;
use crate::{data::Gamedata, game::Tile};
use anyhow::{anyhow, Result};
use conveyor::Conveyor;
use glam::IVec2;
use hurrycurry_protocol::PacketC;
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, VecDeque};
pub trait EntityT: Clone {
    fn tick(
        &mut self,
        data: &Gamedata,
        points: &mut i64,
        packet_out: &mut VecDeque,
        tiles: &mut HashMap,
        dt: f32,
    ) -> Result<()>;
}
#[derive(Debug, Clone)]
pub enum Entity {
    Conveyor(Conveyor),
}
impl EntityT for Entity {
    fn tick(
        &mut self,
        data: &Gamedata,
        points: &mut i64,
        packet_out: &mut VecDeque,
        tiles: &mut HashMap,
        dt: f32,
    ) -> Result<()> {
        match self {
            Entity::Conveyor(x) => x.tick(data, points, packet_out, tiles, dt),
        }
    }
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum EntityDecl {
    Conveyor {
        from: Option,
        to: Option,
        dir: Option,
        speed: Option,
    },
}
pub fn construct_entity(pos: Option, decl: &EntityDecl) -> Result {
    Ok(match decl.to_owned() {
        EntityDecl::Conveyor {
            from,
            to,
            speed,
            dir,
        } => {
            let from = from.or(pos).ok_or(anyhow!("conveyor has no start"))?;
            let to = to
                .or(dir.map(|s| s + from))
                .ok_or(anyhow!("conveyor has no destination"))?;
            Entity::Conveyor(Conveyor {
                from,
                to,
                max_cooldown: 1. / speed.unwrap_or(2.),
                ..Default::default()
            })
        }
    })
}