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