/**
 * Represents a point in the grid
 */
export class Point {
	x: number
	y: number

	constructor(x: number, y: number) {
		this.x = x
		this.y = y
	}
}

/**
 * Represents a box in the grid
 */
export class Box {
	/**
	 * Upper left corner of the box
	 */
	upperLeft: Point

	/**
	 * Lower right corner of the box
	 */
	lowerRight: Point

	constructor(upperLeft: Point, lowerRight: Point) {
		this.upperLeft = upperLeft
		this.lowerRight = lowerRight
	}

	get left(): number {
		return this.upperLeft.x
	}

	get right(): number {
		return this.lowerRight.x
	}

	get bottom(): number {
		return this.lowerRight.y
	}

	get top(): number {
		return this.upperLeft.y
	}

	get width(): number {
		return this.right - this.left
	}

	get height(): number {
		return this.bottom - this.top
	}

	/**
	 * Checks if the box intersects with another box
	 * @param other Box to check if it intersects with
	 * @returns True if the boxes intersect, false otherwise
	 */
	intersects(other: Box): boolean {
		return !(
			this.right <= other.left ||
			this.left >= other.right ||
			this.bottom <= other.top ||
			this.top >= other.bottom
		)
	}

	/**
	 * Returns all positions the box occupies inside the grid
	 * @param box Box to get positions of
	 * @returns Set of positions
	 */
	getAllPositions(): Set<Point> {
		const positions = new Set<Point>()

		for (let x = this.left; x <= this.right; x++) {
			for (let y = this.top; y <= this.bottom; y++) {
				positions.add({ x, y })
			}
		}

		return positions
	}
}
