// Copyright 2021 Google LLC.
#ifndef LogicalRun_DEFINED
#define LogicalRun_DEFINED

#include "experimental/sktext/include/Types.h"
#include "experimental/sktext/src/Line.h"
#include "modules/skshaper/include/SkShaper.h"

namespace skia {
namespace text {

class LogicalRun {
    public:
    LogicalRun(const SkShaper::RunHandler::RunInfo& info, TextIndex textStart, SkScalar glyphOffset);
    SkShaper::RunHandler::Buffer newRunBuffer() {
        return {fGlyphs.data(), fPositions.data(), fOffsets.data(), fClusters.data(), {0.0f, 0.0f} };
    }
    void commit() {
        fFont.getBounds(fGlyphs.data(), fGlyphs.size(), fBounds.data(), nullptr);
        fPositions[fGlyphs.size()] = fAdvance;
        fClusters[fGlyphs.size()] = this->leftToRight() ? fUtf8Range.end() : fUtf8Range.begin();
    }

    TextRange getTextRange() const { return fUtf16Range; }

    SkScalar calculateWidth(GlyphRange glyphRange) const {
        SkASSERT(glyphRange.fStart <= glyphRange.fEnd &&
                 glyphRange.fEnd < SkToSizeT(fPositions.size()));
        return fPositions[glyphRange.fEnd].fX - fPositions[glyphRange.fStart].fX;
    }
    SkScalar calculateWidth(GlyphIndex start, GlyphIndex end) const {
      return calculateWidth(GlyphRange(start, end));
    }
    SkScalar width() const { return fAdvance.fX; }
    SkScalar firstGlyphPosition() const { return fPositions[0].fX; }

    bool leftToRight() const { return fBidiLevel % 2 == 0; }
    uint8_t bidiLevel() const { return fBidiLevel; }
    size_t size() const { return fGlyphs.size(); }

    LogicalRunType getRunType() const { return fRunType; }
    void setRunType(LogicalRunType runType) { fRunType = runType; }

    template <typename Callback>
    void forEachCluster(Callback&& callback) {
        for(int glyph = 0; glyph < fClusters.size(); ++glyph) {
            callback(glyph, fRunStart + fClusters[glyph]);
        }
    }

    template <typename Callback>
    void convertUtf16Range(Callback&& callback) {
        this->fUtf16Range.fStart = callback(this->fUtf8Range.begin());
        this->fUtf16Range.fEnd = callback(this->fUtf8Range.end());
    }

    // Convert indexes into utf16 and also shift them to be on the entire text scale
    template <typename Callback>
    void convertClusterIndexes(Callback&& callback) {
        for (int glyph = 0; glyph < fClusters.size(); ++glyph) {
            fClusters[glyph] = callback(fClusters[glyph]);
        }
    }

    private:
    friend class ShapedText;
    friend class WrappedText;
    SkFont fFont;
    TextMetrics fTextMetrics;

    LogicalRunType fRunType;
    SkVector fAdvance;
    SkShaper::RunHandler::Range fUtf8Range;
    TextRange fUtf16Range;
    TextIndex fRunStart;
    SkScalar  fRunOffset;
    SkSTArray<128, SkGlyphID, true> fGlyphs;
    SkSTArray<128, SkPoint, true> fPositions;
    SkSTArray<128, SkPoint, true> fOffsets;
    SkSTArray<128, uint32_t, true> fClusters;
    SkSTArray<128, SkRect, true> fBounds;

    uint8_t fBidiLevel;
};

} // namespace text
} // namespace skia
#endif
