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

#ifndef FLUTTER_IMPELLER_GEOMETRY_RECT_H_
#define FLUTTER_IMPELLER_GEOMETRY_RECT_H_

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

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

namespace impeller {

#define ONLY_ON_FLOAT_M(Modifiers, Return) \
  template <typename U = T>                \
  Modifiers std::enable_if_t<std::is_floating_point_v<U>, Return>
#define ONLY_ON_FLOAT(Return) DL_ONLY_ON_FLOAT_M(, Return)

/// Templated struct for holding an axis-aligned rectangle.
///
/// Rectangles are defined as 4 axis-aligned edges that might contain
/// space. They can be viewed as 2 X coordinates that define the
/// left and right edges and 2 Y coordinates that define the top and
/// bottom edges; or they can be viewed as an origin and horizontal
/// and vertical dimensions (width and height).
///
/// When the left and right edges are equal or reversed (right <= left)
/// or the top and bottom edges are equal or reversed (bottom <= top),
/// the rectangle is considered empty. Considering the rectangle in XYWH
/// form, the width and/or the height would be negative or zero. Such
/// reversed/empty rectangles contain no space and act as such in the
/// methods that operate on them (Intersection, Union, IntersectsWithRect,
/// Contains, Cutout, etc.)
///
/// Rectangles cannot be modified by any method and a new value can only
/// be stored into an existing rect using assignment. This keeps the API
/// clean compared to implementations that might have similar methods
/// that produce the answer in place, or construct a new object with
/// the answer, or place the result in an indicated result object.
///
/// Methods that might fail to produce an answer will use |std::optional|
/// to indicate that success or failure (see |Intersection| and |CutOut|).
/// For convenience, |Intersection| and |Union| both have overloaded
/// variants that take |std::optional| arguments and treat them as if
/// the argument was an empty rect to allow chaining multiple such methods
/// and only needing to check the optional condition of the final result.
/// The primary methods also provide |...OrEmpty| overloaded variants that
/// translate an empty optional answer into a simple empty rectangle of the
/// same type.
///
/// Rounding instance methods are not provided as the return value might
/// be wanted as another floating point rectangle or sometimes as an integer
/// rectangle. Instead a |RoundOut| factory, defined only for floating point
/// input rectangles, is provided to provide control over the result type.
///
/// NaN and Infinity values
///
/// Constructing an LTRB rectangle using Infinity values should work as
/// expected with either 0 or +Infinity returned as dimensions depending on
/// which side the Infinity values are on and the sign.
///
/// Constructing an XYWH rectangle using Infinity values will usually
/// not work if the math requires the object to compute a right or bottom
/// edge from ([xy] -Infinity + [wh] +Infinity). Other combinations might
/// work.
///
/// The special factory |MakeMaximum| is provided to construct a rectangle
/// of the indicated coordinate type that covers all finite coordinates.
/// It does not use infinity values, but rather the largest finite values
/// to avoid math that might produce a NaN value from various getters.
///
/// Any rectangle that is constructed with, or computed to have a NaN value
/// will be considered the same as any empty rectangle.
///
/// Empty Rectangle canonical results summary:
///
/// Union will ignore any empty rects and return the other rect
/// Intersection will return nullopt if either rect is empty
/// IntersectsWithRect will return false if either rect is empty
/// Cutout will return the source rect if the argument is empty
/// Cutout will return nullopt if the source rectangle is empty
/// Contains(Point) will return false if the source rectangle is empty
/// Contains(Rect) will return false if the source rectangle is empty
/// Contains(Rect) will otherwise return true if the argument is empty
/// Specifically, EmptyRect.Contains(EmptyRect) returns false
///
/// ---------------
/// Special notes on problems using the XYWH form of specifying rectangles:
///
/// It is possible to have integer rectangles whose dimensions exceed
/// the maximum number that their coordinates can represent since
/// (MAX_INT - MIN_INT) overflows the representable positive numbers.
/// Floating point rectangles technically have a similar issue in that
/// overflow can occur, but it will be automatically converted into
/// either an infinity, or a finite-overflow value and still be
/// representable, just with little to no precision.
///
/// Secondly, specifying a rectangle using XYWH leads to cases where the
/// math for (x+w) and/or (y+h) are also beyond the maximum representable
/// coordinates. For N-bit integer rectangles declared as XYWH, the
/// maximum right coordinate will require N+1 signed bits which cannot be
/// stored in storage that uses N-bit integers.
///
/// Saturated math is used when constructing a rectangle from XYWH values
/// and when returning the dimensions of the rectangle. Constructing an
/// integer rectangle from values such that xy + wh is beyond the range
/// of the integer type will place the right or bottom edges at the maximum
/// value for the integer type. Similarly, constructing an integer rectangle
/// such that the distance from the left to the right (or top to bottom) is
/// greater than the range of the integer type will simply return the
/// maximum integer value as the dimension. Floating point rectangles are
/// naturally saturated by the rules of IEEE arithmetic.
template <class T>
struct TRect {
 private:
  using Type = T;

