use crate::genetics::{Genetic, Transcriber};

#[derive(Default)]
pub struct Stats {
    pub iq: Stat<'.', '!', 5, 10>, // 5-15
    pub eq: Stat<'.', '!', 5, 10>, // 5-15
}

impl Stats {
    pub fn profile(&self) -> String {
        format!("IQ: {}\nEQ: {}\n", self.iq.value(), self.eq.value())
    }
}

impl Genetic for Stats {
    fn transcribe(&mut self, t: Transcriber) {
        self.iq.transcribe(t.nest("IQ"));
        self.eq.transcribe(t.nest("EQ"));
    }
}

#[derive(Clone, Copy)]
pub struct Stat<const OFF: char, const ON: char, const MIN: usize, const RANGE: usize> {
    values: [bool; RANGE],
}

impl<const OFF: char, const ON: char, const MIN: usize, const RANGE: usize>
    Stat<OFF, ON, MIN, RANGE>
{
    pub fn value(&self) -> usize {
        let mut value = MIN;
        for v in self.values.iter() {
            value += *v as usize;
        }
        return value;
    }
}

impl<const OFF: char, const ON: char, const MIN: usize, const RANGE: usize> Default
    for Stat<OFF, ON, MIN, RANGE>
{
    fn default() -> Self {
        Self {
            values: [false; RANGE],
        }
    }
}

impl<const OFF: char, const ON: char, const MIN: usize, const RANGE: usize> Genetic
    for Stat<OFF, ON, MIN, RANGE>
{
    fn transcribe(&mut self, mut t: Transcriber) {
        for v in self.values.iter_mut() {
            t.express(v, &[(OFF, false), (ON, true)])
        }
    }
}
