/*
 * Copyright 2022 Rive
 */

#include "rive/rive_types.hpp"

#ifdef RIVE_BUILD_FOR_APPLE

#include "cg_factory.hpp"
#include "cg_renderer.hpp"
#include "mac_utils.hpp"

#if defined(RIVE_BUILD_FOR_OSX)
#include <ApplicationServices/ApplicationServices.h>
#elif defined(RIVE_BUILD_FOR_IOS)
#include <CoreGraphics/CoreGraphics.h>
#include <ImageIO/ImageIO.h>
#endif

#include "utils/factory_utils.hpp"
#include "rive/math/vec2d.hpp"
#include "rive/core/type_conversions.hpp"
#include "rive/shapes/paint/color.hpp"

using namespace rive;

static CGAffineTransform convert(const Mat2D& m) {
    return CGAffineTransformMake(m[0], m[1], m[2], m[3], m[4], m[5]);
}

static CGPathDrawingMode convert(FillRule rule) {
    return (rule == FillRule::nonZero) ? CGPathDrawingMode::kCGPathFill
                                       : CGPathDrawingMode::kCGPathEOFill;
}

static CGLineJoin convert(StrokeJoin j) {
    const CGLineJoin cg[] = {
        CGLineJoin::kCGLineJoinMiter,
        CGLineJoin::kCGLineJoinRound,
        CGLineJoin::kCGLineJoinBevel,
    };
    return cg[(unsigned)j];
}

static CGLineCap convert(StrokeCap c) {
    const CGLineCap cg[] = {
        CGLineCap::kCGLineCapButt,
        CGLineCap::kCGLineCapRound,
        CGLineCap::kCGLineCapSquare,
    };
    return cg[(unsigned)c];
}

// clang-format off
static CGBlendMode convert(BlendMode mode) {
    CGBlendMode cg = kCGBlendModeNormal;
    switch (mode) {
        case BlendMode::srcOver: cg = kCGBlendModeNormal; break;
        case BlendMode::screen: cg = kCGBlendModeScreen; break;
        case BlendMode::overlay: cg = kCGBlendModeOverlay; break;
        case BlendMode::darken: cg = kCGBlendModeDarken; break;
        case BlendMode::lighten: cg = kCGBlendModeLighten; break;
        case BlendMode::colorDodge: cg = kCGBlendModeColorDodge; break;
        case BlendMode::colorBurn: cg = kCGBlendModeColorBurn; break;
        case BlendMode::hardLight: cg = kCGBlendModeHardLight; break;
        case BlendMode::softLight: cg = kCGBlendModeSoftLight; break;
        case BlendMode::difference: cg = kCGBlendModeDifference; break;
        case BlendMode::exclusion: cg = kCGBlendModeExclusion; break;
        case BlendMode::multiply: cg = kCGBlendModeMultiply; break;
        case BlendMode::hue: cg = kCGBlendModeHue; break;
        case BlendMode::saturation: cg = kCGBlendModeSaturation; break;
        case BlendMode::color: cg = kCGBlendModeColor; break;
        case BlendMode::luminosity: cg = kCGBlendModeLuminosity; break;
    }
    return cg;
}
// clang-format on

static void convertColor(ColorInt c, CGFloat rgba[]) {
    constexpr float kByteToUnit = 1.0f / 255;
    rgba[0] = colorRed(c) * kByteToUnit;
    rgba[1] = colorGreen(c) * kByteToUnit;
    rgba[2] = colorBlue(c) * kByteToUnit;
    rgba[3] = colorAlpha(c) * kByteToUnit;
}

class CGRenderPath : public RenderPath {
private:
    AutoCF<CGMutablePathRef> m_path = CGPathCreateMutable();
    CGPathDrawingMode m_fillMode = CGPathDrawingMode::kCGPathFill;

public:
    CGRenderPath() {}

    CGRenderPath(Span<const Vec2D> pts, Span<const PathVerb> vbs, FillRule rule) {
        m_fillMode = convert(rule);

        auto p = pts.data();
        for (auto v : vbs) {
            switch ((PathVerb)v) {
                case PathVerb::move:
                    CGPathMoveToPoint(m_path, nullptr, p[0].x, p[0].y);
                    p += 1;
                    break;
                case PathVerb::line:
                    CGPathAddLineToPoint(m_path, nullptr, p[0].x, p[0].y);
                    p += 1;
                    break;
                case PathVerb::quad:
                    CGPathAddQuadCurveToPoint(m_path, nullptr, p[0].x, p[0].y, p[1].x, p[1].y);
                    p += 2;
                    break;
                case PathVerb::cubic:
                    CGPathAddCurveToPoint(m_path,
                                          nullptr,
                                          p[0].x,
                                          p[0].y,
                                          p[1].x,
                                          p[1].y,
                                          p[2].x,
                                          p[2].y);
                    p += 3;
                    break;
                case PathVerb::close: CGPathCloseSubpath(m_path); break;
            }
        }
        assert(p == pts.end());
    }