 public:
  constexpr TRect() : left_(0), top_(0), right_(0), bottom_(0) {}

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

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

  constexpr static TRect MakeOriginSize(const TPoint<Type>& origin,
                                        const TSize<Type>& size) {
    return MakeXYWH(origin.x, origin.y, size.width, size.height);
  }

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

  [[nodiscard]] constexpr static TRect MakeMaximum() {
    return TRect::MakeLTRB(std::numeric_limits<Type>::lowest(),
                           std::numeric_limits<Type>::lowest(),
                           std::numeric_limits<Type>::max(),
                           std::numeric_limits<Type>::max());
  }

  [[nodiscard]] constexpr bool operator==(const TRect& r) const {
    return left_ == r.left_ &&    //
           top_ == r.top_ &&      //
           right_ == r.right_ &&  //
           bottom_ == r.bottom_;
  }

  [[nodiscard]] constexpr bool operator!=(const TRect& r) const {
    return !(*this == r);
  }

  [[nodiscard]] constexpr TRect Scale(Type scale) const {
    return TRect(left_ * scale,   //
                 top_ * scale,    //
                 right_ * scale,  //
                 bottom_ * scale);
  }

  [[nodiscard]] constexpr TRect Scale(Type scale_x, Type scale_y) const {
    return TRect(left_ * scale_x,   //
                 top_ * scale_y,    //
                 right_ * scale_x,  //
                 bottom_ * scale_y);
  }

  [[nodiscard]] constexpr TRect Scale(TPoint<T> scale) const {
    return Scale(scale.x, scale.y);
  }

  [[nodiscard]] constexpr TRect Scale(TSize<T> scale) const {
    return Scale(scale.width, scale.height);
  }

  /// @brief  Returns true iff the provided point |p| is inside the
  ///         half-open interior of this rectangle.
  ///
  ///         For purposes of containment, a rectangle contains points
  ///         along the top and left edges but not points along the
  ///         right and bottom edges so that a point is only ever
  ///         considered inside one of two abutting rectangles.
  [[nodiscard]] constexpr bool Contains(const TPoint<Type>& p) const {
    return !this->IsEmpty() &&  //
           p.x >= left_ &&      //
           p.y >= top_ &&       //
           p.x < right_ &&      //
           p.y < bottom_;
  }

  /// @brief  Returns true iff the provided point |p| is inside the
  ///         closed-range interior of this rectangle.
  ///
  ///         Unlike the regular |Contains(TPoint)| method, this method
  ///         considers all points along the boundary of the rectangle
  ///         to be contained within the rectangle - useful for testing
  ///         if vertices that define a filled shape would carry the
  ///         interior of that shape outside the bounds of the rectangle.
  ///         Since both geometries are defining half-open spaces, their
  ///         defining geometry needs to consider their boundaries to
  ///         be equivalent with respect to interior and exterior.
  [[nodiscard]] constexpr bool ContainsInclusive(const TPoint<Type>& p) const {
    return !this->IsEmpty() &&  //
           p.x >= left_ &&      //
           p.y >= top_ &&       //
           p.x <= right_ &&     //
           p.y <= bottom_;
  }

