class Rect
{
	constructor(xMin, yMin, width, height)
	{
		if (typeof PIXI !== 'undefined' && xMin instanceof PIXI.Rectangle)
		{
			// cast PIXI.Rectangle to Rect
			this._xMin = xMin.x;
			this._yMin = xMin.y;
			this._width = xMin.width;
			this._height = xMin.height;
		}
		else if (xMin && yMin && xMin.x !== undefined && xMin.y !== undefined && yMin.x !== undefined && yMin.y !== undefined)
		{
			this._xMin = xMin.x;
			this._yMin = xMin.y;
			this._width = yMin.x;
			this._height = yMin.y;
		}
		else
		{
			this._xMin = xMin === undefined ? 0 : xMin;
			this._yMin = yMin === undefined ? 0 : yMin;
			this._width = width === undefined ? 0 : width;
			this._height = height === undefined ? 0 : height;
		}
	}

	set(xMin, yMin, width, height)
	{
		this._xMin = xMin === undefined ? 0 : xMin;
		this._yMin = yMin === undefined ? 0 : yMin;
		this._width = width === undefined ? 0 : width;
		this._height = height === undefined ? 0 : height;
	}
	
	get x() { return this._xMin; }
	get xMin() { return this._xMin; }	
	get left() { return this._xMin; }
	get xMax() { return this._xMin + this._width; }
	get right() { return this._xMin + this._width; }
	get width() { return this._width; }	
	
	get y() { return this._yMin; }
	get yMin() { return this._yMin; }
	get top() { return this._yMin; }
	get yMax() { return this._yMin + this._height; }
	get bottom() { return this._yMin + this._height; }
	get height() { return this._height; }
	
	set x(x) { this._xMin = x; }
	set left(xMin) { this.xMin = xMin;}
	set xMin(xMin) { var xMax = this.xMax; this._xMin = xMin; this._width = xMax - xMin; }
	set right(xMax) {this.xMax = xMax;}
	set xMax(xMax) { var xMin = this.xMin; this._xMax = xMax; this._width = xMax - xMin; }
	set width(w) { this._width = w; }
	
	set y(y) { this._yMin = y; }
	set top(yMin) { this.yMin = yMin; }
	set yMin(yMin) { var yMax = this.yMax; this._yMin = yMin; this._height = yMax - yMin; }
	set bottom(yMax) { this.yMax = yMax; }
 	set yMax(yMax) { var yMin = this.yMin; this._yMax = yMax; this._height = yMax - yMin; }
	set height(h) { this._height = h; }

	center()
	{
		// getting lazy
		if (this._centerVector === undefined) this._centerVector = new Vector2();
		this._centerVector.x = this.x + this.width * 0.5;
		this._centerVector.y = this.y + this.height * 0.5;
		return this._centerVector;
	}

	copy(r)
	{
		this._xMin = r._xMin;
		this._yMin = r._yMin;
		this._width = r._width;
		this._height = r._height;
		return this;
	}
	
	clone()
	{
		return new Rect(this._xMin, this._yMin, this._width, this._height);
	}
	
	contains(x, y)
	{
		if (y === undefined)
		{
			var p = x;	//Vector2
			return this.contains(p.x, p.y);
		}
		return x >= this.xMin && x <= this.xMax && y >= this.yMin && y <= this.yMax;
	}

	overlaps(rect)
	{
		/*// check if either rect contains a point of the other rect
		if (this.contains(rect.xMin, rect.yMin)) return true;
		if (this.contains(rect.xMin, rect.yMax)) return true;
		if (this.contains(rect.xMax, rect.yMin)) return true;
		if (this.contains(rect.xMax, rect.yMax)) return true;

		// its possible this rectangle is completely enclosed by the other rectangle
		if (rect.contains(this.xMin, this.yMin)) return true;
		if (rect.contains(this.xMin, this.yMax)) return true;
		if (rect.contains(this.xMax, this.yMin)) return true;
		if (rect.contains(this.xMax, this.yMax)) return true;

		return false
		*/

		// better solution, the reverse! does not overlap if one rect above or beside other rectangle
		if (this.xMax < rect.xMin || rect.xMax < this.xMin) return false;
		if (this.yMax < rect.yMin || rect.yMax < this.yMax) return false;

		return true;
	}
}

if (typeof module === 'object' && module.exports) module.exports = Rect;