// Copyright 2021 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::num::NonZeroUsize;

use crate::{
    math,
    shapes::command_path::{Command, CommandPath, CommandPathBuilder},
};

#[derive(Clone, Copy, Debug)]
struct CubicSegment {
    t: f32,
    len: f32,
}

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
enum PathPartType {
    Line,
    Cubic(NonZeroUsize),
}

#[derive(Clone, Copy, Debug)]
struct PathPart {
    r#type: PathPartType,
    offset: usize,
    num_segments: usize,
}

impl PathPart {
    pub fn line(offset: usize) -> Self {
        Self { r#type: PathPartType::Line, offset, num_segments: 0 }
    }

    pub fn cubic(offset: usize) -> Self {
        Self { r#type: PathPartType::Cubic(NonZeroUsize::new(1).unwrap()), offset, num_segments: 0 }
    }
}

fn compute_hull(
    from: math::Vec,
    from_out: math::Vec,
    to_in: math::Vec,
    to: math::Vec,
    t: f32,
    hull: &mut [math::Vec; 6],
) {
    hull[0] = from.lerp(from_out, t);
    hull[1] = from_out.lerp(to_in, t);
    hull[2] = to_in.lerp(to, t);

    hull[3] = hull[0].lerp(hull[1], t);
    hull[4] = hull[1].lerp(hull[2], t);

    hull[5] = hull[3].lerp(hull[4], t);
}

fn too_far(a: math::Vec, b: math::Vec) -> bool {
    const TOO_FAR: f32 = 1.0;
    (a.x - b.x).abs().max((a.y - b.y).abs()) > TOO_FAR
}

fn should_split_cubic(
    from: math::Vec,
    from_out: math::Vec,
    to_in: math::Vec,
    to: math::Vec,
) -> bool {
    let one_third = from.lerp(to, 1.0 / 3.0);
    let two_thirds = from.lerp(to, 2.0 / 3.0);

    too_far(from_out, one_third) || too_far(to_in, two_thirds)
}

#[allow(clippy::too_many_arguments)]
fn segment_cubic(
    from: math::Vec,
    from_out: math::Vec,
    to_in: math::Vec,
    to: math::Vec,
    mut running_length: f32,
    t0: f32,
    t1: f32,
    segments: &mut Vec<CubicSegment>,
) -> f32 {
    const MIN_SEGMENT_LENGTH: f32 = 0.05;

    if should_split_cubic(from, from_out, to_in, to) {
        let half_t = (t0 + t1) / 2.0;

        let mut hull = [math::Vec::default(); 6];
        compute_hull(from, from_out, to_in, to, 0.5, &mut hull);

        running_length =
            segment_cubic(from, hull[0], hull[3], hull[5], running_length, t0, half_t, segments);
        running_length =
            segment_cubic(hull[5], hull[4], hull[2], to, running_length, half_t, t1, segments);
    } else {
        let length = from.distance(to);
        running_length += length;

        if length > MIN_SEGMENT_LENGTH {
            segments.push(CubicSegment { t: t1, len: running_length });
        }
    }

    running_length
}

#[derive(Debug)]
pub struct MetricsPath {
    points: Vec<math::Vec>,
    cubic_segments: Vec<CubicSegment>,
    parts: Vec<PathPart>,
    lengths: Vec<f32>,
}

impl MetricsPath {
    pub fn new(command_path: &CommandPath) -> Self {
        let mut points = Vec::new();
        let mut parts = Vec::new();

        for command in &command_path.commands {
            match *command {
                Command::MoveTo(p) => points.push(p),
                Command::LineTo(p) => {
                    parts.push(PathPart::line(points.len()));
                    points.push(p);
                }
                Command::CubicTo(c0, c1, p) => {
                    parts.push(PathPart::cubic(points.len()));
                    points.push(c0);
                    points.push(c1);
                    points.push(p);
                }
                Command::Close => {
                    if parts.last().map(|part| part.r#type) == Some(PathPartType::Line) {
                        // We auto close the last part if it's a cubic, if it's not then make
                        // sure to add the final part in so we can compute its length too.
                        parts.push(PathPart::line(points.len()));
                        points.push(points[0]);
                    }
                }
            }
        }

        Self { points, cubic_segments: Vec::new(), parts, lengths: Vec::new() }
    }

    pub fn compute_length(&mut self) -> f32 {
        self.cubic_segments.clear();
        self.lengths.clear();

        let mut i = 0;
        let mut length = 0.0;

        for part in &mut self.parts {
            match part.r#type {
                PathPartType::Line => {
                    let from = self.points[i];
                    let to = self.points[i + 1];

                    i += 1;

                    let part_length = from.distance(to);
                    self.lengths.push(part_length);
                    length += part_length;
                }
                PathPartType::Cubic(ref mut ci) => {
                    let from = self.points[i];
                    let from_out = self.points[i + 1];
                    let to_in = self.points[i + 2];
                    let to = self.points[i + 3];

                    i += 3;

                    let index = self.cubic_segments.len();
                    *ci = NonZeroUsize::new(index + 1).unwrap();

                    let part_length = segment_cubic(
                        from,
                        from_out,
                        to_in,
                        to,
                        0.0,
                        0.0,
                        1.0,
                        &mut self.cubic_segments,
                    );
                    self.lengths.push(part_length);
                    length += part_length;
                    part.num_segments = self.cubic_segments.len() - index;
                }
            }
        }

        length
    }

    pub fn trimmed(
        &self,
        builder: &mut CommandPathBuilder,
        start_len: f32,
        end_len: f32,
        move_to: bool,
    ) {
        assert!(end_len >= start_len);

        if start_len == end_len || self.parts.is_empty() {
            return;
        }

        let parts_and_lengths = self.lengths.iter().scan(0.0, |len, &part_len| {
            let old_len = *len;
            *len += part_len;

            Some((old_len, part_len))
        });

        let first_part = parts_and_lengths
            .clone()
            .enumerate()
            .find(|(_, (len, part_len))| len + part_len > start_len)
            .map(|(i, (len, part_len))| (i, (start_len - len) / part_len));

        if let Some((first_part_index, start_t)) = first_part {
            let (last_part_index, end_t) = parts_and_lengths
                .enumerate()
                .skip(first_part_index)
                .find(|(_, (len, part_len))| len + part_len >= end_len)
                .map(|(i, (len, part_len))| (i, (end_len - len) / part_len))
                .unwrap_or_else(|| (self.parts.len() - 1, 1.0));

            let start_t = start_t.clamp(0.0, 1.0);
            let end_t = end_t.clamp(0.0, 1.0);

            if first_part_index == last_part_index {
                self.extract_sub_part(first_part_index, start_t, end_t, move_to, builder);
            } else {
                self.extract_sub_part(first_part_index, start_t, 1.0, move_to, builder);

                for part in &self.parts[first_part_index + 1..last_part_index] {
                    match part.r#type {
                        PathPartType::Line => {
                            builder.line_to(self.points[part.offset]);
                        }
                        PathPartType::Cubic(_) => {
                            builder.cubic_to(
                                self.points[part.offset],
                                self.points[part.offset + 1],
                                self.points[part.offset + 2],
                            );
                        }
                    }
                }

                self.extract_sub_part(last_part_index, 0.0, end_t, false, builder);
            }
        }
    }

