use fynsul_core::FynsulFunction;
use kuva::prelude::*;

use crate::utils;

fn into_lines(points: Vec<(f64, f64)>) -> Vec<Vec<(f64, f64)>> {
    // keep going until we hit NA in ys, then start a new line
    let mut lines = Vec::new();
    let mut current_line = Vec::new();

    for (x, y) in points {
        if y.is_nan() {
            if !current_line.is_empty() {
                lines.push(current_line.clone());
                current_line.clear();
            }
        } else {
            current_line.push((x, y));
        }
    }

    if !current_line.is_empty() {
        lines.push(current_line);
    }

    lines
}

// TODO: add y limits
pub fn plot(f: FynsulFunction, start: f64, end: f64, n: usize) {
    let xs = utils::linspace(start, end, n);
    let ys: Vec<f64> = xs.iter().map(|x| f(*x).unwrap_or(f64::NAN)).collect();

    let data = xs.into_iter().zip(ys).collect::<Vec<_>>();
    let lines = into_lines(data);

    println!("Plotting {} lines", lines.len());

    let plots = lines
        .into_iter()
        .map(|line| LinePlot::new().with_data(line).into())
        .collect::<Vec<_>>();

    let layout = Layout::auto_from_plots(&plots)
        .with_title("My function")
        .with_x_label("X")
        .with_y_label("Y");

    let svg = render_to_svg(plots, layout);
    std::fs::write("my_plot.svg", svg).unwrap();
}
