Documentation
mod modes;

use crate::{Picasso, PicassoResult};
use image::{imageops::FilterType, GenericImageView, Rgba};
pub use modes::PicassoMode;
use purrmitive::{
    core::{average_color, diff_full, PurrContext, PurrHillClimbModel},
    DynamicImage,
};
use std::sync::{Arc, RwLock};


impl Picasso {
    pub fn render(&mut self, img: DynamicImage, output: &str) -> PicassoResult<()> {
        let (w, h ) = img.dimensions();
        let origin_img = img.to_rgba8();
        let color = average_color(&origin_img);

        let mut current_img = image::ImageBuffer::new(w, h);
        for y in 0..h {
            for x in 0..w {
                let pixel: &mut Rgba<u8> = current_img.get_pixel_mut(x as u32, y as u32);
                pixel.0 = color.0;
            }
        }

        let score = diff_full(&origin_img, &current_img);
        let scale = self.out_size as f32 / w.max(h) as f32;

        let model_ctx = PurrContext {
            w,
            h,
            scale,
            origin_img: Arc::new(origin_img),
            current_img: Arc::new(RwLock::new(current_img)),
            rng: self.rng.clone(),
            score,
            bg: color,
            alpha: self.alpha,
        };

        let mut model_hillclimb = PurrHillClimbModel::new(model_ctx, 1000, 16, 100);
        let mut model_runner = self.shape_type.build_runner(self.num_shapes, num_cpus::get());
        model_runner.run(&mut model_hillclimb);
        model_runner.save(&model_hillclimb.context, output);
        Ok(())
    }
}