  /// @brief  Returns true iff this rectangle is not empty and it also
  ///         contains every point considered inside the provided
  ///         rectangle |o| (as determined by |Contains(TPoint)|).
  ///
  ///         This is similar to a definition where the result is true iff
  ///         the union of the two rectangles is equal to this rectangle,
  ///         ignoring precision issues with performing those operations
  ///         and assuming that empty rectangles are never equal.
  ///
  ///         An empty rectangle can contain no other rectangle.
  ///
  ///         An empty rectangle is, however, contained within any
  ///         other non-empy rectangle as the set of points it contains
  ///         is an empty set and so there are no points to fail the
  ///         containment criteria.
  [[nodiscard]] constexpr bool Contains(const TRect& o) const {
    return !this->IsEmpty() &&                     //
           (o.IsEmpty() || (o.left_ >= left_ &&    //
                            o.top_ >= top_ &&      //
                            o.right_ <= right_ &&  //
                            o.bottom_ <= bottom_));
  }

  /// @brief  Returns true if all of the fields of this floating point
  ///         rectangle are finite.
  ///
  ///         Note that the results of |GetWidth()| and |GetHeight()| may
  ///         still be infinite due to overflow even if the fields themselves
  ///         are finite.
  ONLY_ON_FLOAT_M([[nodiscard]] constexpr, bool)
  IsFinite() const {
    return std::isfinite(left_) &&   //
           std::isfinite(top_) &&    //
           std::isfinite(right_) &&  //
           std::isfinite(bottom_);
  }

  /// @brief  Returns true if either of the width or height are 0, negative,
  ///         or NaN.
  [[nodiscard]] constexpr bool IsEmpty() const {
    // Computing the non-empty condition and negating the result causes any
    // NaN value to return true - i.e. is considered empty.
    return !(left_ < right_ && top_ < bottom_);
  }

  /// @brief  Returns true if width and height are equal and neither is NaN.
  [[nodiscard]] constexpr bool IsSquare() const {
    // empty rectangles can technically be "square", but would be
    // misleading to most callers. Using |IsEmpty| also prevents
    // "non-empty and non-overflowing" computations from happening
    // to be equal to "empty and overflowing" results.
    // (Consider LTRB(10, 15, MAX-2, MIN+2) which is empty, but both
    //  w/h subtractions equal "5").
    return !IsEmpty() && (right_ - left_) == (bottom_ - top_);
  }

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

  /// @brief Returns the upper left corner of the rectangle as specified
  ///        by the left/top or x/y values when it was constructed.
  [[nodiscard]] constexpr TPoint<Type> GetOrigin() const {
    return {left_, top_};
  }

  /// @brief Returns the size of the rectangle which may be negative in
  ///        either width or height and may have been clipped to the
  ///        maximum integer values for integer rects whose size overflows.
  [[nodiscard]] constexpr TSize<Type> GetSize() const {
    return {GetWidth(), GetHeight()};
  }

  /// @brief Returns the X coordinate of the upper left corner, equivalent
  ///        to |GetOrigin().x|
  [[nodiscard]] constexpr Type GetX() const { return left_; }

  /// @brief Returns the Y coordinate of the upper left corner, equivalent
  ///        to |GetOrigin().y|
  [[nodiscard]] constexpr Type GetY() const { return top_; }

  /// @brief Returns the width of the rectangle, equivalent to
  ///        |GetSize().width|
  [[nodiscard]] constexpr Type GetWidth() const {
    return saturated::Sub(right_, left_);
  }

  /// @brief Returns the height of the rectangle, equivalent to
  ///        |GetSize().height|
  [[nodiscard]] constexpr Type GetHeight() const {
    return saturated::Sub(bottom_, top_);
  }

  [[nodiscard]] constexpr auto GetLeft() const { return left_; }

  [[nodiscard]] constexpr auto GetTop() const { return top_; }

  [[nodiscard]] constexpr auto GetRight() const { return right_; }

