#include <cassert>
#include "font.h"
#include "include/core/SkFont.h"

uint16_t RiveFont::charToGlyph(SkUnichar u) const {
    for (size_t i = 0; i < fCMap.size(); ++i) {
        if (fCMap[i].fChar == u) {
            return fCMap[i].fGlyph;
        }
    }
    return 0;
}

float RiveFont::advance(uint16_t glyph) const {
    assert(glyph < fGlyphs.size());
    return fGlyphs[glyph].fAdvance;
}

const SkPath* RiveFont::path(uint16_t glyph) const {
    assert(glyph < fGlyphs.size());
    const SkPath& p = fGlyphs[glyph].fPath;
    return p.isEmpty() ? nullptr : &p;
}

#define kSignature  0x23581321
#define kVersion    1

constexpr uint32_t Tag(unsigned a, unsigned b, unsigned c, unsigned d) {
    assert((a & 0xFF) == a);
    assert((b & 0xFF) == b);
    assert((c & 0xFF) == c);
    assert((d & 0xFF) == d);
    return (a << 24) | (b << 16) | (c << 8) | d;
}

static inline void tag_to_str(uint32_t tag, char str[5]) {
    str[0] = (tag >> 24) & 0xFF;
    str[1] = (tag >> 16) & 0xFF;
    str[2] = (tag >>  8) & 0xFF;
    str[3] = (tag >>  0) & 0xFF;
    str[4] = 0;
}

constexpr uint32_t kOffsets_TableTag  = Tag('p', 'o', 'f', 'f');
constexpr uint32_t kPaths_TableTag    = Tag('p', 'a', 't', 'h');
constexpr uint32_t kCMap_TableTag     = Tag('c', 'm', 'a', 'p');
constexpr uint32_t kInfo_TableTag     = Tag('i', 'n', 'f', 'o');
constexpr uint32_t kAdvances_TableTag = Tag('h', 'a', 'd', 'v');

struct TableDir {
    uint32_t tag;
    uint32_t offset;
    uint32_t length;
};

struct FontHead {
    uint32_t signature;
    uint32_t version;
    uint32_t tableCount;
    // TableDir[dirCount]

    const TableDir* dir() const {
        return (const TableDir*)(this + 1);
    }

    const void* findTable(uint32_t tag) const {
        auto dir = this->dir();
        for (unsigned i = 0; i < this->tableCount; ++i) {
            if (dir[i].tag == tag) {
                return (char*)this + dir[i].offset;
            }
        }
        return nullptr;
    }
};

struct InfoTable {
    uint16_t    glyphCount;
    uint16_t    upem;
};

struct GlyphOffsetTable {
    //  uint32_t offsets[glyphCount+1]; // relative to the glyphdata table
};

struct GlyphRec {
    // uint16_t verbCount;
    // uint16_t pointCount; // if verbCount > 0
    // uint8_t  verbs;       // Move, Line, Quad, Cubic, Close
    // pad16[]
    // uint16_t x,y x,y x,y
};

