package h2d.col;

class RoundRect implements Collider {

	public var x : Float;
	public var y : Float;
	var ray : Float;
	var dx : Float;
	var dy : Float;
	var lenSq : Float;
	var invLenSq : Float;

	public inline function new(x:Float,y:Float,w:Float,h:Float,rotation:Float) {
		if( w < h ) {
			var tmp = w;
			w = h;
			h = tmp;
			rotation += Math.PI / 2;
		}
		var hseg = (w - h) * 0.5;
		var dx = hseg * Math.cos(rotation);
		var dy = hseg * Math.sin(rotation);
		this.x = x - dx;
		this.y = y - dy;
		this.dx = dx * 2;
		this.dy = dy * 2;
		this.ray = h * 0.5;
		lenSq = this.dx * this.dx + this.dy * this.dy;
		invLenSq = lenSq < hxd.Math.EPSILON ? 0 : 1 / lenSq;
	}

	// distance segment
	public inline function distanceCenterSq( p : Point ) {
		var px = p.x - x;
		var py = p.y - y;
		var t = px * dx + py * dy;
		return if( t < 0 )
			px * px + py * py;
		else if( t > lenSq ) {
			var kx = p.x - (x + dx);
			var ky = p.y - (y + dy);
			kx * kx + ky * ky;
		} else {
			var tl2 = t * invLenSq;
			var pdx = x + tl2 * dx - p.x;
			var pdy = y + tl2 * dy - p.y;
			pdx * pdx + pdy * pdy;
		}
	}

	public inline function inside( p : Point ) {
		return distanceCenterSq(p) - ray * ray < 0;
	}

	public inline function distance( p : Point ) {
		return Math.sqrt(distanceCenterSq(p)) - ray;
	}

	public inline function getNormalAt( p : Point ) {
		var px = p.x - x;
		var py = p.y - y;
		var t = px * dx + py * dy;
		if( t < 0 ) {
			// done
		} else if( t > lenSq ) {
			px = p.x - (x + dx);
			py = p.y - (y + dy);
		} else {
			var tl2 = t * invLenSq;
			px = -(x + tl2 * dx - p.x);
			py = -(y + tl2 * dy - p.y);
		}
		return new Point(px, py);
	}

	public function contains( p : Point ) {
		return inside(p);
	}

}