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

#include "modules/skplaintexteditor/src/shape.h"

#include "include/core/SkFont.h"
#include "include/core/SkFontMetrics.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkString.h"
#include "include/core/SkTextBlob.h"
#include "include/core/SkTypes.h"
#include "include/private/SkTFitsIn.h"
#include "modules/skplaintexteditor/src/word_boundaries.h"
#include "modules/skshaper/include/SkShaper.h"
#include "src/core/SkTextBlobPriv.h"
#include "src/utils/SkUTF.h"

#include <limits.h>
#include <string.h>


using namespace SkPlainTextEditor;

namespace {
class RunHandler final : public SkShaper::RunHandler {
public:
    RunHandler(const char* utf8Text, size_t) : fUtf8Text(utf8Text) {}
    using RunCallback = void (*)(void* context,
                                 const char* utf8Text,
                                  size_t utf8TextBytes,
                                  size_t glyphCount,
                                  const SkGlyphID* glyphs,
                                  const SkPoint* positions,
                                  const uint32_t* clusters,
                                  const SkFont& font);
    void setRunCallback(RunCallback f, void* context) {
        fCallbackContext = context;
        fCallbackFunction = f;
    }

    sk_sp<SkTextBlob> makeBlob();
    SkPoint endPoint() const { return fOffset; }
    SkPoint finalPosition() const { return fCurrentPosition; }

    void beginLine() override;
    void runInfo(const RunInfo&) override;
    void commitRunInfo() override;
    SkShaper::RunHandler::Buffer runBuffer(const RunInfo&) override;
    void commitRunBuffer(const RunInfo&) override;
    void commitLine() override;

    const std::vector<size_t>& lineEndOffsets() const { return fLineEndOffsets; }

    SkRect finalRect(const SkFont& font) const {
        if (0 == fMaxRunAscent || 0 == fMaxRunDescent) {
            SkFontMetrics metrics;
            font.getMetrics(&metrics);
            return {fCurrentPosition.x(),
                    fCurrentPosition.y(),
                    fCurrentPosition.x() + font.getSize(),
                    fCurrentPosition.y() + metrics.fDescent - metrics.fAscent};
        } else {
            return {fCurrentPosition.x(),
                    fCurrentPosition.y() + fMaxRunAscent,
                    fCurrentPosition.x() + font.getSize(),
                    fCurrentPosition.y() + fMaxRunDescent};
        }
    }


private:
    SkTextBlobBuilder fBuilder;
    std::vector<size_t> fLineEndOffsets;
    const SkGlyphID* fCurrentGlyphs = nullptr;
    const SkPoint* fCurrentPoints = nullptr;
    void* fCallbackContext = nullptr;
    RunCallback fCallbackFunction = nullptr;
    char const * const fUtf8Text;
    size_t fTextOffset = 0;
    uint32_t* fClusters = nullptr;
    int fClusterOffset = 0;
    int fGlyphCount = 0;
    SkScalar fMaxRunAscent = 0;
    SkScalar fMaxRunDescent = 0;
    SkScalar fMaxRunLeading = 0;
    SkPoint fCurrentPosition = {0, 0};
    SkPoint fOffset = {0, 0};
};
}  // namespace

void RunHandler::beginLine() {
    fCurrentPosition = fOffset;
    fMaxRunAscent = 0;
    fMaxRunDescent = 0;
    fMaxRunLeading = 0;
}

void RunHandler::runInfo(const SkShaper::RunHandler::RunInfo& info) {
    SkFontMetrics metrics;
    info.fFont.getMetrics(&metrics);
    fMaxRunAscent = SkTMin(fMaxRunAscent, metrics.fAscent);
    fMaxRunDescent = SkTMax(fMaxRunDescent, metrics.fDescent);
    fMaxRunLeading = SkTMax(fMaxRunLeading, metrics.fLeading);
}

void RunHandler::commitRunInfo() {
    fCurrentPosition.fY -= fMaxRunAscent;
}

