package search;

import flash.geom.Point;

class Target
{
	var driftVelocity:Point;
	var entryWiggle:Float;
	var driftTimeOffset:Float;
	var entryCoords:Point = new Point();
	var wreckCoords:Point = new Point();
	public var recovered:Bool = false;
	public var isReal:Bool = false;

	public function new(area:Area, forDemo:Bool=false)
	{
		if (!forDemo)
		{
			// come in an an edge somewhere
			entryCoords.x = area.dim.x * Math.random();
			entryCoords.y = area.dim.y * Math.random();
			if (Math.random() < 0.5) entryCoords.x = Math.random() < 0.5 ? 0 : area.dim.x;
			else entryCoords.y = Math.random() < 0.5 ? 0 : area.dim.y;

			// wreck somewhere inside
			var inset = (area.config != null) ? area.config.targetInset : 0.5;
			while (true)
			{
				wreckCoords.x = Util.lerp(inset, area.dim.x-inset, Math.random());
				wreckCoords.y = Util.lerp(inset, area.dim.y-inset, Math.random());
				if (Util.dist(entryCoords, wreckCoords) > 1) break;
			}

			// scale entryWiggle with length of path
			entryWiggle = Math.random() * Util.lerpScale(Util.dist(entryCoords, wreckCoords), 1, area.dim.y, 0, 1);

			// drift from wreck
			var driftAngle = 2 * Math.PI * Math.random();
			var driftSpeed = 0.002 * Math.random();
			driftTimeOffset = 30 * Math.random();
			driftVelocity = new Point(driftSpeed * Math.cos(driftAngle), driftSpeed * Math.sin(driftAngle));
		}
		else
		{
			entryCoords.x = area.dim.x;
			entryCoords.y = 0;
			wreckCoords.x = area.dim.x * 0.5 + ToolSonicBuoy.kMaxRadius*0.8;
			wreckCoords.y = area.dim.y * 0.5 - ToolSonicBuoy.kMaxRadius*0.5;
			driftTimeOffset = 0;
			driftVelocity = new Point(0,0);
			entryWiggle = 0.5;
		}
	}

	public function getCoords(clock:Clock):Point
	{
		return new Point(
			wreckCoords.x + driftVelocity.x * (driftTimeOffset + clock.time),
			wreckCoords.y + driftVelocity.y * (driftTimeOffset + clock.time)
		);
	}

	public function buildEntryPath():Array<Point>
	{
		// build entry path
		var entryPath = new Array<Point>();

		// wiggled control points on a catmull-rom spline
		var entryControlPoints = new Array<Point>();
		var numControlPoints = Std.int(Util.lerp(2, 8, entryWiggle));
		var entryPerp = Util.normalize(Util.perp(Util.sub(wreckCoords, entryCoords)));
		var wiggleMag = Util.lerp(0.1, 2, entryWiggle);
		for (i in 0...numControlPoints)
		{
			var t = i / numControlPoints;
			var mag = (i == 0 || i == numControlPoints-1) ? 0 : Util.lerp(-1, 1, wiggleMag*Math.random());
			var p = Util.plerp(entryCoords, wreckCoords, t);
			p = Util.add(p, Util.mul(mag, entryPerp));
			entryControlPoints.push(p);
		}

		// normalize to linear path
		var numPoints = 50;
		for (i in 0...numPoints)
		{
			var t = i / numPoints;
			var pathS = t * (entryControlPoints.length);

			var i1 = Math.floor(pathS);
			var i0 = Std.int(Math.max(i1-1, 0));
			var i2 = Std.int(Math.min(i1+1, entryControlPoints.length-1));
			var i3 = Std.int(Math.min(i1+2, entryControlPoints.length-1));

			var p = Util.catmull(
				entryControlPoints[i0],
				entryControlPoints[i1],
				entryControlPoints[i2],
				entryControlPoints[i3],
				pathS % 1.0
			);

			entryPath.push(p);
		}

		return entryPath;
	}
}
