#include "rive/shapes/paint/paint_outset.hpp"

#include "rive/math/math_types.hpp"
#include "rive/shapes/paint/feather.hpp"
#include "rive/shapes/paint/shape_paint.hpp"
#include "rive/shapes/paint/stroke.hpp"
#include "rive/shapes/shape_paint_container.hpp"
#include "rive/transform_space.hpp"

#include <algorithm>
#include <cmath>

namespace rive
{

float paintBoundsOutset(
    const std::optional<StrokeParams>& stroke,
    float feather)
{
  float outset = 0.0f;
  if (stroke.has_value())
  {
    // A centered stroke straddles the path, reaching half its thickness.
    // The renderer draws an outside stroke as a centered stroke twice as
    // thick, clipped to the outside, so it reaches the full thickness (and
    // its miter twice as far). An inside one is clipped to the path and
    // reaches nothing past it; half is a safe over-estimate.
    outset = stroke->thickness *
             (stroke->position == StrokePosition::outside ? 1.0f : .5f);
    if (stroke->join == StrokeJoin::miter)
    {
      // Miter joins may be longer than the stroke radius.
      outset *= kMiterLimit;
    }
    else if (stroke->cap == StrokeCap::square)
    {
      // The diagonal of a square cap is longer than the stroke radius.
      outset *= math::SQRT2;
    }
  }
  if (feather != 0.0f)
  {
    outset += featherRadiusFromFeather(feather);
  }
  return outset;
}

ShapePaintOutset shapePaintOutset(const ShapePaint* paint)
{
  ShapePaintOutset out;
  // shouldDraw(), not isVisible(): a paint whose mutator is fully transparent
  // reaches nowhere, and Stroke::isVisible() additionally folds in
  // thickness > 0 so a zero-width stroke costs nothing here.
  if (paint == nullptr || !paint->shouldDraw())
  {
    return out;
  }

  std::optional<StrokeParams> stroke;
  if (paint->is<Stroke>())
  {
    const Stroke* s = paint->as<Stroke>();
    // Mirrors Stroke::applyTo, which is what the renderer actually sees,
    // position included: an outside stroke reaches twice as far.
    StrokeParams params;
    params.thickness = s->thickness();
    params.join = static_cast<StrokeJoin>(s->join());
    params.cap = static_cast<StrokeCap>(s->cap());
    params.position = s->strokePosition();
    stroke = params;
    // Stroke::pickPath: the local path when the transform affects the
    // stroke, the already-world path otherwise.
    out.pathIsLocal = s->transformAffectsStroke();
  }

  float feather = 0.0f;
  if (const Feather* f = paint->feather())
  {
    // inner() only ever moves the blur inward, so treating every feather as
    // outward keeps this an over-estimate -- the safe direction, since the
    // cost of over-estimating is a few wasted texels and the cost of
    // under-estimating is a visible crop.
    feather = f->strength();
    out.featherOffset = {f->offsetX(), f->offsetY()};
    out.featherOffsetInWorld = static_cast<TransformSpace>(f->spaceValue()) ==
                               TransformSpace::world;
  }

  out.outset = paintBoundsOutset(stroke, feather);
  out.trustworthy = !paint->hasEffects();
  return out;
}

PaintReach shapePaintsWorldReach(
    const ShapePaintContainer* container,
    const Mat2D& world)
{
  PaintReach reach;
  if (container == nullptr)
  {
    return reach;
  }
  const float worldScale = world.findMaxScale();
  for (const ShapePaint* paint : container->shapePaints())
  {
    const ShapePaintOutset po = shapePaintOutset(paint);
    reach.trustworthy = reach.trustworthy && po.trustworthy;

    // The outset is expressed in the space of the path the paint actually
    // draws, which pickPath decides. A local-path outset has to be pushed
    // through the shape's scale to mean anything against a world box; a
    // world-path one is already in world units.
    float distance = po.pathIsLocal ? po.outset * worldScale : po.outset;

    // A feather's offset is not symmetric, but padding per axis would have
    // to account for rotation redistributing an x offset into y. Its length
    // covers every orientation.
    Vec2D offset = po.featherOffset;
    if (!po.featherOffsetInWorld)
    {
      // A displacement, not a position: linear part only.
      offset = Vec2D::transformDir(offset, world);
    }
    distance += offset.length();

    if (std::isfinite(distance))
    {
      reach.worldOutset = std::max(reach.worldOutset, distance);
    }
  }
  return reach;
}

} // namespace rive
