/*
 * Copyright 2022 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkFont.h"
#include "include/core/SkFontMgr.h"
#include "include/core/SkGraphics.h"
#include "include/core/SkTime.h"
#include "include/core/SkTypeface.h"
#include "include/ports/SkFontMgr_empty.h"
#include "samplecode/Sample.h"
#include "src/sfnt/SkOTTable_glyf.h"
#include "src/sfnt/SkOTTable_head.h"
#include "src/sfnt/SkOTTable_hhea.h"
#include "src/sfnt/SkOTTable_hmtx.h"
#include "src/sfnt/SkOTTable_loca.h"
#include "src/sfnt/SkOTTable_maxp.h"
#include "src/sfnt/SkSFNTHeader.h"
#include "tools/Resources.h"
#include "tools/timer/TimeUtils.h"

namespace {

constexpr SkScalar DX = 100;
constexpr SkScalar DY = 300;
constexpr int kPointSize = 5;
constexpr SkScalar kFontSize = 200;

constexpr char kFontFile[] = "fonts/sbix_uncompressed_flags.ttf";
constexpr SkGlyphID kGlyphID = 2;

//constexpr char kFontFile[] = "fonts/HangingS.ttf";
//constexpr SkGlyphID kGlyphID = 4;

/**
 *  Return the closest int for the given float. Returns SK_MaxS32FitsInFloat for NaN.
 */
static inline int16_t sk_float_saturate2int16(float x) {
    x = x < SK_MaxS16 ? x : SK_MaxS16;
    x = x > SK_MinS16 ? x : SK_MinS16;
    return (int16_t)x;
}

struct ShortCoordinate { bool negative; uint8_t magnitude; };
static inline ShortCoordinate sk_float_saturate2sm8(float x) {
    bool negative = x < 0;
    x = x <  255 ? x :  255;
    x = x > -255 ? x : -255;
    return ShortCoordinate{ negative, negative ? (uint8_t)-x : (uint8_t)x };
}

struct SBIXView : public Sample {
    SkString name() override { return SkString("SBIX"); }

    SkPoint  fPts[12] = {
        {0, 0}, // min
        {0, 0}, // max
        {0, 20}, // lsb
        {0, 0}, // point
   };
    std::vector<sk_sp<SkFontMgr>> fFontMgr;
    std::vector<SkFont> fFonts;
    sk_sp<SkData> fSBIXData;
    bool fInputChanged = false;
    bool fDirty = true;