void RiveFont::load(sk_sp<SkTypeface> tf, const char str[], size_t len) {
    this->clear();

    SkFont font(std::move(tf), 1.0f);

    uint16_t glyphIDs[len];
    int glyphCount = font.textToGlyphs(str, len, SkTextEncoding::kUTF8, glyphIDs, len);
    assert(glyphCount == (int)len);
    
    struct Rec {
        uint16_t charCode;
        uint16_t srcGlyph;
        uint16_t dstGlyph;
    };
    std::vector<Rec> rec;
    uint16_t newDstGlyphID = 1;    // leave room for glyphID==0 for missing glyph
    // build vector of unique chars
    for (size_t i = 0; i < len; ++i) {
        uint16_t code = str[i];
        auto iter = std::find_if(rec.begin(), rec.end(), [code](const auto& r) {
            return r.charCode == code;
        });
        if (iter == rec.end()) {
            // gonna add code -- now see if its glyph is unique
            uint16_t srcGlyph = glyphIDs[i];
            auto it2 = std::find_if(rec.begin(), rec.end(), [srcGlyph](const auto& r) {
                return r.srcGlyph == srcGlyph;
            });
            uint16_t dstGlyph;
            if (it2 == rec.end()) {
                // srcGlyph is unique (or zero)
                dstGlyph = srcGlyph ? newDstGlyphID++ : 0;
            } else {
                dstGlyph = it2->dstGlyph;   // reuse prev dstGlyph
            }
            rec.push_back({code, srcGlyph, dstGlyph});
        }
    }

    std::sort(rec.begin(), rec.end(), [](const Rec& a, const Rec& b) {
        return a.charCode < b.charCode;
    });
    for (const auto& r : rec) {
        printf("'%c' [%d] %d -> %d\n", r.charCode, r.charCode, r.srcGlyph, r.dstGlyph);
        fCMap.push_back({r.charCode, r.dstGlyph});
    }

    std::sort(rec.begin(), rec.end(), [](const Rec& a, const Rec& b) {
        return a.dstGlyph < b.dstGlyph;
    });

    font.setLinearMetrics(true);
    auto append_glyph = [&](uint16_t srcGlyph) {
        float width;
        font.getWidths(&srcGlyph, 1, &width);
        SkPath path;
        font.getPath(srcGlyph, &path);   // returns false if glyph is bitmap

        fGlyphs.push_back({std::move(path), width});
    };

    append_glyph(0);    // missing glyph
    for (int i = 1; i < newDstGlyphID; ++i) {   // walk through our glyphs
        auto iter = std::find_if(rec.begin(), rec.end(), [i](const auto& r) {
            return r.dstGlyph == i;
        });
        assert(iter != rec.end());
        append_glyph(iter->srcGlyph);
    }
}

struct ByteBuilder {
    std::vector<uint8_t> bytes;
    
    uint32_t length() const { return bytes.size(); }
    
    uint8_t  add8(size_t x) {
        assert((x & 0xFF) == x);
        uint8_t b = (uint8_t)x;
        bytes.push_back(b);
        return b;
    }
    int16_t addS16(ssize_t x) {
        int16_t s = (int16_t)x;
        assert(s == x);
        this->add(&s, 2);
        return s;
    }
    uint16_t addU16(size_t x) {
        assert((x & 0xFFFF) == x);
        uint16_t u = (uint16_t)x;
        this->add(&u, 2);
        return u;
    }
    uint32_t addU32(size_t x) {
        assert((x & 0xFFFFFFFF) == x);
        uint32_t u = (uint32_t)x;
        this->add(&u, 4);
        return u;
    }

    void add(const void* src, size_t n) {
        size_t size = bytes.size();
        bytes.resize(size + n);
        memcpy(bytes.data() + size, src, n);
    }
    template <typename T> void add(const std::vector<T>& v) {
        this->add(v.data(), v.size() * sizeof(T));
    }
    void add(const ByteBuilder& bb) {
        this->add(bb.bytes.data(), bb.bytes.size());
    }
    void add(sk_sp<SkData> data) {
        this->add(data->data(), data->size());
    }
    
    void padTo16() {
        if (bytes.size() & 1) {
            this->add8(0);
        }
    }
    void padTo32() {
        while (bytes.size() & 3) {
            this->add8(0);
        }
    }
    
    void set32(size_t offset, uint32_t value) {
        assert(offset + 4 <= bytes.size());
        assert((offset & 3) == 0);
        memcpy(bytes.data() + offset, &value, 4);
    }
    
    sk_sp<SkData> detach() {
        auto data = SkData::MakeWithCopy(bytes.data(), bytes.size());
        bytes.clear();
        return data;
    }
};