SkShaper::RunHandler::Buffer RunHandler::runBuffer(const RunInfo& info) {
    int glyphCount = SkTFitsIn<int>(info.glyphCount) ? info.glyphCount : INT_MAX;
    int utf8RangeSize = SkTFitsIn<int>(info.utf8Range.size()) ? info.utf8Range.size() : INT_MAX;

    const auto& runBuffer = SkTextBlobBuilderPriv::AllocRunTextPos(&fBuilder, info.fFont, glyphCount,
                                                                   utf8RangeSize, SkString());
    fCurrentGlyphs = runBuffer.glyphs;
    fCurrentPoints = runBuffer.points();

    if (runBuffer.utf8text && fUtf8Text) {
        memcpy(runBuffer.utf8text, fUtf8Text + info.utf8Range.begin(), utf8RangeSize);
    }
    fClusters = runBuffer.clusters;
    fGlyphCount = glyphCount;
    fClusterOffset = info.utf8Range.begin();

    return {runBuffer.glyphs,
            runBuffer.points(),
            nullptr,
            runBuffer.clusters,
            fCurrentPosition};
}

void RunHandler::commitRunBuffer(const RunInfo& info) {
    // for (size_t i = 0; i < info.glyphCount; ++i) {
    //     SkASSERT(fClusters[i] >= info.utf8Range.begin());
    //     // this fails for khmer example.
    //     SkASSERT(fClusters[i] <  info.utf8Range.end());
    // }
    if (fCallbackFunction) {
        fCallbackFunction(fCallbackContext,
                          fUtf8Text,
                          info.utf8Range.end(),
                          info.glyphCount,
                          fCurrentGlyphs,
                          fCurrentPoints,
                          fClusters,
                          info.fFont);
    }
    SkASSERT(0 <= fClusterOffset);
    for (int i = 0; i < fGlyphCount; ++i) {
        SkASSERT(fClusters[i] >= (unsigned)fClusterOffset);
        fClusters[i] -= fClusterOffset;
    }
    fCurrentPosition += info.fAdvance;
    fTextOffset = SkTMax(fTextOffset, info.utf8Range.end());
}

void RunHandler::commitLine() {
    if (fLineEndOffsets.empty() || fTextOffset > fLineEndOffsets.back()) {
        // Ensure that fLineEndOffsets is monotonic.
        fLineEndOffsets.push_back(fTextOffset);
    }
    fOffset += { 0, fMaxRunDescent + fMaxRunLeading - fMaxRunAscent };
}

sk_sp<SkTextBlob> RunHandler::makeBlob() {
    return fBuilder.make();
}

static SkRect selection_box(const SkFontMetrics& metrics,
                            float advance,
                            SkPoint pos) {
    if (fabsf(advance) < 1.0f) {
        advance = copysignf(1.0f, advance);
    }
    return SkRect{pos.x(),
                  pos.y() + metrics.fAscent,
                  pos.x() + advance,
                  pos.y() + metrics.fDescent}.makeSorted();
}

