/*
 * 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); }
};

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(Span<const Vec2D> points, Span<const PathVerb> verbs, FillRule fillRule) {
    return std::make_unique<CGRenderPath>(points, 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