    fn extract_sub_part(
        &self,
        i: usize,
        mut start_t: f32,
        mut end_t: f32,
        move_to: bool,
        builder: &mut CommandPathBuilder,
    ) {
        let part = self.parts[i];
        match part.r#type {
            PathPartType::Line => {
                let from = self.points[part.offset - 1];
                let to = self.points[part.offset];

                let dir = to - from;

                if move_to {
                    builder.move_to(from + dir * start_t);
                }
                builder.line_to(from + dir * end_t);
            }
            PathPartType::Cubic(ci) => {
                let starting_segment_index = ci.get() - 1;
                let mut start_end_segment_index = starting_segment_index;
                let ending_segment_index = starting_segment_index + part.num_segments;

                let len = self.lengths[i];
                if start_t != 0.0 {
                    let start_len = start_t * len;
                    for si in starting_segment_index..ending_segment_index {
                        let segment = self.cubic_segments[si];
                        if segment.len >= start_len {
                            if si == starting_segment_index {
                                start_t = segment.t * (start_len / segment.len);
                            } else {
                                let previous_len = self.cubic_segments[si - 1].len;

                                let t = (start_len - previous_len) / (segment.len - previous_len);
                                start_t = math::lerp(self.cubic_segments[si - 1].t, segment.t, t);
                            }

                            // Help out the ending segment finder by setting its
                            // start to where we landed while finding the first
                            // segment, that way it can skip a bunch of work.
                            start_end_segment_index = si;
                            break;
                        }
                    }
                }

                if end_t != 1.0 {
                    let end_len = end_t * len;
                    for si in start_end_segment_index..ending_segment_index {
                        let segment = self.cubic_segments[si];
                        if segment.len >= end_len {
                            if si == starting_segment_index {
                                end_t = segment.t * (end_len / segment.len);
                            } else {
                                let previous_len = self.cubic_segments[si - 1].len;

                                let t = (end_len - previous_len) / (segment.len - previous_len);
                                end_t = math::lerp(self.cubic_segments[si - 1].t, segment.t, t);
                            }

                            break;
                        }
                    }
                }

                let mut hull = [math::Vec::default(); 6];

                let from = self.points[part.offset - 1];
                let from_out = self.points[part.offset];
                let to_in = self.points[part.offset + 1];
                let to = self.points[part.offset + 2];

                if start_t == 0.0 {
                    compute_hull(from, from_out, to_in, to, end_t, &mut hull);

                    if move_to {
                        builder.move_to(from);
                    }
                    builder.cubic_to(hull[0], hull[3], hull[5]);
                } else {
                    // Split at start since it's non 0.
                    compute_hull(from, from_out, to_in, to, start_t, &mut hull);

                    if move_to {
                        // Move to first point on the right side.
                        builder.move_to(hull[5]);
                    }
                    if end_t == 1.0 {
                        // End is 1, so no further split is necessary just cubicTo
                        // the remaining right side.
                        builder.cubic_to(hull[4], hull[2], to);
                    } else {
                        // End is not 1, so split again and cubic to the left side
                        // of the split and remap endT to the new curve range.
                        compute_hull(
                            hull[5],
                            hull[4],
                            hull[2],
                            to,
                            (end_t - start_t) / (1.0 - start_t),
                            &mut hull,
                        );

                        builder.cubic_to(hull[0], hull[3], hull[5]);
                    }
                }
            }
        }
    }
}
