#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())
    {
        outset = stroke->thickness * .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.
        // StrokePosition is deliberately not read: applyTo never sets it, so
        // the stroke really does straddle the path and thickness/2 is the
        // reach.
        StrokeParams params;
        params.thickness = s->thickness();
        params.join = static_cast<StrokeJoin>(s->join());
        params.cap = static_cast<StrokeCap>(s->cap());
        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
