#ifndef _RIVE_TEXT_CORE_HPP_
#define _RIVE_TEXT_CORE_HPP_
#include "rive/generated/text/text_base.hpp"
#include "rive/text/text_value_run.hpp"
#include "rive/text_engine.hpp"
#include "rive/simple_array.hpp"
#include <vector>
#include "rive/text/glyph_lookup.hpp"
namespace rive
{

enum class TextSizing : uint8_t
{
    autoWidth,
    autoHeight,
    fixed
};

enum class TextOverflow : uint8_t
{
    visible,
    hidden,
    clipped,
    ellipsis
};

enum class TextOrigin : uint8_t
{
    top,
    baseline
};

class OrderedLine;
class TextModifierGroup;

class StyledText
{
private:
    /// Represents the unicode characters making up the entire text string
    /// displayed. Only valid after update.
    std::vector<Unichar> m_value;
    std::vector<TextRun> m_runs;

public:
    bool empty() const;
    void clear();
    void append(rcp<Font> font,
                float size,
                float lineHeight,
                const std::string& text,
                uint16_t styleId);
    const std::vector<Unichar>& unichars() const { return m_value; }
    const std::vector<TextRun>& runs() const { return m_runs; }

    void swapRuns(std::vector<TextRun>& otherRuns) { m_runs.swap(otherRuns); }
};

// STL-style iterator for individual glyphs in a line, simplfies call sites from
// needing to iterate both runs and glyphs within those runs per line. A single
// iterator allows iterating all the glyphs in the line and provides the correct
// run they belong to (this also takes into account bidi which can put the runs
// in different order from how they were provided by the line breaker).
//
//   for (auto [run, glyphIndex] : orderedLine) { ... }
//
class GlyphItr
{
public:
    GlyphItr() = default;
    GlyphItr(const OrderedLine* line, const rive::GlyphRun* const* run, uint32_t glyphIndex) :
        m_line(line), m_run(run), m_glyphIndex(glyphIndex)
    {}

    bool operator!=(const GlyphItr& that) const
    {
        return m_run != that.m_run || m_glyphIndex != that.m_glyphIndex;
    }
    bool operator==(const GlyphItr& that) const
    {
        return m_run == that.m_run && m_glyphIndex == that.m_glyphIndex;
    }

    GlyphItr& operator++();

    std::tuple<const GlyphRun*, uint32_t> operator*() const { return {*m_run, m_glyphIndex}; }

private:
    const OrderedLine* m_line;
    const rive::GlyphRun* const* m_run;
    uint32_t m_glyphIndex;
};

// Represents a line of text with runs ordered visually. Also tracks logical
// start/end which will defer when using bidi.
class OrderedLine
{
public:
    OrderedLine(const Paragraph& paragraph,
                const GlyphLine& line,
                float lineWidth, // for ellipsis
                bool wantEllipsis,
                bool isEllipsisLineLast,
                GlyphRun* ellipsisRun);

    bool buildEllipsisRuns(std::vector<const GlyphRun*>& logicalRuns,
                           const Paragraph& paragraph,
                           const GlyphLine& line,
                           float lineWidth,
                           bool isEllipsisLineLast,
                           GlyphRun* ellipsisRun);
    const GlyphRun* startLogical() const { return m_startLogical; }
    const GlyphRun* endLogical() const { return m_endLogical; }
    const std::vector<const GlyphRun*>& runs() const { return m_runs; }

    GlyphItr begin() const
    {
        auto runItr = m_runs.data();
        return GlyphItr(this, runItr, startGlyphIndex(*runItr));
    }

