// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#pragma once

#include <array>
#include <optional>
#include <ostream>
#include <vector>

#include "impeller/geometry/matrix.h"
#include "impeller/geometry/point.h"
#include "impeller/geometry/scalar.h"
#include "impeller/geometry/size.h"

namespace impeller {

template <class T>
struct TRect {
  using Type = T;

  /// DEPRECATED: Use |GetOrigin|
  TPoint<Type> origin;
  /// DEPRECATED: Use |GetSize|
  TSize<Type> size;

  constexpr TRect() : origin({0, 0}), size({0, 0}) {}

  constexpr static TRect MakeLTRB(Type left,
                                  Type top,
                                  Type right,
                                  Type bottom) {
    return TRect(left, top, right - left, bottom - top);
  }

  constexpr static TRect MakeXYWH(Type x, Type y, Type width, Type height) {
    return TRect(x, y, width, height);
  }

  constexpr static TRect MakeOriginSize(const TPoint<Type>& origin,
                                        const TSize<Type>& size) {
    return TRect(origin, size);
  }

  template <class U>
  constexpr static TRect MakeSize(const TSize<U>& size) {
    return TRect(0.0, 0.0, size.width, size.height);
  }

  template <typename U>
  constexpr static std::optional<TRect> MakePointBounds(const U& value) {
    return MakePointBounds(value.begin(), value.end());
  }

  template <typename PointIter>
  constexpr static std::optional<TRect> MakePointBounds(const PointIter first,
                                                        const PointIter last) {
    if (first == last) {
      return std::nullopt;
    }
    auto left = first->x;
    auto top = first->y;
    auto right = first->x;
    auto bottom = first->y;
    for (auto it = first + 1; it < last; ++it) {
      left = std::min(left, it->x);
      top = std::min(top, it->y);
      right = std::max(right, it->x);
      bottom = std::max(bottom, it->y);
    }
    return TRect::MakeLTRB(left, top, right, bottom);
  }

  constexpr static TRect MakeMaximum() {
    return TRect::MakeLTRB(-std::numeric_limits<Type>::infinity(),
                           -std::numeric_limits<Type>::infinity(),
                           std::numeric_limits<Type>::infinity(),
                           std::numeric_limits<Type>::infinity());
  }

  template <class U>
  constexpr explicit TRect(const TRect<U>& other)
      : origin(static_cast<TPoint<Type>>(other.origin)),
        size(static_cast<TSize<Type>>(other.size)) {}

  constexpr TRect operator+(const TRect& r) const {
    return TRect({origin.x + r.origin.x, origin.y + r.origin.y},
                 {size.width + r.size.width, size.height + r.size.height});
  }

  constexpr TRect operator-(const TRect& r) const {
    return TRect({origin.x - r.origin.x, origin.y - r.origin.y},
                 {size.width - r.size.width, size.height - r.size.height});
  }

  constexpr TRect operator*(Type scale) const { return Scale(scale); }

  constexpr TRect operator*(const TRect& r) const {
    return TRect({origin.x * r.origin.x, origin.y * r.origin.y},
                 {size.width * r.size.width, size.height * r.size.height});
  }

  constexpr bool operator==(const TRect& r) const {
    return origin == r.origin && size == r.size;
  }

  constexpr TRect Scale(Type scale) const {
    return TRect({origin.x * scale, origin.y * scale},
                 {size.width * scale, size.height * scale});
  }

  constexpr TRect Scale(TPoint<T> scale) const {
    return TRect({origin.x * scale.x, origin.y * scale.y},
                 {size.width * scale.x, size.height * scale.y});
  }

  constexpr TRect Scale(TSize<T> scale) const {
    return Scale(TPoint<T>(scale));
  }

  constexpr bool Contains(const TPoint<Type>& p) const {
    return p.x >= GetLeft() && p.x < GetRight() && p.y >= GetTop() &&
           p.y < GetBottom();
  }

  constexpr bool Contains(const TRect& o) const {
    return Union(o).size == size;
  }

  /// Returns true if either of the width or height are 0, negative, or NaN.
  constexpr bool IsEmpty() const { return size.IsEmpty(); }

  constexpr bool IsMaximum() const { return *this == MakeMaximum(); }

  /// @brief Returns the upper left corner of the rectangle as specified
  ///        when it was constructed.
  ///
  ///        Note that unlike the |GetLeft|, |GetTop|, and |GetLeftTop|
  ///        methods which will return values as if the rectangle had been
  ///        "unswapped" by calling |GetPositive| on it, this method
  ///        returns the raw origin values.
  constexpr TPoint<Type> GetOrigin() const { return origin; }

  /// @brief Returns the size of the rectangle as specified when it was
  ///        constructed and which may be negative in either width or
  ///        height.
  constexpr TSize<Type> GetSize() const { return size; }

  constexpr auto GetLeft() const {
    if (IsMaximum()) {
      return -std::numeric_limits<Type>::infinity();
    }
    return std::min(origin.x, origin.x + size.width);
  }

