#include "rive/text/text_style_paint.hpp"
#include "rive/text/text.hpp"
#include "rive/text/text_variation_helper.hpp"
#include "rive/shapes/paint/shape_paint.hpp"
#include "rive/shapes/paint/fill.hpp"
#include "rive/shapes/paint/solid_color.hpp"
#include "rive/shapes/paint/feather.hpp"
#include "rive/artboard.hpp"
#include "rive/factory.hpp"

using namespace rive;

TextStylePaint::TextStylePaint() {}

void TextStylePaint::rewindPath() { m_geometry.rewind(); }

bool TextStylePaint::addPath(
    const RawPath& rawPath,
    float opacity,
    const Mat2D* transform)
{
  return m_geometry.addPath(rawPath, opacity, transform);
}

void TextStylePaint::draw(Renderer* renderer, const Mat2D& worldTransform)
{
  drawGeometry(renderer, worldTransform, m_geometry, 1.0f);
}

void TextStylePaint::drawGeometry(
    Renderer* renderer,
    const Mat2D& worldTransform,
    TextStyleGeometry& geometry,
    float opacityModifier)
{
  // A paint shared by several Texts (opacityModifier carries the drawing
  // Text's opacity) never has its own render paints touched: every bucket,
  // the opaque one included, draws through the geometry's pooled paints.
  const bool owned = opacityModifier == 1.0f;
  auto& opacityPaths = geometry.opacityPaths();
  for (auto shapePaint : m_ShapePaints)
  {
    if (!shapePaint->shouldDraw())
    {
      continue;
    }
    // A global text style's paint lives under the style Artboard, not a
    // Text; keep its shape paint's own (default) blend mode in that case.
    if (owned && parent()->is<Text>())
    {
      auto text = parent()->as<Text>();
      shapePaint->blendMode(text->blendMode(), text->additiveAmount());
    }

    auto drawPooled =
        [&](ShapePaintPath* path, float opacity, uint32_t paintIndex) {
          RenderPaint* renderPaint = geometry.pooledPaint(paintIndex);
          shapePaint->applyTo(renderPaint, opacity * opacityModifier);
          // Pooled paints are shared across shape paints; always set
          // feather and blend mode so one paint's settings don't leak into
          // the others. Pooled draws take the shape paint's own mode (a
          // global style's paint has no Text to inherit from).
          auto feather = shapePaint->feather();
          renderPaint->feather(feather != nullptr ? feather->strength() : 0.0f);
          if (!owned)
          {
            BlendMode mode = shapePaint->inheritsBlendMode()
                                 ? BlendMode::srcOver
                                 : shapePaint->blendMode();
            renderPaint->blendMode(mode);
            renderPaint->additiveness(
                additivenessFor(mode, shapePaint->additiveAmount()));
          }
          shapePaint->draw(renderer, path, worldTransform, true, renderPaint);
        };

    // An effect (dash, trim...) is built from every glyph and replaces
    // whichever bucket's path ShapePaint::draw is handed, so drawing it per
    // bucket would stack the whole outline once per opacity. Draw it once,
    // at the highest opacity any glyph has. The effect's output can't be
    // traced back to glyphs, so fainter glyphs it keeps draw at that opacity
    // too.
    if (shapePaint->lastEffectPath(shapePaint) != nullptr)
    {
      if (opacityPaths.empty())
      {
        continue;
      }
      float opacity = opacityPaths.rbegin()->first;
      if (owned && opacity == 1.0f)
      {
        shapePaint->draw(renderer, geometry.path(), worldTransform, true);
      }
      else
      {
        geometry.reservePaints(artboard()->factory());
        drawPooled(geometry.path(), opacity, 0);
      }
      continue;
    }

    // For blend modes to work, opaque paths render first
    auto itr = opacityPaths.find(1.0f);
    if (owned && itr != opacityPaths.end())
    {
      ShapePaintPath& path = itr->second;
      shapePaint->draw(renderer, &path, worldTransform, true);
    }

    geometry.reservePaints(artboard()->factory());

    uint32_t paintIndex = 0;
    for (itr = opacityPaths.begin(); itr != opacityPaths.end(); itr++)
    {
      // Don't render opaque paths twice
      if (owned && itr->first == 1.0f)
      {
        continue;
      }
      drawPooled(&itr->second, itr->first, paintIndex++);
    }
  }
}

ColorInt TextStylePaint::foregroundColor() const
{
  for (auto shapePaint : m_ShapePaints)
  {
    if (shapePaint->is<Fill>() && shapePaint->paint()->is<SolidColor>())
    {
      return (ColorInt)shapePaint->paint()->as<SolidColor>()->colorValue();
    }
  }
  return 0xFF000000;
}

const Mat2D& TextStylePaint::shapeWorldTransform() const
{
  // Global text style paints are parented to the style Artboard; fall back to
  // the artboard's transform (only used for feather inner-path rebuilds).
  if (parent()->is<Text>())
  {
    return parent()->as<Text>()->shapeWorldTransform();
  }
  return artboard()->shapeWorldTransform();
}

Component* TextStylePaint::pathBuilder() { return parent(); }

Core* TextStylePaint::clone() const
{
  TextStylePaint* twin = TextStylePaintBase::clone()->as<TextStylePaint>();
  cloneFontInto(twin);
  return twin;
}
