/*
 * Copyright 2022 Rive
 */

#include "rive/rive_types.hpp"
#include "utils/rive_utf.hpp"

#if defined(RIVE_BUILD_FOR_APPLE) && defined(WITH_RIVE_TEXT)
#include "renderfont_coretext.hpp"
#include "mac_utils.hpp"

#include "rive/factory.hpp"
#include "rive/render_text.hpp"
#include "rive/core/type_conversions.hpp"

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

constexpr int kStdScale = 2048;
constexpr float gInvScale = 1.0f / kStdScale;

static std::vector<rive::RenderFont::Axis> compute_axes(CTFontRef font)
{
    std::vector<rive::RenderFont::Axis> axes;

    AutoCF array = CTFontCopyVariationAxes(font);
    if (auto count = array.get() ? CFArrayGetCount(array.get()) : 0)
    {
        axes.reserve(count);

        for (auto i = 0; i < count; ++i)
        {
            auto axis = (CFDictionaryRef)CFArrayGetValueAtIndex(array, i);

            auto tag = find_u32(axis, kCTFontVariationAxisIdentifierKey);
            auto min = find_float(axis, kCTFontVariationAxisMinimumValueKey);
            auto def = find_float(axis, kCTFontVariationAxisDefaultValueKey);
            auto max = find_float(axis, kCTFontVariationAxisMaximumValueKey);
            //     printf("%08X %g %g %g\n", tag, min, def, max);

            axes.push_back({tag, min, def, max});
        }
    }
    return axes;
}

static std::vector<rive::RenderFont::Coord> compute_coords(CTFontRef font)
{
    std::vector<rive::RenderFont::Coord> coords(0);
    AutoCF dict = CTFontCopyVariation(font);
    if (dict)
    {
        int count = CFDictionaryGetCount(dict);
        if (count > 0)
        {
            coords.resize(count);

            AutoSTArray<100, const void*> ptrs(count * 2);
            const void** keys = &ptrs[0];
            const void** values = &ptrs[count];
            CFDictionaryGetKeysAndValues(dict, keys, values);
            for (int i = 0; i < count; ++i)
            {
                uint32_t tag = number_as_u32((CFNumberRef)keys[i]);
                float value = number_as_float((CFNumberRef)values[i]);
                //                printf("[%d] %08X %s %g\n", i, tag, tag2str(tag).c_str(), value);
                coords[i] = {tag, value};
            }
        }
    }
    return coords;
}

static rive::RenderFont::LineMetrics make_lmx(CTFontRef font)
{
    return {
        (float)-CTFontGetAscent(font) * gInvScale,
        (float)CTFontGetDescent(font) * gInvScale,
    };
}

CoreTextRenderFont::CoreTextRenderFont(CTFontRef font, std::vector<rive::RenderFont::Axis> axes) :
    rive::RenderFont(make_lmx(font)),
    m_font(font), // we take ownership of font
    m_axes(std::move(axes)),
    m_coords(compute_coords(font))
{}

CoreTextRenderFont::~CoreTextRenderFont() { CFRelease(m_font); }

rive::rcp<rive::RenderFont> CoreTextRenderFont::makeAtCoords(rive::Span<const Coord> coords) const
{
    AutoCF vars = CFDictionaryCreateMutable(kCFAllocatorDefault,
                                            coords.size(),
                                            &kCFTypeDictionaryKeyCallBacks,
                                            &kCFTypeDictionaryValueCallBacks);
    for (const auto& c : coords)
    {
        AutoCF tagNum = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &c.axis);
        AutoCF valueNum = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloat32Type, &c.value);
        CFDictionaryAddValue(vars.get(), tagNum.get(), valueNum.get());
    }

    AutoCF attrs = CFDictionaryCreateMutable(kCFAllocatorDefault,
                                             1,
                                             &kCFTypeDictionaryKeyCallBacks,
                                             &kCFTypeDictionaryValueCallBacks);
    CFDictionarySetValue(attrs.get(), kCTFontVariationAttribute, vars.get());

    AutoCF desc = (CTFontDescriptorRef)CTFontDescriptorCreateWithAttributes(attrs.get());

    auto font = CTFontCreateCopyWithAttributes(m_font, 0, nullptr, desc.get());

    return rive::rcp<rive::RenderFont>(new CoreTextRenderFont(font, compute_axes(font)));
}

