use anyhow::bail;
use image::{GenericImageView, ImageReader};

const TOAST_TIME_SECONDS: u64 = 15;
const CENTER_X: f64 = 100.0;
const CENTER_Y: f64 = 100.0;
const BREAD_HEIGHT: f64 = 12.0;
const IDLE_HEIGHT: f64 = BREAD_HEIGHT + 5.0;
const PIXEL_SIZE_MM: f64 = 3.0;

fn main() -> anyhow::Result<()> {
    let img = ImageReader::open("/home/stephen/Downloads/scd31-qr.png")?.decode()?;

    preamble();

    for x in 0..img.width() {
        for y in 0..img.height() {
            let p = img.get_pixel(x, y);

            match p.0 {
                [0, 0, 0, 255] => {
                    toast(
                        x as f64 - (img.width() as f64 / 2.0),
                        y as f64 - (img.height() as f64 / 2.0),
                    );
                }
                [255, 255, 255, 255] => {
                    // white
                }
                _ => bail!("Pixel was not entirely black nor entirely white: {:?}", p),
            }
        }
    }

    Ok(())
}

fn preamble() {
    println!(
        r#"
G28 ; home
G90 ; absolute positioning
G0 Z{IDLE_HEIGHT}
G0 X{CENTER_X} Y{CENTER_Y}
M109 S230 ; heat hotend to 230C and wait
"#
    );
}

fn toast(x: f64, y: f64) {
    println!(
        r#"
G0 X{:.2} Y{:.2};
G0 Z{BREAD_HEIGHT};
G4 S{TOAST_TIME_SECONDS} ; wait
G0 Z{IDLE_HEIGHT};
"#,
        x * PIXEL_SIZE_MM + CENTER_X,
        y * PIXEL_SIZE_MM + CENTER_Y
    );
}