// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

part of dart.math;

/// A base class for representing two-dimensional axis-aligned rectangles.
///
/// This rectangle uses a left-handed Cartesian coordinate system, with x
/// directed to the right and y directed down, as per the convention in 2D
/// computer graphics.
///
/// See also:
///    [W3C Coordinate Systems Specification](https://www.w3.org/TR/SVG/coords.html#InitialCoordinateSystem).
///
/// The rectangle is the set of points with representable coordinates greater
/// than or equal to left/top, and with distance to left/top no greater than
/// width/height (to the limit of the precision of the coordinates).
///
/// **Legacy:** New usages of [_RectangleBase] are discouraged.
/// To learn more, check out the [Rectangle] class API docs.
abstract class _RectangleBase<T extends num> {
  const _RectangleBase();

  /// The x-coordinate of the left edge.
  T get left;

  /// The y-coordinate of the top edge.
  T get top;

  /// The width of the rectangle.
  T get width;

  /// The height of the rectangle.
  T get height;

  /// The x-coordinate of the right edge.
  T get right => (left + width) as T;

  /// The y-coordinate of the bottom edge.
  T get bottom => (top + height) as T;

  String toString() {
    return 'Rectangle ($left, $top) $width x $height';
  }

  bool operator ==(Object other) =>
      other is Rectangle &&
      left == other.left &&
      top == other.top &&
      right == other.right &&
      bottom == other.bottom;

  int get hashCode => SystemHash.hash4(
    left.hashCode,
    top.hashCode,
    right.hashCode,
    bottom.hashCode,
    0,
  );

  /// Computes the intersection of `this` and [other].
  ///
  /// The intersection of two axis-aligned rectangles, if any, is always another
  /// axis-aligned rectangle.
  ///
  /// Returns the intersection of this and `other`, or `null` if they don't
  /// intersect.
  Rectangle<T>? intersection(Rectangle<T> other) {
    var x0 = max(left, other.left);
    var x1 = min(left + width, other.left + other.width);

    if (x0 <= x1) {
      var y0 = max(top, other.top);
      var y1 = min(top + height, other.top + other.height);

      if (y0 <= y1) {
        return Rectangle<T>(x0, y0, (x1 - x0) as T, (y1 - y0) as T);
      }
    }
    return null;
  }

  /// Returns true if `this` intersects [other].
  bool intersects(Rectangle<num> other) {
    return (left <= other.left + other.width &&
        other.left <= left + width &&
        top <= other.top + other.height &&
        other.top <= top + height);
  }

  /// Returns a new rectangle which completely contains `this` and [other].
  Rectangle<T> boundingBox(Rectangle<T> other) {
    var right = max(this.left + this.width, other.left + other.width);
    var bottom = max(this.top + this.height, other.top + other.height);

    var left = min(this.left, other.left);
    var top = min(this.top, other.top);

    return Rectangle<T>(left, top, (right - left) as T, (bottom - top) as T);
  }

  /// Tests whether `this` entirely contains [another].
  bool containsRectangle(Rectangle<num> another) {
    return left <= another.left &&
        left + width >= another.left + another.width &&
        top <= another.top &&
        top + height >= another.top + another.height;
  }

  /// Tests whether [another] is inside or along the edges of `this`.
  bool containsPoint(Point<num> another) {
    return another.x >= left &&
        another.x <= left + width &&
        another.y >= top &&
        another.y <= top + height;
  }

  Point<T> get topLeft => Point<T>(this.left, this.top);
  Point<T> get topRight => Point<T>((this.left + this.width) as T, this.top);
  Point<T> get bottomRight =>
      Point<T>((this.left + this.width) as T, (this.top + this.height) as T);
  Point<T> get bottomLeft => Point<T>(this.left, (this.top + this.height) as T);
}

/// A class for representing two-dimensional rectangles whose properties are
/// immutable.
///
/// **Legacy:** New usages of [Rectangle] are discouraged.
///
/// - If you are using the `Rectangle` class with `dart:html`,
///   we recommend migrating to `package:web`.
///   To learn how and why to migrate,
///   check out the [migration guide](https://dart.dev/go/package-web).
/// - If you want to store the boundaries of a rectangle
///   in some coordinate system,
///   consider using a [record](https://dart.dev/language/records).
///   Depending on how you will use it, this could look
///   like `var boundaries = (mixX: x1, maxX: x2, minY: y1, maxY: y2)`.
/// - If you need to perform intersection calculations or containment checks,
///   consider using a dedicated library, such as
///   [`package:vector_math`](https://pub.dev/packages/vector_math).
/// - If you are developing a Flutter application or package,
///   consider using the
///   [`Rect`](https://api.flutter.dev/flutter/dart-ui/Rect-class.html)
///   type from `dart:ui`.
// TODO: @Deprecated(
//     'Use records or a dedicated library like package:vector_math instead.')
class Rectangle<T extends num> extends _RectangleBase<T> {
  final T left;
  final T top;
  final T width;
  final T height;