    GlyphItr end() const
    {
        auto runItr = m_runs.data() + (m_runs.size() == 0 ? 0 : m_runs.size() - 1);
        return GlyphItr(this, runItr, endGlyphIndex(*runItr));
    }

private:
    const GlyphRun* m_startLogical = nullptr;
    const GlyphRun* m_endLogical = nullptr;
    uint32_t m_startGlyphIndex;
    uint32_t m_endGlyphIndex;
    std::vector<const GlyphRun*> m_runs;

public:
    const GlyphRun* lastRun() const { return m_runs.back(); }
    uint32_t startGlyphIndex(const GlyphRun* run) const
    {
        switch (run->dir)
        {
            case TextDirection::ltr:
                return m_startLogical == run ? m_startGlyphIndex : 0;
            case TextDirection::rtl:
                return (m_endLogical == run ? m_endGlyphIndex : (uint32_t)run->glyphs.size()) - 1;
        }
        RIVE_UNREACHABLE();
    }
    uint32_t endGlyphIndex(const GlyphRun* run) const
    {
        switch (run->dir)
        {
            case TextDirection::ltr:
                return m_endLogical == run ? m_endGlyphIndex : (uint32_t)run->glyphs.size();
            case TextDirection::rtl:
                return (m_startLogical == run ? m_startGlyphIndex : 0) - 1;
        }
        RIVE_UNREACHABLE();
    }
};

class TextStyle;
class Text : public TextBase
{
public:
    void draw(Renderer* renderer) override;
    Core* hitTest(HitInfo*, const Mat2D&) override;
    void addRun(TextValueRun* run);
    void addModifierGroup(TextModifierGroup* group);
    void markShapeDirty();
    void modifierShapeDirty();
    void markPaintDirty();
    void update(ComponentDirt value) override;

    TextSizing sizing() const { return (TextSizing)sizingValue(); }
    TextOverflow overflow() const { return (TextOverflow)overflowValue(); }
    TextOrigin textOrigin() const { return (TextOrigin)originValue(); }
    void overflow(TextOverflow value) { return overflowValue((uint32_t)value); }
    void buildRenderStyles();
    const TextStyle* styleFromShaperId(uint16_t id) const;
    bool modifierRangesNeedShape() const;
    AABB localBounds() const override;
    void originXChanged() override;
    void originYChanged() override;
#ifdef WITH_RIVE_TEXT
    const std::vector<TextValueRun*>& runs() const { return m_runs; }
#endif

    bool haveModifiers() const
    {
#ifdef WITH_RIVE_TEXT
        return !m_modifierGroups.empty();
#else
        return false;
#endif
    }
#ifdef TESTING
    const std::vector<OrderedLine>& orderedLines() const { return m_orderedLines; }
    const std::vector<TextModifierGroup*>& modifierGroups() const { return m_modifierGroups; }
    const SimpleArray<Paragraph>& shape() const { return m_shape; }
    const std::vector<Unichar>& unichars() const { return m_styledText.unichars(); }
#endif

protected:
    void alignValueChanged() override;
    void sizingValueChanged() override;
    void overflowValueChanged() override;
    void widthChanged() override;
    void heightChanged() override;
    void paragraphSpacingChanged() override;
    bool makeStyled(StyledText& styledText, bool withModifiers = true) const;
    void originValueChanged() override;

private:
#ifdef WITH_RIVE_TEXT
    void updateOriginWorldTransform();
    std::vector<TextValueRun*> m_runs;
    std::vector<TextStyle*> m_renderStyles;
    SimpleArray<Paragraph> m_shape;
    SimpleArray<Paragraph> m_modifierShape;
    SimpleArray<SimpleArray<GlyphLine>> m_lines;
    SimpleArray<SimpleArray<GlyphLine>> m_modifierLines;
    // Runs ordered by paragraph line.
    std::vector<OrderedLine> m_orderedLines;
    GlyphRun m_ellipsisRun;
    std::unique_ptr<RenderPath> m_clipRenderPath;
    AABB m_bounds;
    std::vector<TextModifierGroup*> m_modifierGroups;

    StyledText m_styledText;
    StyledText m_modifierStyledText;

    GlyphLookup m_glyphLookup;
#endif
};
} // namespace rive

#endif