    CGPathRef path() const { return m_path.get(); }
    CGPathDrawingMode drawingMode(bool isStroke) const {
        return isStroke ? CGPathDrawingMode::kCGPathStroke : m_fillMode;
    }

    void reset() override { m_path.reset(CGPathCreateMutable()); }
    void addRenderPath(RenderPath* path, const Mat2D& mx) override {
        auto transform = convert(mx);
        CGPathAddPath(m_path, &transform, ((CGRenderPath*)path)->path());
    }
    void fillRule(FillRule value) override {
        m_fillMode = (value == FillRule::nonZero) ? CGPathDrawingMode::kCGPathFill
                                                  : CGPathDrawingMode::kCGPathEOFill;
    }
    void moveTo(float x, float y) override { CGPathMoveToPoint(m_path, nullptr, x, y); }
    void lineTo(float x, float y) override { CGPathAddLineToPoint(m_path, nullptr, x, y); }
    void cubicTo(float ox, float oy, float ix, float iy, float x, float y) override {
        CGPathAddCurveToPoint(m_path, nullptr, ox, oy, ix, iy, x, y);
    }
    void close() override { CGPathCloseSubpath(m_path); }
};

class CGRenderShader : public RenderShader {
public:
    CGRenderShader() {}

    static constexpr int clampOptions =
        kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation;

    virtual void draw(CGContextRef) {}
};

class CGRenderPaint : public RenderPaint {
private:
    bool m_isStroke = false;
    CGFloat m_rgba[4] = {0, 0, 0, 1};
    float m_width = 1;
    CGLineJoin m_join = kCGLineJoinMiter;
    CGLineCap m_cap = kCGLineCapButt;
    CGBlendMode m_blend = kCGBlendModeNormal;
    rcp<RenderShader> m_shader;

public:
    CGRenderPaint() {}

    bool isStroke() const { return m_isStroke; }
    float opacity() const { return m_rgba[3]; }

    CGRenderShader* shader() const { return static_cast<CGRenderShader*>(m_shader.get()); }

    void apply(CGContextRef ctx) {
        if (m_isStroke) {
            CGContextSetRGBStrokeColor(ctx, m_rgba[0], m_rgba[1], m_rgba[2], m_rgba[3]);
            CGContextSetLineWidth(ctx, m_width);
            CGContextSetLineJoin(ctx, m_join);
            CGContextSetLineCap(ctx, m_cap);
        } else {
            CGContextSetRGBFillColor(ctx, m_rgba[0], m_rgba[1], m_rgba[2], m_rgba[3]);
        }
        CGContextSetBlendMode(ctx, m_blend);
    }

    void style(RenderPaintStyle style) override {
        m_isStroke = (style == RenderPaintStyle::stroke);
    }
    void color(ColorInt value) override { convertColor(value, m_rgba); }
    void thickness(float value) override { m_width = value; }
    void join(StrokeJoin value) override { m_join = convert(value); }
    void cap(StrokeCap value) override { m_cap = convert(value); }
    void blendMode(BlendMode value) override { m_blend = convert(value); }
    void shader(rcp<RenderShader> sh) override { m_shader = std::move(sh); }
    void invalidateStroke() override {}
};

static CGGradientRef convert(const ColorInt colors[], const float stops[], size_t count) {
    AutoCF space = CGColorSpaceCreateDeviceRGB();
    std::vector<CGFloat> floats(count * 5); // colors[4] + stops[1]
    auto c = &floats[0];
    auto s = &floats[count * 4];

    for (size_t i = 0; i < count; ++i) {
        convertColor(colors[i], &c[i * 4]);

        // Rive wants the colors to be premultiplied *after* interpolation
        // Unfortunately, CG doesn't know about this option, it just does
        // a straight interpolation and uses the result (thinking it is
        // in premul form already). This can lead to artifacts in the drawing
        // (e.g. sparkles) so as a hack, we premul our color stops up front.
        // Not exactly correct, but does remove the sparkles.
        // A better fix might be to write a custom Shading proc... but that
        // is likely to be be slower (but need to try/time it to know for sure).
        CGFloat* p = &c[i * 4];
        p[0] *= p[3];
        p[1] *= p[3];
        p[2] *= p[3];
    }
    if (stops) {
        for (size_t i = 0; i < count; ++i) {
            s[i] = stops[i];
        }
    }
    return CGGradientCreateWithColorComponents(space, c, s, count);
}

