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