use crate::Arena;
use crate::samplers::CreateSampler;
use crate::utils::{FileLoc, ParameterDictionary};
use anyhow::{Result, anyhow};
use shared::core::geometry::Point2i;
use shared::core::sampler::{
    HaltonSampler, IndependentSampler, PaddedSobolSampler, Sampler, SobolSampler,
    StratifiedSampler, ZSobolSampler,
};

pub trait SamplerFactory {
    fn create(
        name: &str,
        params: &ParameterDictionary,
        full_res: Point2i,
        loc: &FileLoc,
        arena: &Arena,
    ) -> Result<Self>
    where
        Self: Sized;
}

impl SamplerFactory for Sampler {
    fn create(
        name: &str,
        params: &ParameterDictionary,
        full_res: Point2i,
        loc: &FileLoc,
        arena: &Arena,
    ) -> Result<Self>
    where
        Self: Sized,
    {
        match name {
            "zsobol" => ZSobolSampler::create(params, full_res, loc, arena),
            "paddedsobol" => PaddedSobolSampler::create(params, full_res, loc, arena),
            "halton" => HaltonSampler::create(params, full_res, loc, arena),
            "sobol" => SobolSampler::create(params, full_res, loc, arena),
            "Independent" => IndependentSampler::create(params, full_res, loc, arena),
            "stratified" => StratifiedSampler::create(params, full_res, loc, arena),
            _ => Err(anyhow!("Film type '{}' unknown at {}", name, loc)),
        }
    }
}
