#ifndef _RIVE_TEXT_CORE_HPP_
#define _RIVE_TEXT_CORE_HPP_
#include "rive/generated/text/text_base.hpp"
#include "rive/math/aabb.hpp"
#include "rive/text/text_value_run.hpp"
#include "rive/text_engine.hpp"
#include "rive/shapes/shape_paint_path.hpp"
#include "rive/simple_array.hpp"
#include "rive/text/glyph_lookup.hpp"
#include "rive/text/text_interface.hpp"
#include "rive/text/text_style_geometry.hpp"
#include "rive/text/text_style_on_demand.hpp"
#include "rive/data_bind/host_data_context_consumer.hpp"
#include "rive/advancing_component.hpp"
#include "rive/data_bind/data_bind_list_item_consumer.hpp"
#include "rive/viewmodel/symbol_type.hpp"
#include "rive/viewmodel/viewmodel_instance.hpp"
#include "rive/viewmodel/viewmodel_instance_value.hpp"
#include "rive/viewmodel/property_symbol_dependent.hpp"
#include "rive/dirtyable.hpp"
#include "rive/enums.hpp"

#include <functional>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>

namespace rive
{

class Factory;
class File;
class Renderer;
class StateMachineInstance;
class TextModifierGroup;
class TextStyleBackground;
class TextStylePaint;
class TextStyleReference;
class DataContext;
class ViewModelInstanceArtboard;
class LayoutParticipant;
class TextSelectionController;

// A draw command for interleaving monochrome style paths and color glyphs.
struct TextDrawCommand
{
  enum Type
  {
    kStylePath,
    kColorGlyph
  };
  Type type;
  TextStylePaint* style = nullptr; // for kStylePath
  // For a shared style's paint: this Text's glyphs (the paint holds none).
  TextStyleGeometry* geometry = nullptr;

  struct ColorGlyphInfo
  {
    rcp<Font> font;
    GlyphID glyphId;
    Mat2D transform;
    ColorInt foregroundColor;
    float opacity;
  };
  ColorGlyphInfo colorGlyph; // for kColorGlyph
};

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,
      float letterSpacing,
      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); }
};

struct TextBoundsInfo
{
  float minY;
  float maxWidth;
  float totalHeight;
  int ellipsisLine;
  bool isEllipsisLineLast;
  // Vertical trim removed from the top (ascent above the first line's cap- or
  // x-height) and bottom (descent below the last line's baseline / natural
  // descent). Both are zero when trim is disabled (TextTrimTop/Bottom::none).
  float topTrim;
  float bottomTrim;
};

enum class LineIter : uint8_t
{
  drawLine,
  skipThisLine,
  yOutOfBounds
};

class Text;

#ifdef WITH_RIVE_TEXT
class TextValueRunListener;

class TextValueRunProperty : public PropertySymbolDependentSingle
{
public:
  TextValueRunProperty(
      Core* textValueRun,
      TextValueRunListener* textValueRunListener,
      ViewModelInstanceValue* instanceValue,
      uint16_t propertyKey,
      SymbolType symbolType);

  void writeValue() override;

private:
  SymbolType m_symbolType = SymbolType::none;
};

class TextValueRunListener : public CoreObjectListener
{
public:
  TextValueRunListener(
      TextValueRun* textValueRun,
      rcp<ViewModelInstance> instance,
      Text* text);

  void markDirty() override;
  // Points the run at the style its item's style symbols resolve to.
  void resolveStyle();
  Text* text() { return m_text; }
  // The list item the run shows.
  const rcp<ViewModelInstance>& viewModelInstance() const { return m_instance; }
  TextValueRun* textValueRun()
  {
    if (m_core)
    {
      return m_core->as<TextValueRun>();
    }
    return nullptr;
  }

protected:
  void createProperties() override;

private:
  Text* m_text = nullptr;
  void createPropertyListener(SymbolType symbolType);
  TextValueRunProperty* createSinglePropertyListener(SymbolType symbolType);
};
#endif

