mod coloration;
mod gender;
mod phenotype;
mod species;
mod stats;

use phenotype::Phenotype;

use crate::{choice_function::ChoiceFunction, genetics::Genotype};

#[derive(Clone)]
pub struct Creature {
    genotype: Genotype,
}

impl Creature {
    pub fn generate(choice_function: ChoiceFunction) -> Self {
        Creature {
            genotype: Genotype::generate::<Phenotype>(choice_function),
        }
    }

    pub fn breed(&self, choice_function: ChoiceFunction, other: &Creature) -> Creature {
        return Creature {
            genotype: self.genotype.breed(choice_function, &other.genotype),
        };
    }

    pub fn phenotype(&self) -> Phenotype {
        let phenotype: Phenotype = self.genotype.load();
        return phenotype;
    }

    pub fn profile(&self) -> String {
        let phenotype: Phenotype = self.phenotype();
        let mut profile = phenotype.profile();
        if true {
            profile.push_str("\nGenome:\n");

            for (chromosome, (lhs, rhs)) in self.genotype.chromosomes.iter() {
                profile.push_str(&format!("  {}[l]: {}\n", chromosome, lhs));
                profile.push_str(&format!("  {}[r]: {}\n", chromosome, rhs));
            }
        }
        return profile;
    }
}