  constexpr auto GetTop() const {
    if (IsMaximum()) {
      return -std::numeric_limits<Type>::infinity();
    }
    return std::min(origin.y, origin.y + size.height);
  }

  constexpr auto GetRight() const {
    if (IsMaximum()) {
      return std::numeric_limits<Type>::infinity();
    }
    return std::max(origin.x, origin.x + size.width);
  }

  constexpr auto GetBottom() const {
    if (IsMaximum()) {
      return std::numeric_limits<Type>::infinity();
    }
    return std::max(origin.y, origin.y + size.height);
  }

  constexpr TPoint<T> GetLeftTop() const { return {GetLeft(), GetTop()}; }

  constexpr TPoint<T> GetRightTop() const { return {GetRight(), GetTop()}; }

  constexpr TPoint<T> GetLeftBottom() const { return {GetLeft(), GetBottom()}; }

  constexpr TPoint<T> GetRightBottom() const {
    return {GetRight(), GetBottom()};
  }

  constexpr std::array<T, 4> GetLTRB() const {
    return {GetLeft(), GetTop(), GetRight(), GetBottom()};
  }

  /// @brief  Get a version of this rectangle that has a non-negative size.
  constexpr TRect GetPositive() const {
    auto ltrb = GetLTRB();
    return MakeLTRB(ltrb[0], ltrb[1], ltrb[2], ltrb[3]);
  }

  /// @brief  Get the points that represent the 4 corners of this rectangle. The
  ///         order is: Top left, top right, bottom left, bottom right.
  constexpr std::array<TPoint<T>, 4> GetPoints() const {
    auto [left, top, right, bottom] = GetLTRB();
    return {TPoint(left, top), TPoint(right, top), TPoint(left, bottom),
            TPoint(right, bottom)};
  }

  constexpr std::array<TPoint<T>, 4> GetTransformedPoints(
      const Matrix& transform) const {
    auto points = GetPoints();
    for (size_t i = 0; i < points.size(); i++) {
      points[i] = transform * points[i];
    }
    return points;
  }

  /// @brief  Creates a new bounding box that contains this transformed
  ///         rectangle.
  constexpr TRect TransformBounds(const Matrix& transform) const {
    auto points = GetTransformedPoints(transform);
    return TRect::MakePointBounds(points.begin(), points.end()).value();
  }

  /// @brief  Constructs a Matrix that will map all points in the coordinate
  ///         space of the rectangle into a new normalized coordinate space
  ///         where the upper left corner of the rectangle maps to (0, 0)
  ///         and the lower right corner of the rectangle maps to (1, 1).
  ///
  ///         Empty and non-finite rectangles will return a zero-scaling
  ///         transform that maps all points to (0, 0).
  constexpr Matrix GetNormalizingTransform() const {
    if (!IsEmpty()) {
      Scalar sx = 1.0 / size.width;
      Scalar sy = 1.0 / size.height;
      Scalar tx = origin.x * -sx;
      Scalar ty = origin.y * -sy;

      // Exclude NaN and infinities and either scale underflowing to zero
      if (sx != 0.0 && sy != 0.0 && 0.0 * sx * sy * tx * ty == 0.0) {
        // clang-format off
        return Matrix(  sx, 0.0f, 0.0f, 0.0f,
                      0.0f,   sy, 0.0f, 0.0f,
                      0.0f, 0.0f, 1.0f, 0.0f,
                        tx,   ty, 0.0f, 1.0f);
        // clang-format on
      }
    }

    // Map all coordinates to the origin.
    return Matrix::MakeScale({0.0f, 0.0f, 1.0f});
  }

  constexpr TRect Union(const TRect& o) const {
    auto this_ltrb = GetLTRB();
    auto other_ltrb = o.GetLTRB();
    return TRect::MakeLTRB(std::min(this_ltrb[0], other_ltrb[0]),  //
                           std::min(this_ltrb[1], other_ltrb[1]),  //
                           std::max(this_ltrb[2], other_ltrb[2]),  //
                           std::max(this_ltrb[3], other_ltrb[3])   //
    );
  }

  constexpr std::optional<TRect<T>> Intersection(const TRect& o) const {
    auto this_ltrb = GetLTRB();
    auto other_ltrb = o.GetLTRB();
    auto intersection =
        TRect::MakeLTRB(std::max(this_ltrb[0], other_ltrb[0]),  //
                        std::max(this_ltrb[1], other_ltrb[1]),  //
                        std::min(this_ltrb[2], other_ltrb[2]),  //
                        std::min(this_ltrb[3], other_ltrb[3])   //
        );
    if (intersection.size.IsEmpty()) {
      return std::nullopt;
    }
    return intersection;
  }

  constexpr bool IntersectsWithRect(const TRect& o) const {
    return Intersection(o).has_value();
  }

