using UnityEngine;
using System.Collections;

public struct ColorHsl 
{
	public float h;
	public float s;
	public float l;
	public float a;
	
	public ColorHsl(float h, float s, float l, float a)
	{
		this.h = h;
		this.s = s;
		this.l = l;
		this.a = a;
	}
	
	public ColorHsl(float h, float s, float l) : this(h, s, l, 1f)
	{		
	}
	
	public ColorHsl(Color colorRgb)
	{
		a = colorRgb.a;
		var max = Mathf.Max(colorRgb.r, colorRgb.g, colorRgb.b);
		var min = Mathf.Min(colorRgb.r, colorRgb.g, colorRgb.b);
		l = ((float)(max + min)) / 2f;
		h = 0f;
		s = 0f;
		
		if (max != min)
		{
			var d = max - min;
			s = l > 0.5f ? d / (2f - max - min) : d / (max + min);
			h = ColorExtensions.GetHue(colorRgb.r, colorRgb.g, colorRgb.b, max, d);
		}
	}
	
	public ColorHsl(Color32 colorRgb) : this((Color)colorRgb)
	{
	}
	
	public static implicit operator Color(ColorHsl value)
	{
		return value.ToColor();
	}
	
	public static implicit operator Color32(ColorHsl value)
	{
		return value.ToColor32();
	}
	
	public static implicit operator ColorHsl(Color value)
	{
		return new ColorHsl(value);
	}

	public static implicit operator ColorHsl(Color32 value)
	{
		return new ColorHsl(value);
	}

	public Color ToColor()
	{
		const float oneThird = 1f / 3f;
		float r = 0f;
		float g = 0f;
		float b = 0f;
		
		if(s == 0)
		{
			r = g = b = l; // achromatic
		}
		else
		{
			var q = l < 0.5f ? l * (1f + s) : l + s - l * s;
			var p = 2f * l - q;
			r = HueToRgbComponent(p, q, h + oneThird);
			g = HueToRgbComponent(p, q, h);
			b = HueToRgbComponent(p, q, h - oneThird);
		}
		
		return new Color(r, g, b, a);
	}
	
	public Color32 ToColor32()
	{
		return ToColor();
	}
	
	public static float HueToRgbComponent(float p, float q, float t)
	{
		const float oneSixth = 1f / 6f;
		const float twoThirds = 2f / 3f;
		
		if(t < 0f)
		{
			t += 1f;
		}
		if(t > 1f)
		{
			t -= 1f;
		}
		
		if(t < oneSixth)
		{
			 return p + (q - p) * 6f * t;
		}
		if(t < 0.5f)
		{
			return q;
		}
		if(t < twoThirds)
		{
			return p + (q - p) * (twoThirds - t) * 6f;
		}
		return p;
	}
	
}
