import { Vector2D } from "./vector2d";

export class Rectangle {
  private readonly corner_1: Vector2D;
  private readonly corner_2: Vector2D;

  constructor();
  constructor(corner_1: Vector2D, corner_2: Vector2D);
  constructor(corner_1 = new Vector2D(), corner_2 = new Vector2D()) {
    this.corner_1 = corner_1;
    this.corner_2 = corner_2;
  }

  public get origin(): Vector2D {
    return new Vector2D(
      Math.min(this.corner_1.x, this.corner_2.x),
      Math.min(this.corner_1.y, this.corner_2.y),
    );
  }

  public get left(): number {
    return this.origin.x;
  }

  public get top(): number {
    return this.origin.y;
  }

  public get corner(): Vector2D {
    return new Vector2D(
      Math.max(this.corner_1.x, this.corner_2.x),
      Math.max(this.corner_1.y, this.corner_2.y),
    );
  }

  public get size(): Vector2D {
    return this.corner.minus(this.origin);
  }

  public get width(): number {
    return this.size.x;
  }

  public get height(): number {
    return this.size.y;
  }

  public get middle(): Vector2D {
    return this.origin.plus(this.size.scale(0.5));
  }

  public get area(): number {
    return this.width * this.height;
  }

  public equals(other: Rectangle): boolean {
    return this.origin.equals(other.origin) && this.corner.equals(other.corner);
  }

  public contains(point: Vector2D): boolean {
    return (
      point.x >= this.origin.x &&
      point.y >= this.origin.y &&
      point.x <= this.corner.x &&
      point.y <= this.corner.y
    );
  }

  public update(corner_1?: Vector2D, corner_2?: Vector2D): Rectangle {
    return new Rectangle(corner_1 ?? this.corner_1, corner_2 ?? this.corner_2);
  }

  public move(vector: Vector2D): Rectangle {
    return new Rectangle(
      this.corner_1.plus(vector),
      this.corner_2.plus(vector),
    );
  }
}