  [[nodiscard]] constexpr auto GetBottom() const { return bottom_; }

  [[nodiscard]] constexpr TPoint<T> GetLeftTop() const {  //
    return {left_, top_};
  }

  [[nodiscard]] constexpr TPoint<T> GetRightTop() const {
    return {right_, top_};
  }

  [[nodiscard]] constexpr TPoint<T> GetLeftBottom() const {
    return {left_, bottom_};
  }

  [[nodiscard]] constexpr TPoint<T> GetRightBottom() const {
    return {right_, bottom_};
  }

  /// @brief  Get the area of the rectangle, equivalent to |GetSize().Area()|
  [[nodiscard]] constexpr T Area() const {
    // TODO(141710): Use saturated math to avoid overflow.
    return IsEmpty() ? 0 : (right_ - left_) * (bottom_ - top_);
  }

  /// @brief  Get the center point as a |Point|.
  [[nodiscard]] constexpr Point GetCenter() const {
    return {saturated::AverageScalar(left_, right_),
            saturated::AverageScalar(top_, bottom_)};
  }

  [[nodiscard]] constexpr std::array<T, 4> GetLTRB() const {
    return {left_, top_, right_, bottom_};
  }

  /// @brief  Get the x, y coordinates of the origin and the width and
  ///         height of the rectangle in an array.
  [[nodiscard]] constexpr std::array<T, 4> GetXYWH() const {
    return {left_, top_, GetWidth(), GetHeight()};
  }

  /// @brief  Get a version of this rectangle that has a non-negative size.
  [[nodiscard]] constexpr TRect GetPositive() const {
    if (!IsEmpty()) {
      return *this;
    }
    return {
        std::min(left_, right_),
        std::min(top_, bottom_),
        std::max(left_, right_),
        std::max(top_, bottom_),
    };
  }

  /// @brief  Get the points that represent the 4 corners of this rectangle
  ///         in a Z order that is compatible with triangle strips or a set
  ///         of all zero points if the rectangle is empty.
  ///         The order is: Top left, top right, bottom left, bottom right.
  [[nodiscard]] constexpr std::array<TPoint<T>, 4> GetPoints() const {
    if (IsEmpty()) {
      return {};
    }
    return {
        TPoint{left_, top_},
        TPoint{right_, top_},
        TPoint{left_, bottom_},
        TPoint{right_, bottom_},
    };
  }

  [[nodiscard]] 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, clipped against the near clipping plane if
  ///         necessary.
  [[nodiscard]] constexpr TRect TransformAndClipBounds(
      const Matrix& transform) const {
    if (!transform.HasPerspective2D()) {
      return TransformBounds(transform);
    }

    if (IsEmpty()) {
      return {};
    }

    auto ul = transform.TransformHomogenous({left_, top_});
    auto ur = transform.TransformHomogenous({right_, top_});
    auto ll = transform.TransformHomogenous({left_, bottom_});
    auto lr = transform.TransformHomogenous({right_, bottom_});

    // It can probably be proven that we only ever have 5 points at most
    // which happens when only 1 corner is clipped and we get 2 points
    // in return for it as we interpolate against its neighbors.
    Point points[8];
    int index = 0;

    // Process (clip and interpolate) each point against its 2 neighbors:
    //                                 left, pt, right
    index = ClipAndInsert(points, index, ll, ul, ur);
    index = ClipAndInsert(points, index, ul, ur, lr);
    index = ClipAndInsert(points, index, ur, lr, ll);
    index = ClipAndInsert(points, index, lr, ll, ul);

    auto bounds = TRect::MakePointBounds(points, points + index);
    return bounds.value_or(TRect{});
  }

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

  /// @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).
  [[nodiscard]] constexpr Matrix GetNormalizingTransform() const {
    if (!IsEmpty()) {
      Scalar sx = 1.0 / GetWidth();
      Scalar sy = 1.0 / GetHeight();
      Scalar tx = left_ * -sx;
      Scalar ty = top_ * -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});
  }

