#ifndef _RIVE_AABB_HPP_
#define _RIVE_AABB_HPP_

#include "rive/span.hpp"
#include "rive/math/vec2d.hpp"
#include "rive/math/math_types.hpp"
#include <limits>

namespace rive
{
template <typename T> struct TAABB
{
    T left, top, right, bottom;

    constexpr T width() const { return right - left; }
    constexpr T height() const { return bottom - top; }
    constexpr bool empty() const { return left >= right || top >= bottom; }

    // Create the largest-possible AABB for this type whose intersection with
    // any other rectangle will be equal to that same rectangle.
    static constexpr TAABB makeMaximal()
    {
        return {
            std::numeric_limits<T>::min(),
            std::numeric_limits<T>::min(),
            std::numeric_limits<T>::max(),
            std::numeric_limits<T>::max(),
        };
    }

    // Create a maximally negative AABB for this type whose union with any other
    // rectangle will be equal to that same rectangle.
    static constexpr TAABB makeMaximallyNegative()
    {
        return {
            std::numeric_limits<T>::max(),
            std::numeric_limits<T>::max(),
            std::numeric_limits<T>::min(),
            std::numeric_limits<T>::min(),
        };
    }

    TAABB inset(T dx, T dy) const
    {
        return {T(left + dx), T(top + dy), T(right - dx), T(bottom - dy)};
    }
    TAABB outset(T dx, T dy) const { return inset(-dx, -dy); }
    TAABB offset(T dx, T dy) const
    {
        return {T(left + dx), T(top + dy), T(right + dx), T(bottom + dy)};
    }
    TAABB join(TAABB b) const
    {
        return {std::min(left, b.left),
                std::min(top, b.top),
                std::max(right, b.right),
                std::max(bottom, b.bottom)};
    }

    template <typename U> TAABB intersect(TAABB<U> b) const
    {
        return {std::max(left, math::clamp_cast<T>(b.left)),
                std::max(top, math::clamp_cast<T>(b.top)),
                std::min(right, math::clamp_cast<T>(b.right)),
                std::min(bottom, math::clamp_cast<T>(b.bottom))};
    }

    // Do an intersection, but return a consistent, fully-zero rectangle if the
    // intersection ends up empty or negative.
    template <typename U> TAABB intersectOrEmpty(TAABB<U> b) const
    {
        auto r = intersect(b);
        return r.empty() ? TAABB{} : r;
    }

    template <typename U> TAABB<U> lossless_numeric_cast() const
    {
        return {
            math::lossless_numeric_cast<U>(left),
            math::lossless_numeric_cast<U>(top),
            math::lossless_numeric_cast<U>(right),
            math::lossless_numeric_cast<U>(bottom),
        };
    }

    template <typename U> TAABB<U> clamp_cast() const
    {
        return {
            math::clamp_cast<U>(left),
            math::clamp_cast<U>(top),
            math::clamp_cast<U>(right),
            math::clamp_cast<U>(bottom),
        };
    }
    bool operator==(const TAABB& o) const
    {
        return left == o.left && top == o.top && right == o.right &&
               bottom == o.bottom;
    }
    bool operator!=(const TAABB& o) const { return !(*this == o); }

    template <typename U> bool operator==(const TAABB<U>& o) const
    {
        return math::cmp_equal(left, o.left) &&
               math::cmp_equal(right, o.right) && math::cmp_equal(top, o.top) &&
               math::cmp_equal(bottom, o.bottom);
    }

    template <typename U> bool operator!=(const TAABB<U>& o) const
    {
        return !(*this == o);
    }

    template <typename U> bool contains(const TAABB<U>& rhs) const
    {
        return math::cmp_less_equal(left, rhs.left) &&
               math::cmp_less_equal(top, rhs.top) &&
               math::cmp_greater_equal(right, rhs.right) &&
               math::cmp_greater_equal(bottom, rhs.bottom);
    }

    template <typename U> bool overlaps(const TAABB<U>& b) const
    {
        return math::cmp_less(left, b.right) &&
               math::cmp_greater(right, b.left) &&
               math::cmp_less(top, b.bottom) &&
               math::cmp_greater(bottom, b.top);
    }

    template <typename U> static TAABB MakeWH(U width, U height)
    {
        return {0,
                0,
                math::lossless_numeric_cast<T>(width),
                math::lossless_numeric_cast<T>(height)};
    }
};

using IAABB = TAABB<int32_t>;
using AABBi16 = TAABB<int16_t>;
using AABBu16 = TAABB<uint16_t>;

class AABB
{
public:
    float minX, minY, maxX, maxY;

