use crate::core::filter::CreateFilterSampler;
use shared::Float;
use shared::core::filter::FilterSampler;
use shared::core::geometry::{Point2f, Vector2f};
use shared::filters::GaussianFilter;
use shared::utils::math::gaussian;

pub trait GaussianFilterCreator {
    fn new(radius: Vector2f, sigma: Float) -> Self;
}

impl GaussianFilterCreator for GaussianFilter {
    fn new(radius: Vector2f, sigma: Float) -> Self {
        let exp_x = gaussian(radius.x(), 0., sigma);
        let exp_y = gaussian(radius.y(), 0., sigma);

        let sampler = FilterSampler::new(radius, move |p: Point2f| {
            let gx = (gaussian(p.x(), 0., sigma) - exp_x).max(0.0);
            let gy = (gaussian(p.y(), 0., sigma) - exp_y).max(0.0);
            gx * gy
        });

        Self {
            radius,
            sigma,
            exp_x: gaussian(radius.x(), 0., sigma),
            exp_y: gaussian(radius.y(), 0., sigma),
            sampler,
        }
    }
}