void encode_path(ByteBuilder* bb, const SkPath& path, float scale) {
    std::vector<uint8_t>  varray;
    std::vector<uint16_t> parray;
    
    auto add_point = [&](SkPoint p) {
        parray.push_back(SkScalarRoundToInt(p.fX * scale));
        parray.push_back(SkScalarRoundToInt(p.fY * scale));
    };
    
    SkPath::RawIter iter(path);
    for (;;) {
        SkPoint pts[4];
        auto verb = iter.next(pts);
        if (verb == SkPath::kDone_Verb) {
            break;
        }
        varray.push_back(verb);
        switch ((SkPathVerb)verb) {
            case SkPathVerb::kMove:
                add_point(pts[0]);
                break;
            case SkPathVerb::kLine:
                add_point(pts[1]);
                break;
            case SkPathVerb::kQuad:
                add_point(pts[1]); add_point(pts[2]);
                break;
            case SkPathVerb::kCubic:
                add_point(pts[1]); add_point(pts[2]); add_point(pts[3]);
                break;
            case SkPathVerb::kClose:
                break;
            default:
                assert(false);  // unsupported
        }
    }
    assert((int)varray.size() == path.countVerbs());
    assert((int)parray.size() == path.countPoints() * 2);

    auto no_useful_verbs = [](const std::vector<uint8_t>& verbs) {
        for (auto v : verbs) {
            switch ((SkPathVerb)v) {
                case SkPathVerb::kLine:
                case SkPathVerb::kQuad:
                case SkPathVerb::kCubic:
                    return false;
                default:
                    break;
            }
        }
        return true;
    };
    if (no_useful_verbs(varray)) {
        return; // we signal empty paths with the offset table
    }

    bb->addU16(varray.size());
    assert((parray.size() & 1) == 0);
    bb->addU16(parray.size() / 2);  // #points == 2 * #values
    
    bb->add(varray);
    bb->padTo16();
    bb->add(parray);
}

sk_sp<SkData> RiveFont::encode() const {
    sk_sp<SkData> infoD, cmapD, offsetsD, pathsD;
    const int upem = 2048;
    const float scale = upem;

    struct DirRec {
        uint32_t tag;
        sk_sp<SkData> data;
    };
    std::vector<DirRec> dir;

    {
        InfoTable itable;
        itable.glyphCount = fGlyphs.size();
        itable.upem = upem;
        dir.push_back({
            kInfo_TableTag, SkData::MakeWithCopy(&itable, sizeof(itable))
        });
    }

    {
        ByteBuilder cmap;
        // start with #pairs
        cmap.addU16(fCMap.size());
        for (const auto& cm : fCMap) {
            cmap.addU16(cm.fChar);
            cmap.addU16(cm.fGlyph);
        }
        dir.push_back({ kCMap_TableTag, cmap.detach() });
    }

    // todo: store offset[i] for glyph[i+1] since first offset is always 0
    {
        ByteBuilder paths, advances;
        std::vector<uint32_t> offsets;
        for (const auto& g : fGlyphs) {
            offsets.push_back(paths.length());
            encode_path(&paths, g.fPath, scale);
            paths.padTo16();
            advances.addU16(SkScalarRoundToInt(g.fAdvance * scale));
        }
        offsets.push_back(paths.length());  // store N+1 offsets

        dir.push_back({
            kOffsets_TableTag, SkData::MakeWithCopy(offsets.data(), offsets.size() * 4)
        });
        dir.push_back({ kPaths_TableTag, paths.detach() });
        dir.push_back({ kAdvances_TableTag, advances.detach() });
    }

    std::sort(dir.begin(), dir.end(), [](const DirRec& a, const DirRec& b) {
        return a.tag < b.tag;
    });

    ByteBuilder header;
    header.addU32(kSignature);
    header.addU32(kVersion);
    header.addU32(dir.size());
    for (auto& d : dir) {
        header.addU32(d.tag);
        header.addU32(0);       // offset -- fill in later
        header.addU32(d.data->size());
    }

    size_t offsetToDirEntry = sizeof(FontHead);
    for (auto& d : dir) {
        // +4 to skip the tag field of the dir entry
        header.set32(offsetToDirEntry + 4, header.length());
        offsetToDirEntry += sizeof(TableDir);

        header.add(d.data);
        header.padTo32();
    }
    return header.detach();
}

struct Reader {
    const char* fStart;
    const char* fCurr;
    const char* fStop;

    Reader(const void* data, size_t length) {
        fStart = (const char*)data;
        fCurr = fStart;
        fStop = fStart + length;
    }
    
    bool isAvailable(size_t n) const { return fCurr + n <= fStop; }
    size_t available() const { return fStop - fCurr; }
    
    template <typename T> const T* skip(size_t size) {
        assert(this->isAvailable(size));
        const char* p = fCurr;
        fCurr += size;
        return reinterpret_cast<const T*>(p);
    }
    
    template <typename T> const T* skip() {
        return this->skip<T>(sizeof(T));
    }

    void skip(size_t size) {
    }