  /// Create a rectangle spanned by `(left, top)` and
  /// `(left+width, top+height)`.
  ///
  /// The rectangle contains the points
  /// with x-coordinate between `left` and `left + width`, and
  /// with y-coordinate between `top` and `top + height`, both inclusive.
  ///
  /// The `width` and `height` should be non-negative.
  /// If `width` or `height` are negative, they are clamped to zero.
  ///
  /// If `width` and `height` are zero, the "rectangle" comprises only the
  /// single point `(left, top)`.
  ///
  /// Example:
  /// ```dart
  /// var rectangle = const Rectangle(20, 50, 300, 600);
  /// print(rectangle.left); // 20
  /// print(rectangle.top); // 50
  /// print(rectangle.right); // 320
  /// print(rectangle.bottom); // 650
  /// ```
  ///
  /// **Legacy:** New usages of [Rectangle] are discouraged.
  /// To learn more, check out the [Rectangle] class API docs.
  const Rectangle(this.left, this.top, T width, T height)
    : width =
          (width < 0)
              ? (width == double.negativeInfinity ? 0.0 : (-width * 0))
                  as dynamic
              : (width + 0 as dynamic), // Inline _clampToZero<num>.
      height =
          (height < 0)
              ? (height == double.negativeInfinity ? 0.0 : (-height * 0))
                  as dynamic
              : (height + 0 as dynamic);

  /// Create a rectangle spanned by the points [a] and [b];
  ///
  /// The rectangle contains the points
  /// with x-coordinate between `a.x` and `b.x`, and
  /// with y-coordinate between `a.y` and `b.y`, both inclusive.
  ///
  /// If the distance between `a.x` and `b.x` is not representable
  /// (which can happen if one or both is a double),
  /// the actual right edge might be slightly off from `max(a.x, b.x)`.
  /// Similar for the y-coordinates and the bottom edge.
  ///
  /// Example:
  /// ```dart
  /// var leftTop = const Point(20, 50);
  /// var rightBottom = const Point(300, 600);
  ///
  /// var rectangle = Rectangle.fromPoints(leftTop, rightBottom);
  /// print(rectangle); // Rectangle (20, 50) 280 x 550
  /// print(rectangle.left); // 20
  /// print(rectangle.top); // 50
  /// print(rectangle.right); // 300
  /// print(rectangle.bottom); // 600
  /// ```
  factory Rectangle.fromPoints(Point<T> a, Point<T> b) {
    T left = min(a.x, b.x);
    T width = (max(a.x, b.x) - left) as T;
    T top = min(a.y, b.y);
    T height = (max(a.y, b.y) - top) as T;
    return Rectangle<T>(left, top, width, height);
  }
}

