// Copyright 2022 The vello authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Also licensed under MIT license, at your choice.

//! Support for glyph rendering.

pub use moscato::pinot;

use crate::scene::{SceneBuilder, SceneFragment};
use peniko::kurbo::{Affine, Rect};
use peniko::{Brush, Color, Fill, Mix};

use moscato::{Context, Scaler};
use pinot::{types::Tag, FontRef};

use smallvec::SmallVec;

/// General context for creating scene fragments for glyph outlines.
pub struct GlyphContext {
    ctx: Context,
}

impl GlyphContext {
    /// Creates a new context.
    pub fn new() -> Self {
        Self {
            ctx: Context::new(),
        }
    }

    /// Creates a new provider for generating scene fragments for glyphs from
    /// the specified font and settings.
    pub fn new_provider<'a, V>(
        &'a mut self,
        font: &FontRef<'a>,
        font_id: Option<u64>,
        ppem: f32,
        hint: bool,
        variations: V,
    ) -> GlyphProvider<'a>
    where
        V: IntoIterator,
        V::Item: Into<(Tag, f32)>,
    {
        let scaler = if let Some(font_id) = font_id {
            self.ctx
                .new_scaler_with_id(font, font_id)
                .size(ppem)
                .hint(hint)
                .variations(variations)
                .build()
        } else {
            self.ctx
                .new_scaler(font)
                .size(ppem)
                .hint(hint)
                .variations(variations)
                .build()
        };
        GlyphProvider { scaler }
    }
}

/// Generator for scene fragments containing glyph outlines for a specific
/// font.
pub struct GlyphProvider<'a> {
    scaler: Scaler<'a>,
}

impl<'a> GlyphProvider<'a> {
    /// Returns a scene fragment containing the commands to render the
    /// specified glyph.
    pub fn get(&mut self, gid: u16, brush: Option<&Brush>) -> Option<SceneFragment> {
        let glyph = self.scaler.glyph(gid)?;
        let path = glyph.path(0)?;
        let mut fragment = SceneFragment::default();
        let mut builder = SceneBuilder::for_fragment(&mut fragment);
        builder.fill(
            Fill::NonZero,
            Affine::IDENTITY,
            brush.unwrap_or(&Brush::Solid(Color::rgb8(255, 255, 255))),
            None,
            &convert_path(path.elements()),
        );
        builder.finish();
        Some(fragment)
    }

    /// Returns a scene fragment containing the commands and resources to
    /// render the specified color glyph.
    pub fn get_color(&mut self, palette_index: u16, gid: u16) -> Option<SceneFragment> {
        use moscato::Command;
        let glyph = self.scaler.color_glyph(palette_index, gid)?;
        let mut fragment = SceneFragment::default();
        let mut builder = SceneBuilder::for_fragment(&mut fragment);
        let mut xform_stack: SmallVec<[Affine; 8]> = SmallVec::new();
        for command in glyph.commands() {
            match command {
                Command::PushTransform(xform) => {
                    let xform = if let Some(parent) = xform_stack.last() {
                        convert_transform(xform) * *parent
                    } else {
                        convert_transform(xform)
                    };
                    xform_stack.push(xform);
                }
                Command::PopTransform => {
                    xform_stack.pop();
                }
                Command::PushClip(path_index) => {
                    let path = glyph.path(*path_index)?;
                    if let Some(xform) = xform_stack.last() {
                        builder.push_layer(
                            Mix::Clip,
                            1.0,
                            Affine::IDENTITY,
                            &convert_transformed_path(path.elements(), xform),
                        );
                    } else {
                        builder.push_layer(
                            Mix::Clip,
                            1.0,
                            Affine::IDENTITY,
                            &convert_path(path.elements()),
                        );
                    }
                }
                Command::PopClip => builder.pop_layer(),
                Command::PushLayer(bounds) => {
                    let mut min = convert_point(bounds.min);
                    let mut max = convert_point(bounds.max);
                    if let Some(xform) = xform_stack.last() {
                        min = *xform * min;
                        max = *xform * max;
                    }
                    let rect = Rect::from_points(min, max);
                    builder.push_layer(Mix::Normal, 1.0, Affine::IDENTITY, &rect);
                }
                Command::PopLayer => builder.pop_layer(),
                Command::BeginBlend(bounds, mode) => {
                    let mut min = convert_point(bounds.min);
                    let mut max = convert_point(bounds.max);
                    if let Some(xform) = xform_stack.last() {
                        min = *xform * min;
                        max = *xform * max;
                    }
                    let rect = Rect::from_points(min, max);
                    builder.push_layer(convert_blend(*mode), 1.0, Affine::IDENTITY, &rect);
                }
                Command::EndBlend => builder.pop_layer(),
                Command::SimpleFill(path_index, brush, brush_xform) => {
                    let path = glyph.path(*path_index)?;
                    let brush = convert_brush(brush);
                    let brush_xform = brush_xform.map(|xform| convert_transform(&xform));
                    if let Some(xform) = xform_stack.last() {
                        builder.fill(
                            Fill::NonZero,
                            Affine::IDENTITY,
                            &brush,
                            brush_xform.map(|x| x * *xform),
                            &convert_transformed_path(path.elements(), xform),
                        );
                    } else {
                        builder.fill(
                            Fill::NonZero,
                            Affine::IDENTITY,
                            &brush,
                            brush_xform,
                            &convert_path(path.elements()),
                        );
                    }
                }
                Command::Fill(_brush, _brush_xform) => {
                    // TODO: this needs to compute a bounding box for
                    // the parent clips
                }
            }
        }
        builder.finish();
        Some(fragment)
    }
}