    sk_sp<SkData> updateSBIXData(SkData* originalData, bool setPts) {
        // Lots of unlikely to be aligned pointers in here, which is UB. Total hack.

        sk_sp<SkData> dataCopy = SkData::MakeWithCopy(originalData->data(), originalData->size());

        SkSFNTHeader* sfntHeader = static_cast<SkSFNTHeader*>(dataCopy->writable_data());

        SkASSERT_RELEASE(memcmp(sfntHeader, originalData->data(), originalData->size()) == 0);

        SkSFNTHeader::TableDirectoryEntry* tableEntry =
            SkTAfter<SkSFNTHeader::TableDirectoryEntry>(sfntHeader);
        SkSFNTHeader::TableDirectoryEntry* glyfTableEntry = nullptr;
        SkSFNTHeader::TableDirectoryEntry* headTableEntry = nullptr;
        SkSFNTHeader::TableDirectoryEntry* hheaTableEntry = nullptr;
        SkSFNTHeader::TableDirectoryEntry* hmtxTableEntry = nullptr;
        SkSFNTHeader::TableDirectoryEntry* locaTableEntry = nullptr;
        SkSFNTHeader::TableDirectoryEntry* maxpTableEntry = nullptr;
        int numTables = SkEndian_SwapBE16(sfntHeader->numTables);
        for (int tableEntryIndex = 0; tableEntryIndex < numTables; ++tableEntryIndex) {
            if (SkOTTableGlyph::TAG == tableEntry[tableEntryIndex].tag) {
                glyfTableEntry = tableEntry + tableEntryIndex;
            }
            if (SkOTTableHead::TAG == tableEntry[tableEntryIndex].tag) {
                headTableEntry = tableEntry + tableEntryIndex;
            }
            if (SkOTTableHorizontalHeader::TAG == tableEntry[tableEntryIndex].tag) {
                hheaTableEntry = tableEntry + tableEntryIndex;
            }
            if (SkOTTableHorizontalMetrics::TAG == tableEntry[tableEntryIndex].tag) {
                hmtxTableEntry = tableEntry + tableEntryIndex;
            }
            if (SkOTTableIndexToLocation::TAG == tableEntry[tableEntryIndex].tag) {
                locaTableEntry = tableEntry + tableEntryIndex;
            }
            if (SkOTTableMaximumProfile::TAG == tableEntry[tableEntryIndex].tag) {
                maxpTableEntry = tableEntry + tableEntryIndex;
            }
        }
        SkASSERT_RELEASE(glyfTableEntry);
        SkASSERT_RELEASE(headTableEntry);
        SkASSERT_RELEASE(hheaTableEntry);
        SkASSERT_RELEASE(hmtxTableEntry);
        SkASSERT_RELEASE(locaTableEntry);
        SkASSERT_RELEASE(maxpTableEntry);

        size_t glyfTableOffset = SkEndian_SwapBE32(glyfTableEntry->offset);
        SkOTTableGlyph* glyfTable =
                SkTAddOffset<SkOTTableGlyph>(sfntHeader, glyfTableOffset);

        size_t headTableOffset = SkEndian_SwapBE32(headTableEntry->offset);
        SkOTTableHead* headTable =
                SkTAddOffset<SkOTTableHead>(sfntHeader, headTableOffset);

        size_t hheaTableOffset = SkEndian_SwapBE32(hheaTableEntry->offset);
        SkOTTableHorizontalHeader* hheaTable =
                SkTAddOffset<SkOTTableHorizontalHeader>(sfntHeader, hheaTableOffset);

        size_t hmtxTableOffset = SkEndian_SwapBE32(hmtxTableEntry->offset);
        SkOTTableHorizontalMetrics* hmtxTable =
                SkTAddOffset<SkOTTableHorizontalMetrics>(sfntHeader, hmtxTableOffset);

        size_t locaTableOffset = SkEndian_SwapBE32(locaTableEntry->offset);
        SkOTTableIndexToLocation* locaTable =
                SkTAddOffset<SkOTTableIndexToLocation>(sfntHeader, locaTableOffset);

        size_t maxpTableOffset = SkEndian_SwapBE32(maxpTableEntry->offset);
        SkOTTableMaximumProfile* maxpTable =
                SkTAddOffset<SkOTTableMaximumProfile>(sfntHeader, maxpTableOffset);

        SkASSERT_RELEASE(SkEndian_SwapBE32(maxpTable->version.version) == 0x00010000);
        int numGlyphs = SkEndian_SwapBE16(maxpTable->version.tt.numGlyphs);
        SkASSERT_RELEASE(kGlyphID < numGlyphs);

        int emSize = SkEndian_SwapBE16(headTable->unitsPerEm);
        SkScalar toEm = emSize / kFontSize;

        SkOTTableGlyph::Iterator glyphIter(*glyfTable, *locaTable, headTable->indexToLocFormat);
        glyphIter.advance(kGlyphID);
        SkOTTableGlyphData* glyphData = glyphIter.next();
        if (glyphData) {
            if (setPts) {
                fPts[0].set((int16_t)SkEndian_SwapBE16(glyphData->xMin) /  toEm,
                            (int16_t)SkEndian_SwapBE16(glyphData->yMin) / -toEm);
                fPts[1].set((int16_t)SkEndian_SwapBE16(glyphData->xMax) /  toEm,
                            (int16_t)SkEndian_SwapBE16(glyphData->yMax) / -toEm);
            } else {
                glyphData->xMin = SkEndian_SwapBE16(sk_float_saturate2int16( fPts[0].x()*toEm));
                glyphData->yMin = SkEndian_SwapBE16(sk_float_saturate2int16(-fPts[0].y()*toEm));
                glyphData->xMax = SkEndian_SwapBE16(sk_float_saturate2int16( fPts[1].x()*toEm));
                glyphData->yMax = SkEndian_SwapBE16(sk_float_saturate2int16(-fPts[1].y()*toEm));
            }

            int contourCount = SkEndian_SwapBE16(glyphData->numberOfContours);
            if (contourCount > 0) {
                SK_OT_USHORT* endPtsOfContours = SkTAfter<SK_OT_USHORT>(glyphData);
                SK_OT_USHORT* numInstructions = SkTAfter<SK_OT_USHORT>(endPtsOfContours,
                                                                       contourCount);
                SK_OT_BYTE* instructions = SkTAfter<SK_OT_BYTE>(numInstructions);
                SkOTTableGlyphData::Simple::Flags* flags =
                    SkTAfter<SkOTTableGlyphData::Simple::Flags>(
                        instructions, SkEndian_SwapBE16(*numInstructions));

                int numResultPoints = SkEndian_SwapBE16(endPtsOfContours[contourCount-1]) + 1;
                struct Coordinate {
                    SkOTTableGlyphData::Simple::Flags* flags;
                    size_t offsetToXDelta;
                    size_t xDeltaSize;
                    size_t offsetToYDelta;
                    size_t yDeltaSize;
                };
                std::vector<Coordinate> coordinates(numResultPoints);

                size_t offsetToXDelta = 0;
                size_t offsetToYDelta = 0;
                SkOTTableGlyphData::Simple::Flags* currentFlags = flags;
                for (int i = 0; i < numResultPoints; ++i) {
                    SkOTTableGlyphData::Simple::Flags* nextFlags;
                    int times = 1;
                    if (currentFlags->field.Repeat) {
                        SK_OT_BYTE* repeat = SkTAfter<SK_OT_BYTE>(currentFlags);
                        times += *repeat;
                        nextFlags = SkTAfter<SkOTTableGlyphData::Simple::Flags>(repeat);
                    } else {
                        nextFlags = SkTAfter<SkOTTableGlyphData::Simple::Flags>(currentFlags);
                    }

                    --i;
                    for (int time = 0; time < times; ++time) {
                        ++i;
                        coordinates[i].flags = currentFlags;
                        coordinates[i].offsetToXDelta = offsetToXDelta;
                        coordinates[i].offsetToYDelta = offsetToYDelta;

                        if (currentFlags->field.xShortVector) {
                            offsetToXDelta += 1;
                            coordinates[i].xDeltaSize = 1;
                        } else if (currentFlags->field.xIsSame_xShortVectorPositive) {
                            offsetToXDelta += 0;
                            if (i == 0) {
                                coordinates[i].xDeltaSize = 0;
                            } else {
                                coordinates[i].xDeltaSize = coordinates[i-1].xDeltaSize;
                            }
                        } else {
                            offsetToXDelta += 2;
                            coordinates[i].xDeltaSize = 2;
                        }

                        if (currentFlags->field.yShortVector) {
                            offsetToYDelta += 1;
                            coordinates[i].yDeltaSize = 1;
                        } else if (currentFlags->field.yIsSame_yShortVectorPositive) {
                            offsetToYDelta += 0;
                            if (i == 0) {
                                coordinates[i].yDeltaSize = 0;
                            } else {
                                coordinates[i].yDeltaSize = coordinates[i-1].yDeltaSize;
                            }
                        } else {
                            offsetToYDelta += 2;
                            coordinates[i].yDeltaSize = 2;
                        }
                    }
                    currentFlags = nextFlags;
                }
                SK_OT_BYTE* xCoordinates = reinterpret_cast<SK_OT_BYTE*>(currentFlags);
                SK_OT_BYTE* yCoordinates = xCoordinates + offsetToXDelta;

                int pointIndex = 0;
                if (coordinates[pointIndex].xDeltaSize == 0) {
                    // Zero delta relative to the origin. There is no data to modify.
                    SkDebugf("Failed to move point in X at all.\n");
                } else if (coordinates[pointIndex].xDeltaSize == 1) {
                    ShortCoordinate x = sk_float_saturate2sm8(fPts[3].x()*toEm);
                    xCoordinates[coordinates[pointIndex].offsetToXDelta] = x.magnitude;
                    coordinates[pointIndex].flags->field.xIsSame_xShortVectorPositive = !x.negative;
                } else {
                    *reinterpret_cast<SK_OT_SHORT*>(xCoordinates + coordinates[pointIndex].offsetToXDelta) =
                        SkEndian_SwapBE16(sk_float_saturate2int16(fPts[3].x()*toEm));
                }

                if (coordinates[pointIndex].yDeltaSize == 0) {
                    // Zero delta relative to the origin. There is no data to modify.
                    SkDebugf("Failed to move point in Y at all.\n");
                } else if (coordinates[pointIndex].yDeltaSize == 1) {
                    ShortCoordinate y = sk_float_saturate2sm8(-fPts[3].y()*toEm);
                    yCoordinates[coordinates[pointIndex].offsetToYDelta] = y.magnitude;
                    coordinates[pointIndex].flags->field.yIsSame_yShortVectorPositive = !y.negative;
                } else {
                    *reinterpret_cast<SK_OT_SHORT*>(yCoordinates + coordinates[pointIndex].offsetToYDelta) =
                        SkEndian_SwapBE16(sk_float_saturate2int16(-fPts[3].y()*toEm));
                }
            }
        }

        int numberOfFullMetrics = SkEndian_SwapBE16(hheaTable->numberOfHMetrics);
        SkOTTableHorizontalMetrics::FullMetric* fullMetrics = hmtxTable->longHorMetric;
        SK_OT_SHORT lsb = SkEndian_SwapBE16(sk_float_saturate2int16(fPts[2].x()*toEm));
        if (kGlyphID < numberOfFullMetrics) {
            if (setPts) {
                fPts[2].fX = (int16_t)SkEndian_SwapBE16(fullMetrics[kGlyphID].lsb) / toEm;
            } else {
                fullMetrics[kGlyphID].lsb = lsb;
            }
        } else {
            SkOTTableHorizontalMetrics::ShortMetric* shortMetrics =
                SkTAfter<SkOTTableHorizontalMetrics::ShortMetric>(fullMetrics, numberOfFullMetrics);
            int shortMetricIndex = kGlyphID - numberOfFullMetrics;
            if (setPts) {
                fPts[2].fX = (int16_t)SkEndian_SwapBE16(shortMetrics[shortMetricIndex].lsb) / toEm;
            } else {
                shortMetrics[shortMetricIndex].lsb = lsb;
            }
        }

        headTable->flags.field.LeftSidebearingAtX0 = false;
        return dataCopy;
    }

