// Copyright (c) 2016, 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.

import 'dart:math' hide Rectangle;
import 'dart:math' as math show Point, Rectangle, MutableRectangle;
import 'package:expect/expect.dart' show Expect;

void main() {
  verifyRectable(new Rectangle(1, 2, 3, 4));
}

void verifyRectable(math.Rectangle rect) {
  Expect.equals(1.0, rect.left.toDouble());
  Expect.equals(2.0, rect.top.toDouble());
  Expect.equals(4.0, rect.right.toDouble());
  Expect.equals(6.0, rect.bottom.toDouble());
}

class Rectangle<T extends num> implements math.MutableRectangle<T> {
  T left;
  T top;
  T width;
  T height;

  Rectangle(this.left, this.top, this.width, this.height);

  T get right => (left + width) as T;

  T get bottom => (top + height) as T;

  Point<T> get topLeft => new Point<T>(left, top);

  Point<T> get topRight => new Point<T>(right, top);

  Point<T> get bottomLeft => new Point<T>(left, bottom);

  Point<T> get bottomRight => new Point<T>(right, bottom);

  //---------------------------------------------------------------------------

  bool contains(num px, num py) {
    return left <= px && top <= py && right > px && bottom > py;
  }

  bool containsPoint(math.Point<num> p) {
    return contains(p.x, p.y);
  }

  bool intersects(math.Rectangle<num> r) {
    return left < r.right && right > r.left && top < r.bottom && bottom > r.top;
  }

  /// Returns a new rectangle which completely contains `this` and [other].

  Rectangle<T> boundingBox(math.Rectangle<T> other) {
    T rLeft = min(left, other.left);
    T rTop = min(top, other.top);
    T rRight = max(right, other.right);
    T rBottom = max(bottom, other.bottom);
    return new Rectangle<T>(
      rLeft,
      rTop,
      (rRight - rLeft) as T,
      (rBottom - rTop) as T,
    );
  }

  /// Tests whether `this` entirely contains [another].

  bool containsRectangle(math.Rectangle<num> r) {
    return left <= r.left &&
        top <= r.top &&
        right >= r.right &&
        bottom >= r.bottom;
  }

  Rectangle<T> intersection(math.Rectangle<T> rect) {
    T rLeft = max(left, rect.left);
    T rTop = max(top, rect.top);
    T rRight = min(right, rect.right);
    T rBottom = min(bottom, rect.bottom);
    return new Rectangle<T>(
      rLeft,
      rTop,
      (rRight - rLeft) as T,
      (rBottom - rTop) as T,
    );
  }
}