/// A class for representing two-dimensional axis-aligned rectangles with
/// mutable properties.
///
/// **Legacy:** New usages of [MutableRectangle] are discouraged.
///
/// - If you are using the `MutableRectangle` class with `dart:html`,
///   we recommend migrating to `package:web`.
///   To learn how and why to migrate,
///   check out the [migration guide](https://dart.dev/go/package-web).
/// - If you want to store the boundaries of a rectangle
///   in some coordinate system,
///   consider using a [record](https://dart.dev/language/records).
///   Depending on how you will use it, this could look
///   like `var boundaries = (mixX: x1, maxX: x2, minY: y1, maxY: y2)`.
/// - If you need to perform intersection calculations or containment checks,
///   consider using a dedicated library, such as
///   [`package:vector_math`](https://pub.dev/packages/vector_math).
/// - If you are developing a Flutter application or package,
///   consider using the
///   [`Rect`](https://api.flutter.dev/flutter/dart-ui/Rect-class.html)
///   type from `dart:ui`.
// TODO: @Deprecated(
//     'Use records or a dedicated library like package:vector_math instead.')
class MutableRectangle<T extends num> extends _RectangleBase<T>
    implements Rectangle<T> {
  /// The x-coordinate of the left edge.
  ///
  /// Setting the value will move the rectangle without changing its width.
  T left;

  /// The y-coordinate of the left edge.
  ///
  /// Setting the value will move the rectangle without changing its height.
  T top;
  T _width;
  T _height;

  /// Create a mutable rectangle spanned by `(left, top)` and
  /// `(left+width, top+height)`.
  ///
  /// The rectangle contains the points
  /// with x-coordinate between `left` and `left + width`, and
  /// with y-coordinate between `top` and `top + height`, both inclusive.
  ///
  /// The `width` and `height` should be non-negative.
  /// If `width` or `height` are negative, they are clamped to zero.
  ///
  /// If `width` and `height` are zero, the "rectangle" comprises only the
  /// single point `(left, top)`.
  ///
  /// Example:
  /// ```dart
  /// var rectangle = MutableRectangle(20, 50, 300, 600);
  /// print(rectangle); // Rectangle (20, 50) 300 x 600
  /// print(rectangle.left); // 20
  /// print(rectangle.top); // 50
  /// print(rectangle.right); // 320
  /// print(rectangle.bottom); // 650
  ///
  /// // Change rectangle width and height.
  /// rectangle.width = 200;
  /// rectangle.height = 100;
  ///
  /// print(rectangle); // Rectangle (20, 50) 200 x 100
  /// print(rectangle.left); // 20
  /// print(rectangle.top); // 50
  /// print(rectangle.right); // 220
  /// print(rectangle.bottom); // 150
  /// ```
  ///
  /// **Legacy:** New usages of [MutableRectangle] are discouraged.
  /// To learn more, check out the [MutableRectangle] class API docs.
  MutableRectangle(this.left, this.top, T width, T height)
    : this._width =
          (width < 0) ? _clampToZero<T>(width) : (width + 0 as dynamic),
      this._height =
          (height < 0) ? _clampToZero<T>(height) : (height + 0 as dynamic);

  /// Create a mutable rectangle spanned by the points [a] and [b];
  ///
  /// The rectangle contains the points
  /// with x-coordinate between `a.x` and `b.x`, and
  /// with y-coordinate between `a.y` and `b.y`, both inclusive.
  ///
  /// If the distance between `a.x` and `b.x` is not representable
  /// (which can happen if one or both is a double),
  /// the actual right edge might be slightly off from `max(a.x, b.x)`.
  /// Similar for the y-coordinates and the bottom edge.
  ///
  /// Example:
  /// ```dart
  /// var leftTop = const Point(20, 50);
  /// var rightBottom = const Point(300, 600);
  /// var rectangle = MutableRectangle.fromPoints(leftTop, rightBottom);
  /// print(rectangle); // Rectangle (20, 50) 280 x 550
  /// print(rectangle.left); // 20
  /// print(rectangle.top); // 50
  /// print(rectangle.right); // 300
  /// print(rectangle.bottom); // 600
  /// ```
  factory MutableRectangle.fromPoints(Point<T> a, Point<T> b) {
    T left = min(a.x, b.x);
    T width = (max(a.x, b.x) - left) as T;
    T top = min(a.y, b.y);
    T height = (max(a.y, b.y) - top) as T;
    return MutableRectangle<T>(left, top, width, height);
  }

  T get width => _width;

  /// Sets the width of the rectangle.
  ///
  /// The width must be non-negative.
  /// If a negative width is supplied, it is clamped to zero.
  ///
  /// Setting the value will change the right edge of the rectangle,
  /// but will not change [left].
  set width(T width) {
    if (width < 0) width = _clampToZero<T>(width);
    _width = width;
  }

  T get height => _height;

  /// Sets the height of the rectangle.
  ///
  /// The height must be non-negative.
  /// If a negative height is supplied, it is clamped to zero.
  ///
  /// Setting the value will change the bottom edge of the rectangle,
  /// but will not change [top].
  set height(T height) {
    if (height < 0) height = _clampToZero<T>(height);
    _height = height;
  }
}

/// Converts a negative [int] or [double] to a zero-value of the same type.
///
/// Returns `0` if value is int, `0.0` if value is double.
T _clampToZero<T extends num>(T value) {
  assert(value < 0);
  if (value == double.negativeInfinity) return 0.0 as dynamic;
  return (-value * 0) as dynamic;
}
