using System;
using UnityEngine;

public static class FloatExtensions
{
	public static float Fraction(this float f)
	{
		if(f > 9e18f || f < -9e18f)
		{
			return 0f;
		}
		return f - ((long)f);
	}

	static public bool Approximately(this float value, float other)
	{
		//return Mathf.Approximately(value, other);
		
		const float newEpsilon = 0.00001f;
		
		return Mathf.Abs(value - other) < newEpsilon;
	}
	
	static public float SubtractToMinimum(this float value, float toSubtract, float minimum)
	{
		//Debug.Log(value + " - " + toSubtract + ": " + Mathf.Max(value - toSubtract, minimum));
		return Mathf.Max(value - toSubtract, minimum);
	}

	static public float AddToMaximum(this float value, float toAdd, float maximum)
	{
		return Mathf.Min(value + toAdd, maximum);
	}
	
	static public float AddWithinRange(this float value, float toAdd, float minimum, float maximum)
	{
		return Mathf.Max(Mathf.Min(value + toAdd, maximum), minimum);
	}
	
	static public float ToAngle(this Vector2 value)
	{
		return (float)System.Math.Atan2(value.y, value.x) / Mathf.PI * 180.0f;
	}
	
	static public float GetAngleDifference(this float value, float other)
	{
		//var inter = NormalizeAngle(NormalizeAngle(value) - NormalizeAngle(other));
		//var inter2 = NormalizeAngle(value);
		//var inter3 = NormalizeAngle(other);
		var result = ((NormalizeAngle(NormalizeAngle(value) - NormalizeAngle(other)) + 180.0f) % 360.0f) - 180.0f;
		//Debug.Log("GetAngleDifference(" + value + ", " + other + ") = " + result + "; " + inter + "; " + inter2 + "; " + inter3);
		return result;
	}
	
	static public float NormalizeAngle(this float value)
	{
		return Mathf.Atan2(Mathf.Sin(value / 180.0f * Mathf.PI),Mathf.Cos(value / 180.0f * Mathf.PI)) * 180.0f / Mathf.PI; // (((value + 360.0f) % 360.0f) - 360.0f) % 360.0f;
	}
	
	static public float Pulse(float frequency, float min, float max, float t)
	{
		//var s = ((Mathf.Sin(frequency * t * Mathf.PI * 2f) + 1f) * 0.5f);
		var r = (((Mathf.Sin(frequency * t * Mathf.PI * 2f) + 1f) * 0.5f) * (max - min)) + min;
		//Debug.Log(s);
		return r;
	}
	
}

