using UnityEngine;
using System.Collections;

public abstract class Easing
{
	public static readonly Easing Linear = new Easing.LinearEasing ();
	public static readonly Easing Quadratic = new Easing.QuadraticEasing ();

	public abstract float EaseIn (float time, float startValue, float deltaValue, float duration);

	public abstract float EaseOut (float time, float startValue, float deltaValue, float duration);

	public float EaseInOut (float time, float startValue, float deltaValue, float duration)
	{
		var halfDuration = duration / 2f;
		var halfDelta = deltaValue / 2f;
		if (time < halfDuration) {
			return this.EaseIn (time, startValue, halfDelta, halfDuration);
		} else {
			return this.EaseOut (time - halfDuration, startValue + halfDelta, halfDelta, halfDuration);
		}
	}

	public float EaseIn01 (float time, float duration)
	{
		return this.EaseIn (time, 0f, 1f, duration);
	}

	public float EaseOut01 (float time, float duration)
	{
		return this.EaseOut (time, 0f, 1f, duration);
	}

	public float EaseInOut01 (float time, float duration)
	{
		return this.EaseInOut (time, 0f, 1f, duration);
	}

	private class LinearEasing : Easing
	{
		public override float EaseIn (float time, float startValue, float deltaValue, float duration)
		{
			return startValue + time / duration * deltaValue;
		}

		public override float EaseOut (float time, float startValue, float deltaValue, float duration)
		{
			return startValue + time / duration * deltaValue;
		}
	}

	private class QuadraticEasing : Easing
	{
		public override float EaseIn (float time, float startValue, float deltaValue, float duration)
		{
			var ratio = time / duration;
			return startValue + deltaValue * ratio * ratio;
		}

		public override float EaseOut (float time, float startValue, float deltaValue, float duration)
		{
			var ratio = time / duration;
			return startValue - deltaValue * ratio * (ratio - 2);
		}
	}

	// http://gizma.com/easing/#sin1
}