static CTFontRef font_from_run(CTRunRef run)
{
    auto attr = CTRunGetAttributes(run);
    assert(attr);
    CTFontRef ct = (CTFontRef)CFDictionaryGetValue(attr, kCTFontAttributeName);
    assert(ct);
    return ct;
}

static rive::rcp<rive::RenderFont> convert_to_renderfont(CTFontRef ct,
                                                         rive::rcp<rive::RenderFont> rf)
{
    auto ctrf = static_cast<CoreTextRenderFont*>(rf.get());
    if (ctrf->m_font == ct)
    {
        return rf;
    }
    CFRetain(ct);
    return rive::rcp<rive::RenderFont>(new CoreTextRenderFont(ct, compute_axes(ct)));
}

static void apply_element(void* ctx, const CGPathElement* element)
{
    auto path = (rive::RawPath*)ctx;
    const CGPoint* points = element->points;

    switch (element->type)
    {
        case kCGPathElementMoveToPoint:
            path->moveTo(points[0].x, points[0].y);
            break;

        case kCGPathElementAddLineToPoint:
            path->lineTo(points[0].x, points[0].y);
            break;

        case kCGPathElementAddQuadCurveToPoint:
            path->quadTo(points[0].x, points[0].y, points[1].x, points[1].y);
            break;

        case kCGPathElementAddCurveToPoint:
            path->cubicTo(points[0].x,
                          points[0].y,
                          points[1].x,
                          points[1].y,
                          points[2].x,
                          points[2].y);
            break;

        case kCGPathElementCloseSubpath:
            path->close();
            break;

        default:
            assert(false);
            break;
    }
}

rive::RawPath CoreTextRenderFont::getPath(rive::GlyphID glyph) const
{
    rive::RawPath rpath;

    AutoCF cgPath = CTFontCreatePathForGlyph(m_font, glyph, nullptr);
    if (!cgPath)
    {
        return rpath;
    }

    CGPathApply(cgPath.get(), &rpath, apply_element);
    rpath.transformInPlace(rive::Mat2D::fromScale(gInvScale, -gInvScale));
    return rpath;
}

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

struct AutoUTF16
{
    std::vector<uint16_t> array;

    AutoUTF16(const rive::Unichar uni[], int count)
    {
        array.reserve(count);
        for (int i = 0; i < count; ++i)
        {
            uint16_t tmp[2];
            int n = rive::UTF::ToUTF16(uni[i], tmp);

            for (int i = 0; i < n; ++i)
            {
                array.push_back(tmp[i]);
            }
        }
    }
};

static rive::RenderGlyphRun add_run(CTRunRef run, uint32_t textStart, float textSize, float& startX)
{
    if (auto count = CTRunGetGlyphCount(run))
    {
        const float scale = textSize * gInvScale;

        rive::RenderGlyphRun gr(count);
        gr.size = textSize;

        CTRunGetGlyphs(run, {0, count}, gr.glyphs.data());

        AutoSTArray<1024, CFIndex> indices(count);
        AutoSTArray<1024, CGSize> advances(count);

        CTRunGetAdvances(run, {0, count}, advances.data());
        CTRunGetStringIndices(run, {0, count}, indices.data());

        for (CFIndex i = 0; i < count; ++i)
        {
            gr.xpos[i] = startX;
            gr.textIndices[i] = textStart + indices[i]; // utf16 offsets, will fix-up later
            startX += advances[i].width * scale;
        }
        gr.xpos[count] = startX;
        return gr;
    }
    return rive::RenderGlyphRun();
}

