import 'dart:math' show Point;

import 'package:flutter/painting.dart' show Offset;

import 'vector.dart';

class DPoint {
  static final zero = DPoint(0, 0);

  double _x = 0;
  double _y = 0;

  // ignore: unnecessary_getters_setters
  double get x => _x;
  set x(double value) => _x = value;

  // ignore: unnecessary_getters_setters
  double get y => _y;
  set y(double value) => _y = value;

  DPoint(double x, double y) {
    _x = x;
    _y = y;
  }

  Offset toOffset() => Offset(x, y);

  Point toInnerPoint() => Point(x, y);

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

  void addOffset(double offsetX, double offsetY) {
    _x += offsetX;
    _y += offsetY;
  }

  DPoint addVector(DVector vector) {
    _x += vector.x;
    _y += vector.y;
    return this;
  }

  DPoint subtractVector(DVector vector) {
    _x -= vector.x;
    _y -= vector.y;
    return this;
  }

  static DPoint parse(String source) {
    var splits = source.split(',');
    if (splits.length != 2) {
      throw ArgumentError("Parse $source to DPoint failed");
    }
    return DPoint(double.parse(splits[0]), double.parse(splits[1]));
  }

  static DPoint parsePoint(Point<double> point) {
    return DPoint(point.x, point.y);
  }

  static DPoint parseOffset(Offset offset) {
    return DPoint(offset.dx, offset.dy);
  }

  @override
  bool operator ==(Object other) =>
      other is DPoint && x == other.x && y == other.y;

  bool operator <(DPoint other) =>
      toInnerPoint().magnitude < other.toInnerPoint().magnitude;
  bool operator <=(DPoint other) =>
      toInnerPoint().magnitude <= other.toInnerPoint().magnitude;
  bool operator >(DPoint other) =>
      toInnerPoint().magnitude > other.toInnerPoint().magnitude;
  bool operator >=(DPoint other) =>
      toInnerPoint().magnitude >= other.toInnerPoint().magnitude;

  DVector operator -(DPoint other) => DVector(x - other.x, y - other.y);

  @override
  int get hashCode => x.hashCode ^ y.hashCode;
}
