package schema;


class Box {
	public var topleft : Point;
	public var width : Int;
	public var height : Int;
	public var center : Point;

	public function new (topleft : Point, width : Int, height : Int) {
		this.topleft = topleft;
		this.width = width;
		this.height = height;
		this.center = { x : Std.int (topleft.x + width / 2), y : Std.int (topleft.y + height / 2) };
	}

	public static function areSameLine(box1 : Box, box2 : Box) : Bool {
		return Math.abs (box1.center.y - box2.center.y) < 5;
	}

	public static function areSameColumn(box1 : Box, box2 : Box) : Bool {
		return Math.abs (box1.center.x - box2.center.x) < 5;
	}

	public static function leftToRight(box1 : Box, box2 : Box) : Bool {
		return !areSameColumn(box1, box2) && box1.center.x < box2.center.x;
	}

	public static function topToBottom(box1 : Box, box2 : Box) : Bool {
		return !areSameLine(box1, box2) && box1.center.y < box2.center.y;
	}

	public static function getLine (box1 : Box, box2 : Box) : Line {
		var line : Line;
		if (areSameLine (box1, box2)) {
			if (leftToRight (box1, box2)) {
				line = new Line ({ x : box1.topleft.x + box1.width, y : box1.center.y }, { x : box2.topleft.x, y : box1.center.y });
			} else {
				line = new Line ({ x : box1.topleft.x, y : box1.center.y }, { x : box2.topleft.x + box2.width, y : box1.center.y });
			}
		} else if (areSameColumn (box1, box2)) {
			if (topToBottom (box1, box2)) {
				line = new Line ({ x : box1.center.x, y : box1.topleft.y + box1.height }, { x : box1.center.x, y : box2.topleft.y });
			} else {
				line = new Line ({ x : box1.center.x, y : box1.topleft.y }, { x : box1.center.x, y : box2.topleft.y + box2.height });
			}
		} else {
			line = new Line ({ x : box1.center.x, y : box1.center.y }, { x : box2.center.x, y : box2.center.y });
			diagonalLine (box1, box2, line);
		}
		return line;
	}

	static function diagonalLine (box1 : Box, box2 : Box, line : Line) {
		var steering : Float = line.getSteering();
		var offset : Float = line.getOffset();
		var face1 : Point = { x : box1.topleft.x + (box1.center.x < box2.center.x ? box1.width : 0),
							y :  box1.topleft.y + (box1.center.y < box2.center.y ? box1.height : 0) };
			//face.x is the abscissa of the vertical box side, and face.y is the ordinate of the horizontal box side
		var cross1 : Point = { x : Math.round((face1.y - offset) / steering), y : Math.round(face1.x * steering + offset) };
			//the line cross the box either on (cross.x, face.y) or on (face.x, cross.y)
		if (cross1.y >= box1.topleft.y && cross1.y <= box1.topleft.y + box1.height) { //if the line intersects the box left or right side
			line.start.x = face1.x;
			line.start.y = cross1.y;
		} else { //else, it intersects the top or bottom side
			line.start.x = cross1.x;
			line.start.y = face1.y;
		}
		//same for the second box
		var face2 : Point = { x : box2.topleft.x + (box1.center.x < box2.center.x ? 0 : box2.width),
							y :  box2.topleft.y + (box1.center.y < box2.center.y ? 0 : box2.height) };
		var cross2 : Point = { x : Math.round((face2.y - offset) / steering), y : Math.round(face2.x * steering + offset) };
		if (cross2.y >= box2.topleft.y && cross2.y <= box2.topleft.y + box2.height) {
			line.end.x = face2.x;
			line.end.y = cross2.y;
		} else {
			line.end.x = cross2.x;
			line.end.y = face2.y;
		}
	}
}