    uint8_t u8() {
        assert(this->isAvailable(1));
        return *fCurr++;
    }
    
    int16_t s16() {
        assert(this->isAvailable(2));
        int16_t s;
        memcpy(&s, fCurr, 2);
        fCurr += 2;
        return s;
    }
    uint16_t u16() {
        assert(this->isAvailable(2));
        uint16_t s;
        memcpy(&s, fCurr, 2);
        fCurr += 2;
        return s;
    }
    uint32_t u32() {
        assert(this->isAvailable(4));
        uint32_t s;
        memcpy(&s, fCurr, 4);
        fCurr += 4;
        return s;
    }
    
    void read(void* dst, size_t size) {
        assert(this->isAvailable(size));
        memcpy(dst, fCurr, size);
        fCurr += size;
    }
    
    void skipPad16() {
        size_t amount = fCurr - fStart;
        if (amount & 1) {
            assert(this->isAvailable(1));
            fCurr += 1;
        }
    }
};

static int compute_point_count(const uint8_t verbs[], int verbCount) {
    int count = 0;
    for (int i = 0; i < verbCount; ++i) {
        switch ((SkPathVerb)verbs[i]) {
            case SkPathVerb::kMove:  count += 1; break;
            case SkPathVerb::kLine:  count += 1; break;
            case SkPathVerb::kQuad:  count += 2; break;
            case SkPathVerb::kCubic: count += 3; break;
            case SkPathVerb::kClose: count += 0; break;
            default:
                assert(false);
                return -1;
        }
    }
    return count;
}

static SkPath decode_path(const void* data, size_t length, float scale) {
    Reader reader(data, length);

    const int verbCount = reader.u16();
    assert(verbCount > 0);
    const int pointCount = reader.u16();

    auto verbs = reader.skip<uint8_t>(verbCount);
    reader.skipPad16();
    const int computedPointCount = compute_point_count(verbs, verbCount);
    assert(pointCount == computedPointCount);

    auto pts16 = reader.skip<int16_t>(pointCount * 2 * sizeof(int16_t));
    assert(reader.available() == 0);

    SkPoint pts[pointCount];
    for (int i = 0; i < pointCount; ++i) {
        pts[i] = { pts16[0] * scale, pts16[1] * scale };
        pts16 += 2;
    }

    return SkPath::Make(pts, pointCount,
                        verbs, verbCount,
                        nullptr, 0,
                        SkPathFillType::kWinding);
}

bool RiveFont::decode(const void* data, size_t length) {
    Reader reader(data, length);

    auto font = reader.skip<FontHead>();
    assert(font->signature == kSignature);
    assert(font->version == kVersion);
    assert(font->tableCount >= 0);

    assert(reader.isAvailable(font->tableCount * sizeof(TableDir)));

    if (true) {
        auto dir = font->dir();
        for (unsigned i = 0; i < font->tableCount; ++i) {
            char str[5];
            tag_to_str(dir[i].tag, str);
            printf("[%d] {%0x08 %s %10d} %d %d\n", i, dir[i].tag, str, dir[i].tag,
                   dir[i].offset, dir[i].length);
        }
    }

    auto info     = (const InfoTable*)font->findTable(kInfo_TableTag);
    auto cmap     = (const uint16_t*)font->findTable(kCMap_TableTag);
    auto paths    = (const char*)font->findTable(kPaths_TableTag);
    auto offsets  = (const uint32_t*)font->findTable(kOffsets_TableTag);
    auto advances = (const uint16_t*)font->findTable(kAdvances_TableTag);

    const int glyphCount = info->glyphCount;

    this->clear();

    const int pairCount = *cmap++;
    for (int i = 0; i < pairCount; ++i) {
        uint16_t c = *cmap++;
        uint16_t g = *cmap++;
        assert(g < glyphCount);

        fCMap.push_back({c, g});
    }
    
    const float scale = 1.0f / (float)info->upem;

    for (int i = 0; i < glyphCount; ++i) {
        float adv = advances[i] * scale;
        uint32_t start = offsets[i];
        uint32_t end = offsets[i+1];
        assert(start <= end);

        fGlyphs.push_back({
            (start == end) ? SkPath() : decode_path(paths + start, end - start, scale),
            adv
        });
    }
    return true;
}
