// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use std::{fs::File, io::Write, path::PathBuf};

use arrayvec::ArrayVec;
use clap::{CommandFactory, ErrorKind, Parser};
use rayon::prelude::*;
use roots::Roots;

const LINES_PER_PIXEL: usize = 58;
const INCREMENT: f64 = 1.0 / (LINES_PER_PIXEL as f64);

#[derive(Parser)]
#[clap(about = "high-precision Bézier renderer")]
struct Config {
    /// Width of the image
    #[clap(short, long, default_value = "1000")]
    width: usize,
    /// Height of the image
    #[clap(short, long, default_value = "1000")]
    height: usize,
    /// .pgm output file
    #[clap(short, long, parse(from_os_str), default_value = "ref.pgm")]
    file: PathBuf,
    points: Vec<f64>,
}

fn roots_at(y: f64, points: &[f64]) -> ArrayVec<f64, 3> {
    let roots = match *points {
        [a, b] => roots::find_roots_linear(a, b - y),
        [a, b, c] => roots::find_roots_quadratic(a, b, c - y),
        [a, b, c, d] => roots::find_roots_cubic(a, b, c, d - y),
        _ => unreachable!(),
    };

    match roots {
        Roots::No(_) => ArrayVec::new(),
        Roots::One(roots) => roots.as_slice().try_into().unwrap(),
        roots::Roots::Two(roots) => roots.as_slice().try_into().unwrap(),
        roots::Roots::Three(roots) => roots.as_slice().try_into().unwrap(),
        _ => unreachable!(),
    }
}

fn lerp(t: f64, a: f64, b: f64) -> f64 {
    t.mul_add(b, (-t).mul_add(a, a))
}

fn eval(t: f64, points: &[f64]) -> f64 {
    match points {
        [a, b] => lerp(t, *a, *b),
        points => lerp(t, eval(t, &points[..points.len() - 1]), eval(t, &points[1..])),
    }
}

fn intersections_at(y: f64, points: &[f64]) -> ArrayVec<f64, 3> {
    let roots = match *points {
        [_, y0, _, y1] => roots_at(y, &[y1 - y0, y0]),
        [_, y0, _, y1, _, y2] => roots_at(y, &[y0 - 2.0 * y1 + y2, 2.0 * (y1 - y0), y0]),
        [_, y0, _, y1, _, y2, _, y3] => roots_at(
            y,
            &[y3 + 3.0 * (y1 - y2) - y0, 3.0 * (y0 - 2.0 * y1 + y2), 3.0 * (y1 - y0), y0],
        ),
        _ => unreachable!(),
    };

    roots
        .into_iter()
        .filter_map(|t| {
            (0.0..=1.0).contains(&t).then(|| match *points {
                [x0, _, x1, _] => eval(t, &[x0, x1]),
                [x0, _, x1, _, x2, _] => eval(t, &[x0, x1, x2]),
                [x0, _, x1, _, x2, _, x3, _] => eval(t, &[x0, x1, x2, x3]),
                _ => unreachable!(),
            })
        })
        .collect()
}

fn linear_to_srgb(l: f32) -> u8 {
    // From Hacker's Delight, p. 378-380. 2 ^ 23 as f32.
    const C23: u32 = 0x4B00_0000;

    let l = if l <= 0.0031308 { 12.92 * l } else { 1.055 * l.powf(1.0 / 2.4) - 0.055 };

    let max = u8::MAX as f32;

    let scaled = (l * max).clamp(0.0, max);
    let val = scaled + f32::from_bits(C23);

    val.to_bits() as u8
}

fn render_line(line: &mut [u8], y: usize, points: &[f64]) {
    let mut coverage = vec![0.0; line.len()];
    let intersections: Vec<_> = (0..LINES_PER_PIXEL)
        .into_iter()
        .map(|i| {
            let y = y as f64 + i as f64 * INCREMENT;

            let mut intersections = intersections_at(y, points);

            if intersections.len() % 2 != 0 {
                if !intersections_at(y - INCREMENT, points).is_empty()
                    && !intersections_at(y + INCREMENT, points).is_empty()
                {
                    intersections.push(line.len() as f64);
                } else {
                    intersections.clear();
                }
            }

            intersections
        })
        .flatten()
        .collect();

    for x in intersections.chunks(2) {
        for c in &mut coverage[x[0].ceil() as usize..x[1].floor() as usize] {
            *c += INCREMENT as f32;
        }

        if x[0].floor() != x[0].ceil() {
            coverage[x[0].floor() as usize] += ((1.0 - x[0].fract()) * INCREMENT) as f32;
        }

        if x[1].floor() != x[1].ceil() {
            coverage[x[1].floor() as usize] += (x[1].fract() * INCREMENT) as f32;
        }
    }

    for (x, c) in line.iter_mut().zip(coverage.into_iter()) {
        *x = linear_to_srgb(1.0 - c)
    }
}

fn main() {
    let config = Config::parse();

    if config.points.len() < 4 {
        Config::command().error(ErrorKind::TooFewValues, "[POINTS] need to be at least 2").exit();
    }

    if config.points.len() > 8 {
        Config::command().error(ErrorKind::TooFewValues, "[POINTS] need to be at most 8").exit();
    }

    if config.points.len() % 2 != 0 {
        Config::command()
            .error(ErrorKind::TooFewValues, "[POINTS] need to come in x y pairs")
            .exit();
    }

    let mut buffer = vec![255u8; config.width * config.height];

    buffer.par_chunks_mut(config.width).enumerate().for_each(|(y, line)| {
        render_line(line, y, &config.points);
    });

    let mut output = File::options().write(true).create(true).open(config.file).unwrap();
    output.write_all(format!("P5\n{} {}\n255\n", config.width, config.height).as_bytes()).unwrap();
    output.write_all(&buffer).unwrap();
}
