// 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 utility class for representing two-dimensional positions.
///
/// Example:
/// ```dart
/// var leftTop = const Point(0, 0);
/// var rightBottom = const Point(200, 400);
/// ```
///
/// **Legacy:** New usages of [Point] are discouraged.
///
/// - If you are using the `Point` 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 combine an `x` and `y` coordinate,
///   consider using a [record](https://dart.dev/language/records).
///   Depending on how you will use it, this could look
///   like `var point = (x, y)` or `var point = (x: x, y: y)`.
/// - If you want to perform vector operations,
///   like vector addition or scalar multiplication,
///   consider using a dedicated vector math library,
///   such as [`package:vector_math`](https://pub.dev/packages/vector_math).
/// - If you are developing a Flutter application or package,
///   consider using the
///   [`Offset`](https://api.flutter.dev/flutter/dart-ui/Offset-class.html)
///   type from `dart:ui`.
// TODO: @Deprecated(
//     'Use records or a dedicated library like package:vector_math instead.')
class Point<T extends num> {
  final T x;
  final T y;

  /// Creates a point with the provided [x] and [y] coordinates.
  ///
  /// **Legacy:** New usages of [Point] are discouraged.
  /// To learn more, check out the [Point] class API docs.
  const Point(T x, T y) : this.x = x, this.y = y;

  String toString() => 'Point($x, $y)';

  /// Whether [other] is a point with the same coordinates as this point.
  ///
  /// Returns `true` if [other] is a [Point] with [x] and [y]
  /// coordinates equal to the corresponding coordinates of this point,
  /// and `false` otherwise.
  ///
  /// Example:
  /// ```dart
  /// var result = const Point(0, 0) == const Point(0, 0); // true
  /// result = const Point(1.0, 0) == const Point(-1.0, 0); // false
  /// ```
  bool operator ==(Object other) =>
      other is Point && x == other.x && y == other.y;

  int get hashCode => SystemHash.hash2(x.hashCode, y.hashCode, 0);

  /// Add [other] to `this`, as if both points were vectors.
  ///
  /// Returns the resulting "vector" as a Point.
  ///
  /// Example:
  /// ```dart
  /// var point = const Point(10, 100) + const Point(10, 10); // Point(20, 110)
  /// point = const Point(-10, -20) + const Point(10, 100); // Point(0, 80)
  /// ```
  Point<T> operator +(Point<T> other) {
    return Point<T>((x + other.x) as T, (y + other.y) as T);
  }

  /// Subtract [other] from `this`, as if both points were vectors.
  ///
  /// Returns the resulting "vector" as a Point.
  ///
  /// Example:
  /// ```dart
  /// var point = const Point(10, 100) - const Point(10, 10); // Point(0, 90)
  /// point = const Point(-10, -20) - const Point(100, 100); // Point(-110, -120)
  /// ```
  Point<T> operator -(Point<T> other) {
    return Point<T>((x - other.x) as T, (y - other.y) as T);
  }

  /// Scale this point by [factor] as if it were a vector.
  ///
  /// **Important Note**: This function accepts a `num` as its argument only so
  /// that you can scale `Point<double>` objects by an `int` factor. Because the
  /// `*` operator always returns the same type of `Point` as it is called on,
  /// passing in a double [factor] on a `Point<int>` _causes_ _a_
  /// _runtime_ _error_.
  ///
  /// Example:
  /// ```dart
  /// // Integer values.
  /// var point = const Point(10, 100) * 10; // Point(100, 1000)
  /// point = const Point(-10, -100) * 5; // Point(-50, -500)
  /// // Double values.
  /// var doublePoint = Point(10.0, 100.0) * 1.5; // Point(15.0, 150.0)
  /// // Runtime error due the invalid type cast.
  /// var newPoint = const Point(10, 100) * 1.5; // Throws.
  /// ```
  Point<T> operator *(num /*T|int*/ factor) {
    return Point<T>((x * factor) as T, (y * factor) as T);
  }

  /// Get the straight line (Euclidean) distance between the origin (0, 0) and
  /// this point.
  ///
  /// Example:
  /// ```dart
  /// var magnitude = const Point(0, 0).magnitude; // 0.0
  /// magnitude = const Point(10, 0).magnitude;  // 10.0
  /// magnitude = const Point(0, -10).magnitude; // 10.0
  /// magnitude = const Point(10, 10).magnitude;  // 14.142135623730951
  /// ```
  double get magnitude => sqrt(x * x + y * y);

  /// Returns the distance between `this` and [other].
  /// ```dart
  /// var distanceTo = const Point(0, 0).distanceTo(const Point(0, 0)); // 0.0
  /// distanceTo = const Point(0, 0).distanceTo(const Point(10, 0)); // 10.0
  /// distanceTo = const Point(0, 0).distanceTo(const Point(0, -10)); // 10.0
  /// distanceTo = const Point(-10, 0).distanceTo(const Point(100, 0)); // 110.0
  /// ```
  double distanceTo(Point<T> other) {
    var dx = x - other.x;
    var dy = y - other.y;
    return sqrt(dx * dx + dy * dy);
  }

  /// Returns the squared distance between `this` and [other].
  ///
  /// Squared distances can be used for comparisons when the actual value is not
  /// required.
  ///
  /// Example:
  /// ```dart
  /// var squaredDistance =
  ///     const Point(0, 0).squaredDistanceTo(const Point(0, 0)); // 0.0
  /// squaredDistance =
  ///     const Point(0, 0).squaredDistanceTo(const Point(10, 0)); // 100
  /// squaredDistance =
  ///     const Point(0, 0).squaredDistanceTo(const Point(0, -10)); // 100
  /// squaredDistance =
  ///     const Point(-10, 0).squaredDistanceTo(const Point(100, 0)); // 12100
  /// ```
  T squaredDistanceTo(Point<T> other) {
    var dx = x - other.x;
    var dy = y - other.y;
    return (dx * dx + dy * dy) as T;
  }
}