class CGRadialGradientRenderShader : public CGRenderShader {
    AutoCF<CGGradientRef> m_grad;
    CGPoint m_center;
    CGFloat m_radius;

public:
    CGRadialGradientRenderShader(float cx,
                                 float cy,
                                 float radius,
                                 const ColorInt colors[],
                                 const float stops[],
                                 size_t count) :
        m_grad(convert(colors, stops, count)) {
        m_center = CGPointMake(cx, cy);
        m_radius = radius;
    }

    void draw(CGContextRef ctx) override {
        CGContextDrawRadialGradient(ctx, m_grad, m_center, 0, m_center, m_radius, clampOptions);
    }
};

class CGLinearGradientRenderShader : public CGRenderShader {
    AutoCF<CGGradientRef> m_grad;
    CGPoint m_start, m_end;

public:
    CGLinearGradientRenderShader(float sx,
                                 float sy,
                                 float ex,
                                 float ey,
                                 const ColorInt colors[], // [count]
                                 const float stops[],     // [count]
                                 size_t count) :
        m_grad(convert(colors, stops, count)) {
        m_start = CGPointMake(sx, sy);
        m_end = CGPointMake(ex, ey);
    }

    void draw(CGContextRef ctx) override {
        CGContextDrawLinearGradient(ctx, m_grad, m_start, m_end, clampOptions);
    }
};

class CGRenderImage : public RenderImage {
public:
    AutoCF<CGImageRef> m_image;

    CGRenderImage(const Span<const uint8_t> span) : m_image(DecodeToCGImage(span)) {
        if (m_image) {
            m_Width = rive::castTo<uint32_t>(CGImageGetWidth(m_image.get()));
            m_Height = rive::castTo<uint32_t>(CGImageGetHeight(m_image.get()));
        }
    }

    Mat2D localM2D() const { return Mat2D(1, 0, 0, -1, 0, (float)m_Height); }

    void applyLocalMatrix(CGContextRef ctx) const {
        CGContextConcatCTM(ctx, CGAffineTransformMake(1, 0, 0, -1, 0, (float)m_Height));
    }

    static const CGRenderImage* Cast(const RenderImage* image) {
        return reinterpret_cast<const CGRenderImage*>(image);
    }
};

//////////////////////////////////////////////////////////////////////////

CGRenderer::CGRenderer(CGContextRef ctx, int width, int height) : m_ctx(ctx) {
    CGContextSaveGState(ctx);

    Mat2D m(1, 0, 0, -1, 0, height);
    CGContextConcatCTM(ctx, convert(m));

    CGContextSetInterpolationQuality(ctx, kCGInterpolationMedium);
}

CGRenderer::~CGRenderer() { CGContextRestoreGState(m_ctx); }

void CGRenderer::save() { CGContextSaveGState(m_ctx); }

void CGRenderer::restore() { CGContextRestoreGState(m_ctx); }

void CGRenderer::transform(const Mat2D& m) { CGContextConcatCTM(m_ctx, convert(m)); }

void CGRenderer::drawPath(RenderPath* path, RenderPaint* paint) {
    auto cgpaint = reinterpret_cast<CGRenderPaint*>(paint);
    auto cgpath = reinterpret_cast<CGRenderPath*>(path);

    cgpaint->apply(m_ctx);

    CGContextBeginPath(m_ctx);
    CGContextAddPath(m_ctx, cgpath->path());
    if (auto sh = cgpaint->shader()) {
        if (cgpaint->isStroke()) {
            // so we can clip against the "stroke" of the path
            CGContextReplacePathWithStrokedPath(m_ctx);
        }
        CGContextSaveGState(m_ctx);
        CGContextClip(m_ctx);

        // so the gradient modulates with the color's alpha
        CGContextSetAlpha(m_ctx, cgpaint->opacity());

        sh->draw(m_ctx);
        CGContextRestoreGState(m_ctx);
    } else {
        CGContextDrawPath(m_ctx, cgpath->drawingMode(cgpaint->isStroke()));
    }

    assert(CGContextIsPathEmpty(m_ctx));
}

void CGRenderer::clipPath(RenderPath* path) {
    auto cgpath = reinterpret_cast<CGRenderPath*>(path);

    CGContextBeginPath(m_ctx);
    CGContextAddPath(m_ctx, cgpath->path());
    CGContextClip(m_ctx);
}

void CGRenderer::drawImage(const RenderImage* image, BlendMode blendMode, float opacity) {
    auto bounds = CGRectMake(0, 0, image->width(), image->height());

    CGContextSaveGState(m_ctx);
    CGContextSetAlpha(m_ctx, opacity);
    CGContextSetBlendMode(m_ctx, convert(blendMode));
    auto cgimg = CGRenderImage::Cast(image);
    cgimg->applyLocalMatrix(m_ctx);
    CGContextDrawImage(m_ctx, bounds, cgimg->m_image);
    CGContextRestoreGState(m_ctx);
}