    void onOnceBeforeDraw() override {
        fFontMgr.emplace_back(SkFontMgr::RefDefault());
        //fFontMgr.emplace_back(SkFontMgr_New_Custom_Empty());
        // GetResourceAsData may be backed by a read only file mapping.
        // For sanity always make a copy.
        fSBIXData = GetResourceAsData(kFontFile);
        this->setBGColor(SK_ColorGRAY);

        updateSBIXData(fSBIXData.get(), true);
    }

    void onDrawContent(SkCanvas* canvas) override {
        canvas->translate(DX, DY);

        SkPaint paint;
        SkPoint position{0, 0};
        SkPoint origin{0, 0};

        if (fDirty) {
            sk_sp<SkData> data(updateSBIXData(fSBIXData.get(), false));
            fFonts.clear();
            for (auto&& fontmgr : fFontMgr) {
                fFonts.emplace_back(fontmgr->makeFromData(data), kFontSize);
            }
            fDirty = false;
        }
        for (auto&& font : fFonts) {
            paint.setStyle(SkPaint::kFill_Style);
            paint.setColor(SK_ColorBLACK);
            canvas->drawGlyphs(1, &kGlyphID, &position, origin, font, paint);

            paint.setStrokeWidth(SkIntToScalar(kPointSize / 2));
            paint.setStyle(SkPaint::kStroke_Style);
            SkScalar advance;
            SkRect rect;
            font.getWidthsBounds(&kGlyphID, 1, &advance, &rect, &paint);

            paint.setColor(SK_ColorRED);
            canvas->drawRect(rect, paint);
            paint.setColor(SK_ColorGREEN);
            canvas->drawLine(0, 0, advance, 0, paint);
            paint.setColor(SK_ColorRED);
            canvas->drawPoint(0, 0, paint);
            canvas->drawPoint(advance, 0, paint);

            paint.setStrokeWidth(SkIntToScalar(kPointSize));
            canvas->drawPoints(SkCanvas::kPoints_PointMode, SK_ARRAY_COUNT(fPts), fPts, paint);

            canvas->translate(kFontSize, 0);
        }
    }

    class PtClick : public Click {
    public:
        int fIndex;
        PtClick(int index) : fIndex(index) {}
    };

    static bool hittest(const SkPoint& pt, SkScalar x, SkScalar y) {
        return SkPoint::Length(pt.fX - x, pt.fY - y) < SkIntToScalar(kPointSize);
    }

    Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override {
        x -= DX;
        y -= DY;
        for (size_t i = 0; i < SK_ARRAY_COUNT(fPts); i++) {
            if (hittest(fPts[i], x, y)) {
                return new PtClick((int)i);
            }
        }
        return nullptr;
    }

    bool onClick(Click* click) override {
        fPts[((PtClick*)click)->fIndex].set(click->fCurr.fX - DX, click->fCurr.fY - DY);
        fDirty = true;
        return true;
    }

private:
    using INHERITED = Sample;
};
}  // namespace
DEF_SAMPLE( return new SBIXView(); )