static void set_character_bounds(void* context,
                                 const char* utf8Text,
                                 size_t utf8TextBytes,
                                 size_t glyphCount,
                                 const SkGlyphID* glyphs,
                                 const SkPoint* positions,
                                 const uint32_t* clusters,
                                 const SkFont& font)
{
    SkASSERT(context);
    SkASSERT(glyphCount > 0);
    SkRect* cursors = (SkRect*)context;

    SkFontMetrics metrics;
    font.getMetrics(&metrics);
    std::unique_ptr<float[]> advances(new float[glyphCount]);
    font.getWidths(glyphs, glyphCount, advances.get());

    // Loop over each cluster in this run.
    size_t clusterStart = 0;
    for (size_t glyphIndex = 0; glyphIndex < glyphCount; ++glyphIndex) {
        if (glyphIndex + 1 < glyphCount  // more glyphs
            && clusters[glyphIndex] == clusters[glyphIndex + 1]) {
            continue; // multi-glyph cluster
        }
        unsigned textBegin = clusters[glyphIndex];
        unsigned textEnd = utf8TextBytes;
        for (size_t i = 0; i < glyphCount; ++i) {
            if (clusters[i] >= textEnd) {
                textEnd = clusters[i] + 1;
            }
        }
        for (size_t i = 0; i < glyphCount; ++i) {
            if (clusters[i] > textBegin && clusters[i] < textEnd) {
                textEnd = clusters[i];
                if (textEnd == textBegin + 1) { break; }
            }
        }
        SkASSERT(glyphIndex + 1 > clusterStart);
        unsigned clusterGlyphCount = glyphIndex + 1 - clusterStart;
        const SkPoint* clusterGlyphPositions = &positions[clusterStart];
        const float* clusterAdvances = &advances[clusterStart];
        clusterStart = glyphIndex + 1;  // for next loop

        SkRect clusterBox = selection_box(metrics, clusterAdvances[0], clusterGlyphPositions[0]);
        for (unsigned i = 1; i < clusterGlyphCount; ++i) { // multiple glyphs
            clusterBox.join(selection_box(metrics, clusterAdvances[i], clusterGlyphPositions[i]));
        }
        if (textBegin + 1 == textEnd) {  // single byte, fast path.
            cursors[textBegin] = clusterBox;
            continue;
        }
        int textCount = textEnd - textBegin;
        int codePointCount = SkUTF::CountUTF8(utf8Text + textBegin, textCount);
        if (codePointCount == 1) {  // single codepoint, fast path.
            cursors[textBegin] = clusterBox;
            continue;
        }

        float width = clusterBox.width() / codePointCount;
        SkASSERT(width > 0);
        const char* ptr = utf8Text + textBegin;
        const char* end = utf8Text + textEnd;
        float x = clusterBox.left();
        while (ptr < end) {  // for each codepoint in cluster
            const char* nextPtr = ptr;
            SkUTF::NextUTF8(&nextPtr, end);
            int firstIndex = ptr - utf8Text;
            float nextX = x + width;
            cursors[firstIndex] = SkRect{x, clusterBox.top(), nextX, clusterBox.bottom()};
            x = nextX;
            ptr = nextPtr;
        }
    }
}

ShapeResult SkPlainTextEditor::Shape(const char* utf8Text,
                          size_t textByteLen,
                          const SkFont& font,
                          const char* locale,
                          float width)
{
    ShapeResult result;
    if (SkUTF::CountUTF8(utf8Text, textByteLen) < 0) {
        utf8Text = nullptr;
        textByteLen = 0;
    }
    std::unique_ptr<SkShaper> shaper = SkShaper::Make();
    float height = font.getSpacing();
    RunHandler runHandler(utf8Text, textByteLen);
    if (textByteLen) {
        result.glyphBounds.resize(textByteLen);
        for (SkRect& c : result.glyphBounds) {
            c = SkRect{-FLT_MAX, -FLT_MAX, -FLT_MAX, -FLT_MAX};
        }
        runHandler.setRunCallback(set_character_bounds, result.glyphBounds.data());
        // TODO: make use of locale in shaping.
        shaper->shape(utf8Text, textByteLen, font, true, width, &runHandler);
        if (runHandler.lineEndOffsets().size() > 1) {
            result.lineBreakOffsets = runHandler.lineEndOffsets();
            SkASSERT(result.lineBreakOffsets.size() > 0);
            result.lineBreakOffsets.pop_back();
        }
        height = std::max(height, runHandler.endPoint().y());
        result.blob = runHandler.makeBlob();
    }
    result.glyphBounds.push_back(runHandler.finalRect(font));
    result.verticalAdvance = (int)ceilf(height);
    result.wordBreaks = GetUtf8WordBoundaries(utf8Text, textByteLen, locale);
    return result;
}
