package ;

import flixel.FlxG;
import flash.geom.Point;
import flixel.text.FlxText;
import flixel.util.FlxPoint;
import flixel.FlxSprite;

class Util
{
	public static inline function lerp(a:Float, b:Float, t:Float):Float
	{
		return a + (b-a) * t;
	}

	public static inline function lerpScale(v:Float, v0:Float, v1:Float, out0:Float, out1:Float):Float
	{
		return lerp(out0, out1, (Math.max(Math.min(v, v1), v0) - v0) / (v1 - v0));
	}

	public static inline function setPos(s:FlxSprite, pos:FlxPoint):FlxSprite
	{
		s.setPosition(pos.x, pos.y);
		return s;
	}

	public static function makeText(str:String, width:Int=400, color:Int=0xffffffff, align="center"):FlxText
	{
		var text = new FlxText(0, 0, width, str);
		text.setFormat("assets/images/Hippauf.ttf", 12, color, align);
		return text;
	}

	public static inline function dist(a:Point, b:Point):Float
	{
		var dx = a.x - b.x;
		var dy = a.y - b.y;
		return Math.sqrt(dx*dx + dy*dy);
	}

	public static inline function sub(a:Point, b:Point):Point
	{
		return new Point(a.x-b.x, a.y-b.y);
	}

	public static inline function add(a:Point, b:Point):Point
	{
		return new Point(a.x+b.x, a.y+b.y);
	}

	public static inline function mul(f:Float, p:Point):Point
	{
		return new Point(f*p.x, f*p.y);
	}

	public static inline function normalize(p:Point):Point
	{
		var len = Math.sqrt(p.x*p.x + p.y*p.y);
		return len == 0 ? new Point(0,0) : new Point(p.x/len, p.y/len);
	}

	public static inline function plerp(a:Point, b:Point, t:Float):Point
	{
		return new Point(lerp(a.x, b.x, t), lerp(a.y, b.y, t));
	}

	public static inline function dot(a:Point, b:Point):Float
	{
		return (a.x*b.x + a.y*b.y);
	}

	public static inline function perp(p:Point):Point
	{
		return new Point(p.y, -p.x);
	}

	public static function intersect(a0:Point, a1:Point, b0:Point, b1:Point):Point
	{
		// http://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect
		//	char get_line_intersection(float p0_x, float p0_y, float p1_x, float p1_y,
		//    float b0.x, float b0.y, float b1.x, float b1.y, float *i_x, float *i_y)
		var s1_x = a1.x - a0.x;
		var s1_y = a1.y - a0.y;
		var s2_x = b1.x - b0.x;
		var s2_y = b1.y - b0.y;

		var s = (-s1_y * (a0.x - b0.x) + s1_x * (a0.y - b0.y)) / (-s2_x * s1_y + s1_x * s2_y);
		var t = ( s2_x * (a0.y - b0.y) - s2_y * (a0.x - b0.x)) / (-s2_x * s1_y + s1_x * s2_y);

		if (s >= 0 && s <= 1 && t >= 0 && t <= 1)
		{
			// Collision detected
			return new Point(a0.x + (t * s1_x), a0.y + (t * s1_y));
		}
		else
		{
			return null;
		}
	}

	public static function catmull(P0:Point, P1:Point, P2:Point, P3:Point, t:Float):Point
	{
		// http://www.mvps.org/directx/articles/catmull/
		var x = 0.5 * ((2*P1.x) + (-P0.x + P2.x) * t + (2*P0.x - 5*P1.x + 4*P2.x - P3.x) * t*t + (-P0.x + 3*P1.x- 3*P2.x + P3.x) * t*t*t);
		var y = 0.5 * ((2*P1.y) + (-P0.y + P2.y) * t + (2*P0.y - 5*P1.y + 4*P2.y - P3.y) * t*t + (-P0.y + 3*P1.y- 3*P2.y + P3.y) * t*t*t);
		return new Point(x,y);
	}

	public static function playSound(name:String)
	{
		FlxG.sound.play("assets/sounds/" + name);
	}
}
