#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