rive::SimpleArray<rive::RenderGlyphRun>
CoreTextRenderFont::onShapeText(rive::Span<const rive::Unichar> text,
                                rive::Span<const rive::RenderTextRun> truns) const
{
    rive::SimpleArrayBuilder<rive::RenderGlyphRun> gruns(truns.size());

    uint32_t textIndex = 0;
    float startX = 0;
    for (const auto& tr : truns)
    {
        CTFontRef font = ((CoreTextRenderFont*)tr.font.get())->m_font;

        AutoUTF16 utf16(&text[textIndex], tr.unicharCount);
        const bool hasSurrogates = utf16.array.size() != tr.unicharCount;
        assert(!hasSurrogates);

        AutoCF string = CFStringCreateWithCharactersNoCopy(nullptr,
                                                           utf16.array.data(),
                                                           utf16.array.size(),
                                                           kCFAllocatorNull);

        AutoCF attr = CFDictionaryCreateMutable(kCFAllocatorDefault,
                                                0,
                                                &kCFTypeDictionaryKeyCallBacks,
                                                &kCFTypeDictionaryValueCallBacks);
        CFDictionaryAddValue(attr.get(), kCTFontAttributeName, font);

        AutoCF attrString = CFAttributedStringCreate(kCFAllocatorDefault, string.get(), attr.get());

        AutoCF typesetter = CTTypesetterCreateWithAttributedString(attrString.get());

        AutoCF line = CTTypesetterCreateLine(typesetter.get(), {0, tr.unicharCount});

        CFArrayRef run_array = CTLineGetGlyphRuns(line.get());
        CFIndex runCount = CFArrayGetCount(run_array);
        for (CFIndex i = 0; i < runCount; ++i)
        {
            CTRunRef runref = (CTRunRef)CFArrayGetValueAtIndex(run_array, i);
            rive::RenderGlyphRun grun = add_run(runref, textIndex, tr.size, startX);
            if (grun.glyphs.size() > 0)
            {
                auto ct = font_from_run(runref);
                grun.font = convert_to_renderfont(ct, tr.font);
                grun.size = tr.size;
                gruns.add(std::move(grun));
            }
        }
        textIndex += tr.unicharCount;
    }

    return std::move(gruns);
}

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

rive::rcp<rive::RenderFont> CoreTextRenderFont::FromCT(CTFontRef ctfont)
{
    if (!ctfont)
    {
        return nullptr;
    }

    // We always want the ctfont at our magic size
    if (CTFontGetSize(ctfont) != kStdScale)
    {
        ctfont = CTFontCreateCopyWithAttributes(ctfont, kStdScale, nullptr, nullptr);
    }
    else
    {
        CFRetain(ctfont);
    }

    // Apple may have secretly set the opsz axis based on the size. We want to undo this
    // since our stdsize isn't really the size we'll show it at.
    auto axes = compute_axes(ctfont);
    if (axes.size() > 0)
    {
        constexpr uint32_t kOPSZ = make_tag('o', 'p', 's', 'z');
        for (const auto& ax : axes)
        {
            if (ax.tag == kOPSZ)
            {
                auto xform = CGAffineTransformMakeScale(kStdScale / ax.def, kStdScale / ax.def);
                // Recreate the font at this size, but with a balancing transform,
                // so we get the 'default' shapes w.r.t. the opsz axis
                auto newfont = CTFontCreateCopyWithAttributes(ctfont, ax.def, &xform, nullptr);
                CFRelease(ctfont);
                ctfont = newfont;
                break;
            }
        }
    }

    return rive::rcp<rive::RenderFont>(new CoreTextRenderFont(ctfont, std::move(axes)));
}

rive::rcp<rive::RenderFont> CoreTextRenderFont::Decode(rive::Span<const uint8_t> span)
{
    AutoCF data = CFDataCreate(nullptr, span.data(), span.size()); // makes a copy
    if (!data)
    {
        assert(false);
        return nullptr;
    }

    AutoCF desc = CTFontManagerCreateFontDescriptorFromData(data.get());
    if (!desc)
    {
        assert(false);
        return nullptr;
    }

    CTFontOptions options = kCTFontOptionsPreventAutoActivation;

    AutoCF ctfont =
        CTFontCreateWithFontDescriptorAndOptions(desc.get(), kStdScale, nullptr, options);
    if (!ctfont)
    {
        assert(false);
        return nullptr;
    }
    return FromCT(ctfont.get());
}

#endif
