#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);
    }

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

    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;
    }
    AABB outset(float dx, float dy) const { return inset(-dx, -dy); }
    AABB offset(float dx, float dy) const
    {
        return {minX + dx, minY + dy, maxX + dx, maxY + dy};
    }

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

    ///
    /// 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
