use bytes2rgb::*;

fn chroma_err(palette: &TonedPalette) -> f64 {
    let (mc, bc) = (palette.mean_color(), palette.base());
    let (a, b) = (chroma_rec709(mc), chroma_rec709(bc));
    ((a.0 - b.0).powi(2) + (a.1 - b.1).powi(2)).sqrt()
}

fn main() {
    let bases: [(&str, [u8; 3]); 12] = [
        ("white", [0xff, 0xff, 0xff]),
        ("black", [0x00, 0x00, 0x00]),
        ("grey", [0x80, 0x80, 0x80]),
        ("pink", [0xff, 0xc0, 0xcb]),
        ("red", [0xff, 0x00, 0x00]),
        ("orange", [0xff, 0x80, 0x00]),
        ("yellow", [0xff, 0xff, 0x00]),
        ("green", [0x00, 0xc0, 0x40]),
        ("cyan", [0x00, 0xc0, 0xc0]),
        ("blue", [0x20, 0x60, 0xc0]),
        ("navy", [0x10, 0x18, 0x40]),
        ("lilac", [0xc8, 0xb4, 0xe6]),
    ];

    println!("{:>7}  preset 20bit/±48              balanced(1.2)", "");
    for (name, base) in bases {
        let preset = TonedPalette::from_config(TonedConfig {
            base,
            luma_tolerance: 48,
            bits_per_pixel: 20,
            ordering: ToneOrdering::ChromaProximity,
        });
        let preset_str = match &preset {
            Ok(p) => format!("mean {:?} err {:>5.1}", p.mean_color(), chroma_err(p)),
            Err(_) => "INFEASIBLE".to_string(),
        };

        let auto = TonedPalette::balanced(base, 1.2).unwrap();
        let c = auto.config();
        println!(
            "{name:>7}  {preset_str:<38} ±{:>3} luma {:>2} bits  mean {:?} err {:>5.1}",
            c.luma_tolerance,
            c.bits_per_pixel,
            auto.mean_color(),
            chroma_err(&auto)
        );
    }
}