  /// @brief Returns the new boundary rectangle that would result from the
  ///        rectangle being cutout by a second rectangle.
  constexpr std::optional<TRect<T>> Cutout(const TRect& o) const {
    const auto& [a_left, a_top, a_right, a_bottom] = GetLTRB();  // Source rect.
    const auto& [b_left, b_top, b_right, b_bottom] = o.GetLTRB();  // Cutout.
    if (b_left <= a_left && b_right >= a_right) {
      if (b_top <= a_top && b_bottom >= a_bottom) {
        // Full cutout.
        return std::nullopt;
      }
      if (b_top <= a_top && b_bottom > a_top) {
        // Cuts off the top.
        return TRect::MakeLTRB(a_left, b_bottom, a_right, a_bottom);
      }
      if (b_bottom >= a_bottom && b_top < a_bottom) {
        // Cuts out the bottom.
        return TRect::MakeLTRB(a_left, a_top, a_right, b_top);
      }
    }
    if (b_top <= a_top && b_bottom >= a_bottom) {
      if (b_left <= a_left && b_right > a_left) {
        // Cuts out the left.
        return TRect::MakeLTRB(b_right, a_top, a_right, a_bottom);
      }
      if (b_right >= a_right && b_left < a_right) {
        // Cuts out the right.
        return TRect::MakeLTRB(a_left, a_top, b_left, a_bottom);
      }
    }

    return *this;
  }

  /// @brief  Returns a new rectangle translated by the given offset.
  constexpr TRect<T> Shift(TPoint<T> offset) const {
    return TRect(origin.x + offset.x, origin.y + offset.y, size.width,
                 size.height);
  }

  /// @brief  Returns a rectangle with expanded edges. Negative expansion
  ///         results in shrinking.
  constexpr TRect<T> Expand(T left, T top, T right, T bottom) const {
    return TRect(origin.x - left,            //
                 origin.y - top,             //
                 size.width + left + right,  //
                 size.height + top + bottom);
  }

  /// @brief  Returns a rectangle with expanded edges in all directions.
  ///         Negative expansion results in shrinking.
  constexpr TRect<T> Expand(T amount) const {
    return TRect(origin.x - amount,        //
                 origin.y - amount,        //
                 size.width + amount * 2,  //
                 size.height + amount * 2);
  }

  /// @brief  Returns a rectangle with expanded edges in all directions.
  ///         Negative expansion results in shrinking.
  constexpr TRect<T> Expand(TPoint<T> amount) const {
    return TRect(origin.x - amount.x,        //
                 origin.y - amount.y,        //
                 size.width + amount.x * 2,  //
                 size.height + amount.y * 2);
  }

  /// @brief  Returns a new rectangle that represents the projection of the
  ///         source rectangle onto this rectangle. In other words, the source
  ///         rectangle is redefined in terms of the corrdinate space of this
  ///         rectangle.
  constexpr TRect<T> Project(TRect<T> source) const {
    return source.Shift(-origin).Scale(
        TSize<T>(1.0 / static_cast<Scalar>(size.width),
                 1.0 / static_cast<Scalar>(size.height)));
  }

  constexpr static TRect RoundOut(const TRect& r) {
    return TRect::MakeLTRB(floor(r.GetLeft()), floor(r.GetTop()),
                           ceil(r.GetRight()), ceil(r.GetBottom()));
  }

  constexpr static std::optional<TRect> Union(const TRect& a,
                                              const std::optional<TRect> b) {
    return b.has_value() ? a.Union(b.value()) : a;
  }

  constexpr static std::optional<TRect> Union(const std::optional<TRect> a,
                                              const TRect& b) {
    return Union(b, a);
  }

  constexpr static std::optional<TRect> Union(const std::optional<TRect> a,
                                              const std::optional<TRect> b) {
    return a.has_value() ? Union(a.value(), b) : b;
  }

  constexpr static std::optional<TRect> Intersection(
      const TRect& a,
      const std::optional<TRect> b) {
    return b.has_value() ? a.Intersection(b.value()) : a;
  }

  constexpr static std::optional<TRect> Intersection(
      const std::optional<TRect> a,
      const TRect& b) {
    return Intersection(b, a);
  }

  constexpr static std::optional<TRect> Intersection(
      const std::optional<TRect> a,
      const std::optional<TRect> b) {
    return a.has_value() ? Intersection(a.value(), b) : b;
  }

 private:
  constexpr TRect(Type x, Type y, Type width, Type height)
      : origin(x, y), size(width, height) {}

  constexpr TRect(TPoint<Type> origin, TSize<Type> size)
      : origin(origin), size(size) {}
};

using Rect = TRect<Scalar>;
using IRect = TRect<int64_t>;

}  // namespace impeller

namespace std {

template <class T>
inline std::ostream& operator<<(std::ostream& out,
                                const impeller::TRect<T>& r) {
  out << "(" << r.origin << ", " << r.size << ")";
  return out;
}

}  // namespace std
