use core::f32;

use plotters::{coord::Shift, prelude::*, style::full_palette::GREEN};
use rand::{rngs::SmallRng, Rng, SeedableRng};
use ray_tracing_material::iridescent::Iridescent;
fn main() -> Result<(), Box<dyn std::error::Error>> {
    let root = BitMapBackend::new("iridescent_sweep.png", (2200, 1200)).into_drawing_area();

    root.fill(&WHITE)?;

    let d = root.split_evenly((3, 5));

    let ds = [0.1, 0.3, 0.5, 0.7, 0.9];
    let deltas = [244.0, 500.0, 988.0];

    for (i, c) in d.into_iter().enumerate() {
        draw_subplot(deltas[i / 5], 1.0 - ds[i % 5], &c)?;
    }

    root.present()?;

    Ok(())
}

fn draw_subplot<DB: DrawingBackend>(
    delta: f32,
    d2: f32,
    c: &DrawingArea<DB, Shift>,
) -> Result<(), Box<dyn std::error::Error>>
where
    <DB as plotters::prelude::DrawingBackend>::ErrorType: 'static,
{
    let mut chart = ChartBuilder::on(c)
        .margin(5)
        .x_label_area_size(30)
        .y_label_area_size(30)
        .build_cartesian_2d(0f32..f32::consts::FRAC_PI_2, 0f32..1.1f32)?;

    chart.configure_mesh().draw()?;

    let (pixel_range_x, pixel_range_y) = chart.plotting_area().get_pixel_range();
    let buckets = pixel_range_x.end - pixel_range_x.start;
    let height_per_pixel = 1.0 / (pixel_range_y.end - pixel_range_y.start) as f32;
    let samples = 10000;

    let m = Iridescent::new((1.0 - d2) * delta, d2 * delta, 1.0, 1.5, 20);

    let mut data = Vec::new();

    let mut rng = SmallRng::seed_from_u64(0);

    let plotting_area = chart.plotting_area();
    for i in 0..buckets {
        let mut s = ray_tracing_core::color::Color::black();
        let mut s_wavelength = ray_tracing_core::color::Color::black();

        for _ in 0..samples {
            let theta1 = rng.gen_range(
                (f32::consts::FRAC_PI_2 * (i as f32 / buckets as f32))
                    ..=(f32::consts::FRAC_PI_2 * ((i + 1) as f32 / buckets as f32)),
            );
            s += m.monte_carlo_reflectance(theta1, &mut rng);
            s_wavelength += ray_tracing_core::color::Color::new(
                m.averaged_reflectance(599.0, theta1),
                m.averaged_reflectance(556.0, theta1),
                m.averaged_reflectance(442.0, theta1),
            );
            // let theta2 = f32::asin(f32::sin(theta1) * 1.0 / 1.5);
            // s_wavelength += ray_tracing_core::color::Color::new(
            //     m.abs_C_squared(599.0, theta1, theta2, false),
            //     m.abs_C_squared(556.0, theta1, theta2, false),
            //     m.abs_C_squared(442.0, theta1, theta2, false),
            // );
        }

        let c = s / samples as f32;

        // data.push(c);
        data.push(s_wavelength / samples as f32);
        // dbg!(c);
        for j in 0..20 {
            plotting_area
                .draw_pixel(
                    (
                        f32::consts::FRAC_PI_2 * (i as f32 / buckets as f32),
                        1.1 - (height_per_pixel * (j as f32)),
                    ),
                    &RGBColor(
                        (c.r() * 256.0) as u8,
                        (c.g() * 256.0) as u8,
                        (c.b() * 256.0) as u8,
                    ),
                )
                .unwrap();
        }
    }

    chart.draw_series(LineSeries::new(
        data.iter().enumerate().map(|(i, c)| {
            (
                (f32::consts::FRAC_PI_2 * (i as f32 / buckets as f32)),
                c.r(),
            )
        }),
        &RED,
    ))?;

    chart.draw_series(LineSeries::new(
        data.iter().enumerate().map(|(i, c)| {
            (
                (f32::consts::FRAC_PI_2 * (i as f32 / buckets as f32)),
                c.g(),
            )
        }),
        &GREEN,
    ))?;

    chart.draw_series(LineSeries::new(
        data.iter().enumerate().map(|(i, c)| {
            (
                (f32::consts::FRAC_PI_2 * (i as f32 / buckets as f32)),
                c.b(),
            )
        }),
        &BLUE,
    ))?;

    Ok(())
}