struct ColorGlyphCacheKey
{
  const Font* font;
  GlyphID glyphId;
  bool operator==(const ColorGlyphCacheKey& o) const
  {
    return font == o.font && glyphId == o.glyphId;
  }
};

struct ColorGlyphCacheHash
{
  size_t operator()(const ColorGlyphCacheKey& k) const
  {
    size_t h = std::hash<const void*>()(k.font);
    h ^= std::hash<uint16_t>()(k.glyphId) + 0x9e3779b9 + (h << 6) + (h >> 2);
    return h;
  }
};

// Sweep gradients have no Rive shader and fall back to their first stop.
void drawColorGlyphLayer(
    Renderer* renderer,
    Factory* factory,
    Font::ColorGlyphLayer& layer,
    float opacity);

class Text : public TextBase,
             public TextInterface,
             public DataBindListItemConsumer,
             public AdvancingComponent,
             public HostDataContextConsumer
{
public:
#ifdef WITH_RIVE_EDITOR
  void editorPrepareForDestruction() override;
#endif
  // Implements TextInterface
  ~Text();
  void markShapeDirty() override;
  void markPaintDirty() override;
  void styleReferenceWillChange() override;
  void styleReferenceDidChange() override;

  // Advances the global text styles instanced on demand for list runs.
  bool advanceComponent(
      float elapsedSeconds,
      AdvanceFlags flags = AdvanceFlags::Animate |
                           AdvanceFlags::NewFrame) override;
  QuietState quietState() override;

  // Passes the hosting artboard's data context on to the global text styles
  // instanced on demand for list runs.
  void hostDataContext(rcp<DataContext> value) override;
  void relinkHostDataContext() override;
  void updateHostedDataBinds() override;

  void file(File* value) { m_file = value; }
  File* file() const { return m_file; }

  void draw(Renderer* renderer) override;
  Core* hitTest(HitInfo*, const Mat2D&) override;
  void addRun(TextValueRun* run);
  void addModifierGroup(TextModifierGroup* group);
#ifdef WITH_RIVE_EDITOR
  void addModifierGroupForEditor(TextModifierGroup* group);
  void removeModifierGroupForEditor(TextModifierGroup* group);
  /// Re-order `m_allRuns` (and `m_runs`) by the caller-supplied
  /// comparator. The runtime `.riv` import preserves sibling
  /// order via the exporter; coop hydration delivers cores in
  /// arrival order, so the editor needs to re-sort after batch
  /// finalize so concatenated text reads in FractionalIndex
  /// order ("100%", not "%100").
  void sortRunsForEditor(
      const std::function<bool(TextValueRun*, TextValueRun*)>& cmp);
#endif
  void markShapeDirty(bool sendToLayout);
  void modifierShapeDirty();

  void update(ComponentDirt value) override;
  void onDirty(ComponentDirt value) override;

  // Participates in a parent layout via an optional
  // LayoutParticipant child (origin-based; text sizes via its own layout).
  void composeWorldTransform() override;

protected:
  void updateConstraints() override;

public:
  Vec2D layoutBaseTranslation(LayoutParticipant* participant) const;
  LayoutParticipant* layoutParticipant() const;
  bool isParticipatingInLayout() const;

  Mat2D m_transform;
  Mat2D m_shapeWorldTransform;

  const Mat2D& shapeWorldTransform() const { return m_shapeWorldTransform; }
  TextSizing sizing() const { return (TextSizing)sizingValue(); }
  TextSizing effectiveSizing() const;
  TextOverflow overflow() const { return (TextOverflow)overflowValue(); }
  TextOrigin textOrigin() const { return (TextOrigin)originValue(); }
  TextTrimTop verticalTrimTop() const
  {
    return textTrimTop(verticalTrimValue());
  }
  TextTrimBottom verticalTrimBottom() const
  {
    return textTrimBottom(verticalTrimValue());
  }
  TextWrap wrap() const { return (TextWrap)wrapValue(); }
  TextWordBreak wordBreak() const { return (TextWordBreak)wordBreakValue(); }
  VerticalTextAlign verticalAlign() const
  {
    return (VerticalTextAlign)verticalAlignValue();
  }
  TextAlign align() const;
  void overflow(TextOverflow value) { return overflowValue((uint8_t)value); }
  void buildRenderStyles();
  const TextStylePaint* styleFromShaperId(uint16_t id) const;
  bool modifierRangesNeedShape() const;
  // localBounds() is the LAYOUT box, not the ink. Glyphs escape it through
  // negative side bearings, italic overhang, TextOverflow::visible,
  // TextModifierGroup transforms, and per-TextStyle strokes and feathers. It
  // is the right neighbourhood but not a bound, so it is approximate -- a
  // caller sizing a surface must pad it.
  BoundsFidelity paintedWorldBounds(AABB* out) override;

  AABB localBounds() const override;
  AABB constraintBounds() const override { return localBounds(); }
  void originXChanged() override;
  void originYChanged() override;
  StatusCode import(ImportStack& importStack) override;
  Core* clone() const override;

  Vec2D measureLayout(
      float width,
      LayoutMeasureMode widthMode,
      float height,
      LayoutMeasureMode heightMode) override;
  void controlSize(
      Vec2D size,
      LayoutScaleType widthScaleType,
      LayoutScaleType heightScaleType,
      LayoutDirection direction) override;
  float effectiveWidth()
  {
    return std::isnan(m_layoutWidth) ? width() : m_layoutWidth;
  }
  float effectiveHeight()
  {
    return std::isnan(m_layoutHeight) ? height() : m_layoutHeight;
  }
  // Whether a fitFontSize text reports its fitted size to the layout. The
  // authored flag only takes effect for files built against that behavior:
  // older ones were laid out against the unshrunk box and would reflow.
  // See Text::import and File::minorVersion.
  bool fitFontSizeResizesBoxActive() const
  {
    return fitFontSizeResizesBox() &&
           hasFileFeature(FileFeatures::fitFontSizeResizesBox);
  }
  // Whether a layout owns our WIDTH axis, asked of the participant rather
  // than of m_layoutWidth: that is only written by controlSize, which runs
  // after the solve, so during the measure pass it is still NAN. A boxed
  // width means the authored width() is not our width -- the layout's offer
  // is.
  bool layoutOwnsWidth() const;
  // Overflow treats the box as fixed once a layout sizes our box.
  bool overflowAsFixed() const
  {
    return effectiveSizing() == TextSizing::fixed ||
           !std::isnan(layoutBoxWidth());
  }
  // The size a controlling layout imposes on our *box*, or NAN when it
  // imposes none. Not the same as effectiveWidth/Height above, which use
  // m_layoutWidth/Height whenever a layout controls us: before 7.3 the
  // layout sized the text but an auto-sized box still came from the
  // content, so these are NAN there. See Text::import.
  float layoutBoxWidth() const
  {
    return hasFileFeature(FileFeatures::layoutSizesBox) ? m_layoutWidth : NAN;
  }
  float layoutBoxHeight() const
  {
    return hasFileFeature(FileFeatures::layoutSizesBox) ? m_layoutHeight : NAN;
  }
  float computedWidth() override { return localBounds().width(); };
  float computedHeight() override { return localBounds().height(); };
  void updateList(std::vector<rcp<ViewModelInstanceListItem>>* list) override;
#ifdef WITH_RIVE_TEXT
  const std::vector<TextValueRun*>& runs() const { return m_allRuns; }
  /// Breaks paragraphs into lines and aligns them. Lines are aligned within
  /// the larger of the natural paragraph width and minAlignWidth, so a
  /// caller that wants text aligned within a field wider than the text
  /// (see RawTextInput::alignWidth) gets that, while text overflowing the
  /// field falls back to starting at 0.
  static SimpleArray<SimpleArray<GlyphLine>> BreakLines(
      const SimpleArray<Paragraph>& paragraphs,
      float width,
      TextAlign align,
      TextWrap wrap,
      TextWordBreak wordBreak = TextWordBreak::breakWord,
      float minAlignWidth = 0.0f);
  const std::vector<TextStylePaint*>& textStylePaints()
  {
    return m_textStylePaints;
  }
  /// The style a list-driven run's item resolves to: its globalTextStyle
  /// (a handle showing that style, else one instanced on demand), else its
  /// textStyle name, else the first style. Null when the item has neither
  /// style symbol.
  TextStyleReference* resolveListRunStyle(ViewModelInstance* instance);
  /// The style a run whose styleId is data bound to [value] draws: the one a
  /// list run naming that style would (a handle showing it, else one
  /// instanced on demand), except that a style with a state machine gets an
  /// instance of its own per bound run. Null when [value] names no text
  /// style.
  TextStyleReference* boundRunStyle(
      ViewModelInstanceArtboard* value,
      const TextValueRun* run);
  /// A run now draws another style: drops the on-demand styles no run draws
  /// any more and re-shapes.
  void runStyleChanged();
  /// Whether a run of this Text may use a style that listens to its runs
  /// (see TextStyleShareInfo::listensToRuns), so the state machines of
  /// this Text's artboard forward pointers to those styles' state machines.
  bool mayHaveListeningRuns();
  /// Appends to [out] the state machines of this Text's styles that listen
  /// to the runs drawn with them (see TextStyleReference::runStateMachine).
  void runStateMachines(std::vector<StateMachineInstance*>& out);
#ifdef TESTING
  size_t onDemandStyleCount() const { return m_onDemandStyles.size(); }
#endif
#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 wordBreakValueChanged() override;
  void widthChanged() override;
  void heightChanged() override;
  void paragraphSpacingChanged() override;
  bool makeStyled(
      StyledText& styledText,
      bool withModifiers = true,
      float fontScale = 1.0f) const;
  void originValueChanged() override;
  void verticalTrimValueChanged() override;
  void fitFontSizeResizesBoxChanged() override;

private:
#ifdef WITH_RIVE_TEXT
  friend class TextSelectionController;
  TextSelectionController* m_selectionController = nullptr;
  void updateOriginWorldTransform();
  std::vector<TextValueRun*> m_runs;
  std::vector<TextValueRun*> m_allRuns;
  std::vector<TextStylePaint*> m_renderStyles;
  std::vector<TextDrawCommand> m_drawCommands;
  // This Text's glyphs for each shared global style paint it draws (the
  // paint itself holds none, see TextStylePaint::isShared).
  std::vector<std::pair<TextStylePaint*, std::unique_ptr<TextStyleGeometry>>>
      m_sharedGeometry;
  TextStyleGeometry& sharedGeometry(TextStylePaint* paint);
  // Backgrounds of global styles' paints this Text used in its last build.
  std::vector<TextStyleBackground*> m_globalBackgrounds;
  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;
  RawPath m_clipRect;
  ShapePaintPath m_clipPath;
  AABB m_bounds;
  // The font-size multiplier chosen by the last fitFontSize layout. Per-run
  // values are baked into the shaped runs by makeStyled; paragraph spacing is
  // a Text-level gap added between paragraphs during layout, so it is scaled
  // by this to keep the fitted layout a true uniform scale of the authored
  // one. Only meaningful while fitFontSize is the active overflow -- read it
  // through fitParagraphSpacing(), never directly, so a stale value from a
  // previous fit can't leak into a paint-only rebuild.
  float m_fitFontScale = 1.0f;
  std::vector<TextModifierGroup*> m_modifierGroups;

  StyledText m_styledText;
  StyledText m_modifierStyledText;
  GlyphLookup m_glyphLookup;
  std::vector<TextStylePaint*> m_textStylePaints;

  void clearRenderStyles();
  void drawColorGlyph(
      Renderer* renderer,
      const TextDrawCommand::ColorGlyphInfo& info,
      const Mat2D& worldTransform);
  std::unordered_map<ColorGlyphCacheKey, rcp<RenderImage>, ColorGlyphCacheHash>
      m_emojiImageCache;
  float fitParagraphSpacing() const
  {
    return overflow() == TextOverflow::fitFontSize
               ? paragraphSpacing() * m_fitFontScale
               : paragraphSpacing();
  }
  TextBoundsInfo computeBoundsInfo();
  // For TextOverflow::fitFontSize: binary-searches the largest integer font
  // size that fits the bounds and returns it as a multiplier of the authored
  // font size(s). Returns 1.0f when no fitting is needed/possible.
  float fitFontScale();
  // Same search, against an explicit box. Used by measure(), where the box
  // Yoga is offering is not yet reflected in m_layoutWidth/Height.
  float fitFontScale(float boxWidth, float boxHeight);
  LineIter shouldDrawLine(float y, float totalHeight, const GlyphLine& line);
  void buildTextStylePaints();
  std::vector<TextValueRunListener*> m_valueRunListeners;
  // Global text styles instanced on demand for list runs, one per style
  // (and item-supplied view model instance), shared by this Text's runs.
  std::vector<std::unique_ptr<TextStyleOnDemand>> m_onDemandStyles;
  // Runs may have started using a style that listens to its runs (see
  // markListenedRuns); set whenever the shape is dirtied.
  bool m_listenedRunsDirty = true;
  /// Makes every run drawn with a style that listens to its runs a hit
  /// target, so the style's state machine can hit-test it.
  void markListenedRuns();
  // A style may now be drawn for one list run alone, or no longer (see
  // syncStyleListItems); set whenever the shape is dirtied.
  bool m_listItemsDirty = true;
  /// Gives each global style drawn for one list run alone that run's list
  /// item, so the style reads it (see TextStyleInstance::listItem). A style
  /// several runs share gets none.
  void syncStyleListItems();
  /// The style a list run showing [item] draws when its item names the
  /// style [value] holds (see resolveListRunStyle).
  TextStyleReference* globalStyleReference(
      ViewModelInstanceArtboard* value,
      ViewModelInstance* item,
      const TextValueRun* owner = nullptr);
  TextStyleReference* styleReferenceNamed(const std::string& name);
  TextStyleReference* firstStyleReference();
  void resolveListRunStyles();
  void pruneOnDemandStyles();

  // What measure() last reported to the layout and what update() last
  // shaped, as measureKey hashes. Equal means the layout has already sized
  // the text as it is now shaped, so rebuilding it owes the layout nothing.
  // They start unequal: a text the layout never measured keeps notifying it.
  uint64_t m_measuredKey = 0;
  uint64_t m_shapedKey = 1;
  uint64_t measureKey(const StyledText& styled, float fontScale) const;

#endif
  File* m_file = nullptr;
  float m_layoutWidth = NAN;
  float m_layoutHeight = NAN;
  uint8_t m_layoutWidthScaleType = std::numeric_limits<uint8_t>::max();
  uint8_t m_layoutHeightScaleType = std::numeric_limits<uint8_t>::max();
  LayoutDirection m_layoutDirection = LayoutDirection::inherit;
  // Behaviors the file's version opts into, stamped in Text::import from
  // the header. Each one guards a change that would relayout content
  // authored before it, so a file predating the change keeps the old
  // behavior; anything built in memory is current and gets them all.
  //
  // One mask rather than a bool apiece because they are all the same shape
  // -- stamp at import, carry through clone, read at a single call site --
  // so the next gate costs a bit instead of a member plus its plumbing.
  // See File::minorVersion for what each version changed.
  enum class FileFeatures : uint8_t
  {
    none = 0,
    // 7.3: a controlling layout sizes our box, not just our text. Below
    // this an auto-sized text still took its box from the content, so the
    // box could disagree with the slot and every overflow mode was inert.
    layoutSizesBox = 1 << 0,
    // 7.4: Text::fitFontSizeResizesBox is honored, so a fitFontSize text
    // reports its *fitted* size to the layout instead of reserving room
    // at the authored font size.
    fitFontSizeResizesBox = 1 << 1,
    all = layoutSizesBox | fitFontSizeResizesBox,
  };
  FileFeatures m_fileFeatures = FileFeatures::all;
  bool hasFileFeature(FileFeatures feature) const
  {
    return enums::is_flag_set(m_fileFeatures, feature);
  }
  Vec2D measure(Vec2D maxSize);
};
} // namespace rive

#endif