fn convert_path(path: impl Iterator<Item = moscato::Element> + Clone) -> peniko::kurbo::BezPath {
    let mut result = peniko::kurbo::BezPath::new();
    for el in path {
        result.push(convert_path_el(&el));
    }
    result
}

fn convert_transformed_path(
    path: impl Iterator<Item = moscato::Element> + Clone,
    xform: &Affine,
) -> peniko::kurbo::BezPath {
    let mut result = peniko::kurbo::BezPath::new();
    for el in path {
        result.push(*xform * convert_path_el(&el));
    }
    result
}

fn convert_blend(mode: moscato::CompositeMode) -> peniko::BlendMode {
    use moscato::CompositeMode;
    use peniko::{BlendMode, Compose};
    let mut mix = Mix::Normal;
    let mut compose = Compose::SrcOver;
    match mode {
        CompositeMode::Clear => compose = Compose::Clear,
        CompositeMode::Src => compose = Compose::Copy,
        CompositeMode::Dest => compose = Compose::Dest,
        CompositeMode::SrcOver => {}
        CompositeMode::DestOver => compose = Compose::DestOver,
        CompositeMode::SrcIn => compose = Compose::SrcIn,
        CompositeMode::DestIn => compose = Compose::DestIn,
        CompositeMode::SrcOut => compose = Compose::SrcOut,
        CompositeMode::DestOut => compose = Compose::DestOut,
        CompositeMode::SrcAtop => compose = Compose::SrcAtop,
        CompositeMode::DestAtop => compose = Compose::DestAtop,
        CompositeMode::Xor => compose = Compose::Xor,
        CompositeMode::Plus => compose = Compose::Plus,
        CompositeMode::Screen => mix = Mix::Screen,
        CompositeMode::Overlay => mix = Mix::Overlay,
        CompositeMode::Darken => mix = Mix::Darken,
        CompositeMode::Lighten => mix = Mix::Lighten,
        CompositeMode::ColorDodge => mix = Mix::ColorDodge,
        CompositeMode::ColorBurn => mix = Mix::ColorBurn,
        CompositeMode::HardLight => mix = Mix::HardLight,
        CompositeMode::SoftLight => mix = Mix::SoftLight,
        CompositeMode::Difference => mix = Mix::Difference,
        CompositeMode::Exclusion => mix = Mix::Exclusion,
        CompositeMode::Multiply => mix = Mix::Multiply,
        CompositeMode::HslHue => mix = Mix::Hue,
        CompositeMode::HslSaturation => mix = Mix::Saturation,
        CompositeMode::HslColor => mix = Mix::Color,
        CompositeMode::HslLuminosity => mix = Mix::Luminosity,
    }
    BlendMode { mix, compose }
}

fn convert_transform(xform: &moscato::Transform) -> peniko::kurbo::Affine {
    peniko::kurbo::Affine::new([
        xform.xx as f64,
        xform.yx as f64,
        xform.xy as f64,
        xform.yy as f64,
        xform.dx as f64,
        xform.dy as f64,
    ])
}

fn convert_point(point: moscato::Point) -> peniko::kurbo::Point {
    peniko::kurbo::Point::new(point.x as f64, point.y as f64)
}

fn convert_brush(brush: &moscato::Brush) -> peniko::Brush {
    use peniko::Gradient;
    match brush {
        moscato::Brush::Solid(color) => Brush::Solid(Color {
            r: color.r,
            g: color.g,
            b: color.b,
            a: color.a,
        }),
        moscato::Brush::LinearGradient(grad) => Brush::Gradient(
            Gradient::new_linear(convert_point(grad.start), convert_point(grad.end))
                .with_stops(convert_stops(&grad.stops).as_slice())
                .with_extend(convert_extend(grad.extend)),
        ),

        moscato::Brush::RadialGradient(grad) => Brush::Gradient(
            Gradient::new_two_point_radial(
                convert_point(grad.center0),
                grad.radius0,
                convert_point(grad.center1),
                grad.radius1,
            )
            .with_stops(convert_stops(&grad.stops).as_slice())
            .with_extend(convert_extend(grad.extend)),
        ),
    }
}

fn convert_stops(stops: &[moscato::ColorStop]) -> peniko::ColorStops {
    stops
        .iter()
        .map(|stop| {
            (
                stop.offset,
                Color {
                    r: stop.color.r,
                    g: stop.color.g,
                    b: stop.color.b,
                    a: stop.color.a,
                },
            )
                .into()
        })
        .collect()
}

fn convert_extend(extend: moscato::ExtendMode) -> peniko::Extend {
    use peniko::Extend::*;
    match extend {
        moscato::ExtendMode::Pad => Pad,
        moscato::ExtendMode::Repeat => Repeat,
        moscato::ExtendMode::Reflect => Reflect,
    }
}

fn convert_path_el(el: &moscato::Element) -> peniko::kurbo::PathEl {
    use peniko::kurbo::PathEl::*;
    match el {
        moscato::Element::MoveTo(p0) => MoveTo(convert_point(*p0)),
        moscato::Element::LineTo(p0) => LineTo(convert_point(*p0)),
        moscato::Element::QuadTo(p0, p1) => QuadTo(convert_point(*p0), convert_point(*p1)),
        moscato::Element::CurveTo(p0, p1, p2) => {
            CurveTo(convert_point(*p0), convert_point(*p1), convert_point(*p2))
        }
        moscato::Element::Close => ClosePath,
    }
}