  [[nodiscard]] constexpr TRect Union(const TRect& o) const {
    if (IsEmpty()) {
      return o;
    }
    if (o.IsEmpty()) {
      return *this;
    }
    return {
        std::min(left_, o.left_),
        std::min(top_, o.top_),
        std::max(right_, o.right_),
        std::max(bottom_, o.bottom_),
    };
  }

  [[nodiscard]] constexpr std::optional<TRect> Intersection(
      const TRect& o) const {
    if (IntersectsWithRect(o)) {
      return TRect{
          std::max(left_, o.left_),
          std::max(top_, o.top_),
          std::min(right_, o.right_),
          std::min(bottom_, o.bottom_),
      };
    } else {
      return std::nullopt;
    }
  }

  [[nodiscard]] constexpr bool IntersectsWithRect(const TRect& o) const {
    return !IsEmpty() &&        //
           !o.IsEmpty() &&      //
           left_ < o.right_ &&  //
           top_ < o.bottom_ &&  //
           right_ > o.left_ &&  //
           bottom_ > o.top_;
  }

  /// @brief Returns the new boundary rectangle that would result from this
  ///        rectangle being cut out by the specified rectangle.
  [[nodiscard]] constexpr std::optional<TRect<T>> Cutout(const TRect& o) const {
    if (IsEmpty()) {
      // This test isn't just a short-circuit, it also prevents the concise
      // math below from returning the wrong answer on empty rects.
      // Once we know that this rectangle is not empty, the math below can
      // only succeed in computing a value if o is also non-empty and non-nan.
      // Otherwise, the method returns *this by default.
      return std::nullopt;
    }

    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 off 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 off the left.
        return TRect::MakeLTRB(b_right, a_top, a_right, a_bottom);
      }
      if (b_right >= a_right && b_left < a_right) {
        // Cuts off the right.
        return TRect::MakeLTRB(a_left, a_top, b_left, a_bottom);
      }
    }

    return *this;
  }

  [[nodiscard]] constexpr TRect CutoutOrEmpty(const TRect& o) const {
    return Cutout(o).value_or(TRect());
  }

  /// @brief  Returns a new rectangle translated by the given offset.
  [[nodiscard]] constexpr TRect<T> Shift(T dx, T dy) const {
    return {
        saturated::Add(left_, dx),    //
        saturated::Add(top_, dy),     //
        saturated::Add(right_, dx),   //
        saturated::Add(bottom_, dy),  //
    };
  }

  /// @brief  Returns a new rectangle translated by the given offset.
  [[nodiscard]] constexpr TRect<T> Shift(TPoint<T> offset) const {
    return Shift(offset.x, offset.y);
  }

  /// @brief  Returns a rectangle with expanded edges. Negative expansion
  ///         results in shrinking.
  [[nodiscard]] constexpr TRect<T> Expand(T left,
                                          T top,
                                          T right,
                                          T bottom) const {
    return {
        saturated::Sub(left_, left),      //
        saturated::Sub(top_, top),        //
        saturated::Add(right_, right),    //
        saturated::Add(bottom_, bottom),  //
    };
  }

  /// @brief  Returns a rectangle with expanded edges in all directions.
  ///         Negative expansion results in shrinking.
  [[nodiscard]] constexpr TRect<T> Expand(T amount) const {
    return {
        saturated::Sub(left_, amount),    //
        saturated::Sub(top_, amount),     //
        saturated::Add(right_, amount),   //
        saturated::Add(bottom_, amount),  //
    };
  }

  /// @brief  Returns a rectangle with expanded edges in all directions.
  ///         Negative expansion results in shrinking.
  [[nodiscard]] constexpr TRect<T> Expand(T horizontal_amount,
                                          T vertical_amount) const {
    return {
        saturated::Sub(left_, horizontal_amount),   //
        saturated::Sub(top_, vertical_amount),      //
        saturated::Add(right_, horizontal_amount),  //
        saturated::Add(bottom_, vertical_amount),   //
    };
  }

  /// @brief  Returns a rectangle with expanded edges in all directions.
  ///         Negative expansion results in shrinking.
  [[nodiscard]] constexpr TRect<T> Expand(TPoint<T> amount) const {
    return Expand(amount.x, amount.y);
  }

  /// @brief  Returns a rectangle with expanded edges in all directions.
  ///         Negative expansion results in shrinking.
  [[nodiscard]] constexpr TRect<T> Expand(TSize<T> amount) const {
    return Expand(amount.width, amount.height);
  }

  /// @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 coordinate space of this
  ///         rectangle.
  [[nodiscard]] constexpr TRect<T> Project(TRect<T> source) const {
    if (IsEmpty()) {
      return {};
    }
    return source.Shift(-left_, -top_)
        .Scale(1.0 / static_cast<Scalar>(GetWidth()),
               1.0 / static_cast<Scalar>(GetHeight()));
  }

  ONLY_ON_FLOAT_M([[nodiscard]] constexpr static, TRect)
  RoundOut(const TRect<U>& r) {
    return TRect::MakeLTRB(saturated::Cast<U, Type>(floor(r.GetLeft())),
                           saturated::Cast<U, Type>(floor(r.GetTop())),
                           saturated::Cast<U, Type>(ceil(r.GetRight())),
                           saturated::Cast<U, Type>(ceil(r.GetBottom())));
  }

  ONLY_ON_FLOAT_M([[nodiscard]] constexpr static, TRect)
  Round(const TRect<U>& r) {
    return TRect::MakeLTRB(saturated::Cast<U, Type>(round(r.GetLeft())),
                           saturated::Cast<U, Type>(round(r.GetTop())),
                           saturated::Cast<U, Type>(round(r.GetRight())),
                           saturated::Cast<U, Type>(round(r.GetBottom())));
  }

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

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

  [[nodiscard]] 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;
  }

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

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

  [[nodiscard]] 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 left, Type top, Type right, Type bottom)
      : left_(left), top_(top), right_(right), bottom_(bottom) {}

  Type left_;
  Type top_;
  Type right_;
  Type bottom_;

  static constexpr Scalar kMinimumHomogenous = 1.0f / (1 << 14);

  // Clip p against the near clipping plane (W = kMinimumHomogenous)
  // and interpolate a crossing point against the nearby neighbors
  // left and right if p is clipped and either of them is not.
  // This method can produce 0, 1, or 2 points per call depending on
  // how many of the points are clipped.
  // 0 - all points are clipped
  // 1 - p is unclipped OR
  //     p is clipped and exactly one of the neighbors is not
  // 2 - p is clipped and both neighbors are not
  static constexpr int ClipAndInsert(Point clipped[],
                                     int index,
                                     const Vector3& left,
                                     const Vector3& p,
                                     const Vector3& right) {
    if (p.z >= kMinimumHomogenous) {
      clipped[index++] = {p.x / p.z, p.y / p.z};
    } else {
      index = InterpolateAndInsert(clipped, index, p, left);
      index = InterpolateAndInsert(clipped, index, p, right);
    }
    return index;
  }

  // Interpolate (a clipped) point p against one of its neighbors
  // and insert the point into the array where the line between them
  // veers from clipped space to unclipped, if such a point exists.
  static constexpr int InterpolateAndInsert(Point clipped[],
                                            int index,
                                            const Vector3& p,
                                            const Vector3& neighbor) {
    if (neighbor.z >= kMinimumHomogenous) {
      auto t = (kMinimumHomogenous - p.z) / (neighbor.z - p.z);
      clipped[index++] = {
          (t * p.x + (1.0f - t) * neighbor.x) / kMinimumHomogenous,
          (t * p.y + (1.0f - t) * neighbor.y) / kMinimumHomogenous,
      };
    }
    return index;
  }
};

using Rect = TRect<Scalar>;
using IRect32 = TRect<int32_t>;
using IRect64 = TRect<int64_t>;
using IRect = IRect64;

#undef ONLY_ON_FLOAT
#undef ONLY_ON_FLOAT_M

}  // namespace impeller

namespace std {

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

}  // namespace std

#endif  // FLUTTER_IMPELLER_GEOMETRY_RECT_H_
