//! https://www.faccts.de/docs/orca/6.1/manual/contents/moleculardynamics/moldyn.html

use std::path::PathBuf;

use crate::orca::make_inp_block;

#[derive(Clone, Copy, PartialEq, Debug)]
pub enum Thermostat {
    Berendensen,
    Csvr,
    Nhc,
    None,
}

impl Thermostat {
    pub fn keyword(self) -> String {
        match self {
            Self::Berendensen => "Berendensen",
            Self::Csvr => "CSVR",
            Self::Nhc => "NHC",
            Self::None => "None",
        }
        .to_string()
    }
}

/// [Command List](https://www.faccts.de/docs/orca/6.1/manual/contents/moleculardynamics/moldyn.html#command-list)
#[derive(Clone, Debug)]
pub struct Dynamics {
    /// [Timestep](https://www.faccts.de/docs/orca/6.1/manual/contents/moleculardynamics/moldyn.html#timestep) fs
    pub timestep: f32,
    /// [Initvel](https://www.faccts.de/docs/orca/6.1/manual/contents/moleculardynamics/moldyn.html#initvel) Kelvin
    pub init_vel: f32,
    /// [Thermostat](https://www.faccts.de/docs/orca/6.1/manual/contents/moleculardynamics/moldyn.html#thermostat)
    pub thermostat: Thermostat,
    /// Kelvin
    pub thermostat_temp: f32,
    /// fs
    pub thermostat_timecon: f32,
    /// [Dump](https://www.faccts.de/docs/orca/6.1/manual/contents/moleculardynamics/moldyn.html#dump)
    pub traj_out_dir: PathBuf,
    pub steps: u32,
    // todo: Epxand this
}

impl Dynamics {
    /// Note: We can ommit units from the strings in favor of default units, if we wish.
    pub fn make_inp(&self) -> String {
        let mut contents = vec![
            ("Timestep", format!("{:.1}_fs", self.timestep)),
            ("Initvel", format!("{:.1}_K", self.init_vel)),
            (
                "Thermostat",
                format!(
                    "{} {:.1}_K Timecon {:.1}_fs",
                    self.thermostat.keyword(),
                    self.thermostat_temp,
                    self.thermostat_timecon
                ),
            ),
            (
                "Dump",
                format!(
                    "Position Stride 1 Filename \"{}\"",
                    self.traj_out_dir.to_str().unwrap()
                ),
            ),
            ("Run", self.steps.to_string()),
        ];

        make_inp_block("md", &contents)
    }
}