    AABB() : minX(0), minY(0), maxX(0), maxY(0) {}
    AABB(const Vec2D& min, const Vec2D& max) :
        minX(min.x), minY(min.y), maxX(max.x), maxY(max.y)
    {}
    static AABB fromLTWH(float x, float y, float width, float height)
    {
        return {x, y, x + width, y + height};
    }

    AABB(float minX, float minY, float maxX, float maxY) :
        minX(minX), minY(minY), maxX(maxX), maxY(maxY)
    {}

    AABB(const IAABB& o) :
        AABB((float)o.left, (float)o.top, (float)o.right, (float)o.bottom)
    {}

    AABB(Span<Vec2D>); // computes the union of all points, or 0,0,0,0

    bool operator==(const AABB& o) const
    {
        return minX == o.minX && minY == o.minY && maxX == o.maxX &&
               maxY == o.maxY;
    }
    bool operator!=(const AABB& o) const { return !(*this == o); }

    inline float left() const { return minX; }
    inline float top() const { return minY; }
    inline float right() const { return maxX; }
    inline float bottom() const { return maxY; }

    Vec2D min() const { return Vec2D(minX, minY); }
    Vec2D max() const { return Vec2D(maxX, maxY); }
    float width() const { return maxX - minX; }
    float height() const { return maxY - minY; }
    Vec2D size() const { return {width(), height()}; }
    Vec2D center() const
    {
        return {(minX + maxX) * 0.5f, (minY + maxY) * 0.5f};
    }

    bool isEmptyOrNaN() const
    {
        // Use "inverse" logic so we return true if either of the comparisons
        // fail due to a NaN.
        return !(width() > 0 && height() > 0);
    }

    [[nodiscard]] AABB pad(float amount) const
    {
        return outset(amount, amount);
    }

    [[nodiscard]] AABB inset(float dx, float dy) const
    {
        AABB r = {minX + dx, minY + dy, maxX - dx, maxY - dy};
        assert(r.width() >= 0);
        assert(r.height() >= 0);
        return r;
    }
    [[nodiscard]] AABB outset(float dx, float dy) const
    {
        return inset(-dx, -dy);
    }
    [[nodiscard]] AABB offset(float dx, float dy) const
    {
        return {minX + dx, minY + dy, maxX + dx, maxY + dy};
    }

    [[nodiscard]] IAABB round() const;

    // Rounds out to integer bounds that fully contain the rectangle.
    [[nodiscard]] IAABB roundOut() const;

    ///
    /// Initialize an AABB to values that represent an invalid/collapsed
    /// AABB that can then expand to points that are added to it.
    ///
    inline static AABB forExpansion()
    {
        return AABB(std::numeric_limits<float>::max(),
                    std::numeric_limits<float>::max(),
                    -std::numeric_limits<float>::max(),
                    -std::numeric_limits<float>::max());
    }

    ///
    /// Grow the AABB to fit the point.
    ///
    static void expandTo(AABB& out, const Vec2D& point);
    static void expandTo(AABB& out, float x, float y);

    /// Join two AABBs.
    static void join(AABB& out, const AABB& a, const AABB& b);

    void expand(const AABB& other) { join(*this, *this, other); }

    Vec2D factorFrom(Vec2D point) const
    {
        return Vec2D(
            width() == 0.0f ? 0.0f : (point.x - left()) * 2.0f / width() - 1.0f,
            (height() == 0.0f ? 0.0f : point.y - top()) * 2.0f / height() -
                1.0f);
    }

    bool contains(Vec2D position) const;

    bool overlaps(const AABB& b) const
    {
        return minX < b.maxX && maxX > b.minX && minY < b.maxY && maxX > b.minY;
    }

    Vec2D operator[](size_t index) const
    {
        switch (index)
        {
            case 0:
                return Vec2D(minX, minY);
            case 1:
                return Vec2D(maxX, maxY);
            default:
                RIVE_UNREACHABLE();
        }
    }
};

} // namespace rive
#endif