static Mat2D basis_matrix(Vec2D p0, Vec2D p1, Vec2D p2) {
    auto e0 = p1 - p0;
    auto e1 = p2 - p0;
    return Mat2D(e0.x, e0.y, e1.x, e1.y, p0.x, p0.y);
}

void CGRenderer::drawImageMesh(const RenderImage* image,
                               rcp<RenderBuffer> vertices,
                               rcp<RenderBuffer> uvCoords,
                               rcp<RenderBuffer> indices,
                               BlendMode blendMode,
                               float opacity) {
    auto cgimage = CGRenderImage::Cast(image);
    auto const localMatrix = cgimage->localM2D();

    const float sx = image->width();
    const float sy = image->height();
    auto const bounds = CGRectMake(0, 0, sx, sy);

    auto scale = [sx, sy](Vec2D v) { return Vec2D{v.x * sx, v.y * sy}; };

    auto triangles = indices->count() / 3;
    auto ndx = DataRenderBuffer::Cast(indices.get())->u16s();
    auto pts = DataRenderBuffer::Cast(vertices.get())->vecs();
    auto uvs = DataRenderBuffer::Cast(uvCoords.get())->vecs();

    // We use the path to set the clip for each triangle. Since calling
    // CGContextClip() resets the path, we only need to this once at
    // the beginning.
    CGContextBeginPath(m_ctx);

    CGContextSaveGState(m_ctx);
    CGContextSetAlpha(m_ctx, opacity);
    CGContextSetBlendMode(m_ctx, convert(blendMode));
    CGContextSetShouldAntialias(m_ctx, false);

    for (size_t i = 0; i < triangles; ++i) {
        const auto index0 = *ndx++;
        const auto index1 = *ndx++;
        const auto index2 = *ndx++;

        CGContextSaveGState(m_ctx);

        const auto p0 = pts[index0];
        const auto p1 = pts[index1];
        const auto p2 = pts[index2];
        CGContextMoveToPoint(m_ctx, p0.x, p0.y);
        CGContextAddLineToPoint(m_ctx, p1.x, p1.y);
        CGContextAddLineToPoint(m_ctx, p2.x, p2.y);
        CGContextClip(m_ctx);

        const auto v0 = scale(uvs[index0]);
        const auto v1 = scale(uvs[index1]);
        const auto v2 = scale(uvs[index2]);
        auto mx =
            basis_matrix(p0, p1, p2) * basis_matrix(v0, v1, v2).invertOrIdentity() * localMatrix;
        CGContextConcatCTM(m_ctx, convert(mx));
        CGContextDrawImage(m_ctx, bounds, cgimage->m_image);

        CGContextRestoreGState(m_ctx);
    }

    CGContextRestoreGState(m_ctx); // restore opacity, antialias, etc.
}

// Factory

rcp<RenderBuffer> CGFactory::makeBufferU16(Span<const uint16_t> data) {
    return DataRenderBuffer::Make(data);
}

rcp<RenderBuffer> CGFactory::makeBufferU32(Span<const uint32_t> data) {
    return DataRenderBuffer::Make(data);
}

rcp<RenderBuffer> CGFactory::makeBufferF32(Span<const float> data) {
    return DataRenderBuffer::Make(data);
}

rcp<RenderShader> CGFactory::makeLinearGradient(float sx,
                                                float sy,
                                                float ex,
                                                float ey,
                                                const ColorInt colors[], // [count]
                                                const float stops[],     // [count]
                                                size_t count) {
    return rcp<RenderShader>(
        new CGLinearGradientRenderShader(sx, sy, ex, ey, colors, stops, count));
}

rcp<RenderShader> CGFactory::makeRadialGradient(float cx,
                                                float cy,
                                                float radius,
                                                const ColorInt colors[], // [count]
                                                const float stops[],     // [count]
                                                size_t count) {
    return rcp<RenderShader>(
        new CGRadialGradientRenderShader(cx, cy, radius, colors, stops, count));
}

std::unique_ptr<RenderPath> CGFactory::makeRenderPath(RawPath& rawPath, FillRule fillRule) {
    return std::make_unique<CGRenderPath>(rawPath.points(), rawPath.verbs(), fillRule);
}

std::unique_ptr<RenderPath> CGFactory::makeEmptyRenderPath() {
    return std::make_unique<CGRenderPath>();
}

std::unique_ptr<RenderPaint> CGFactory::makeRenderPaint() {
    return std::make_unique<CGRenderPaint>();
}

std::unique_ptr<RenderImage> CGFactory::decodeImage(Span<const uint8_t> encoded) {
    return std::make_unique<CGRenderImage>(encoded);
}

#endif // APPLE
