using System;
using System.Drawing;

namespace Super2d3dGraphLibrary;

public class HsbColorUtil
{
	private byte m_red;

	private byte m_green;

	private byte m_blue;

	private double m_hue;

	private double m_luminance;

	private double m_saturation;

	public byte Red
	{
		get
		{
			return m_red;
		}
		set
		{
			m_red = value;
			ToHLS();
		}
	}

	public byte Green
	{
		get
		{
			return m_green;
		}
		set
		{
			m_green = value;
			ToHLS();
		}
	}

	public byte Blue
	{
		get
		{
			return m_blue;
		}
		set
		{
			m_blue = value;
			ToHLS();
		}
	}

	public double Luminance
	{
		get
		{
			return m_luminance;
		}
		set
		{
			if (value < 0.0 || value > 1.0)
			{
				throw new ArgumentOutOfRangeException("Luminance", "Luminance must be between 0.0 and 1.0");
			}
			m_luminance = value;
			ToRGB();
		}
	}

	public double Hue
	{
		get
		{
			return m_hue;
		}
		set
		{
			if (value < 0.0 || value > 360.0)
			{
				throw new ArgumentOutOfRangeException("Hue", "Hue must be between 0.0 and 360.0");
			}
			m_hue = value;
			ToRGB();
		}
	}

	public double Saturation
	{
		get
		{
			return m_saturation;
		}
		set
		{
			if (value < 0.0 || value > 1.0)
			{
				throw new ArgumentOutOfRangeException("Saturation", "Saturation must be between 0.0 and 1.0");
			}
			m_saturation = value;
			ToRGB();
		}
	}

	public Color Color
	{
		get
		{
			return Color.FromArgb(m_red, m_green, m_blue);
		}
		set
		{
			m_red = value.R;
			m_green = value.G;
			m_blue = value.B;
			ToHLS();
		}
	}

	public void LightenColor(double lightenBy)
	{
		m_luminance *= 1.0 + lightenBy;
		if (m_luminance > 1.0)
		{
			m_luminance = 1.0;
		}
		ToRGB();
	}

	public void DarkenColor(double darkenBy)
	{
		m_luminance *= darkenBy;
		ToRGB();
	}

	public HsbColorUtil(Color c)
	{
		m_red = 0;
		m_green = 0;
		m_blue = 0;
		m_hue = 0.0;
		m_luminance = 0.0;
		m_saturation = 0.0;
		m_red = c.R;
		m_green = c.G;
		m_blue = c.B;
		ToHLS();
	}

	public HsbColorUtil(double hue, double luminance, double saturation)
	{
		m_red = 0;
		m_green = 0;
		m_blue = 0;
		m_hue = 0.0;
		m_luminance = 0.0;
		m_saturation = 0.0;
		if (saturation < 0.0 || saturation > 1.0)
		{
			throw new ArgumentOutOfRangeException("Saturation", "Saturation must be between 0.0 and 1.0");
		}
		if (hue < 0.0 || hue > 360.0)
		{
			throw new ArgumentOutOfRangeException("Hue", "Hue must be between 0.0 and 360.0");
		}
		if (luminance < 0.0 || luminance > 1.0)
		{
			throw new ArgumentOutOfRangeException("Luminance", "Luminance must be between 0.0 and 1.0");
		}
		m_hue = hue;
		m_luminance = luminance;
		m_saturation = saturation;
		ToRGB();
	}

	public HsbColorUtil(byte red, byte green, byte blue)
	{
		m_red = 0;
		m_green = 0;
		m_blue = 0;
		m_hue = 0.0;
		m_luminance = 0.0;
		m_saturation = 0.0;
		m_red = red;
		m_green = green;
		m_blue = blue;
	}

	public HsbColorUtil(HsbColorUtil hlsrgb)
	{
		m_red = 0;
		m_green = 0;
		m_blue = 0;
		m_hue = 0.0;
		m_luminance = 0.0;
		m_saturation = 0.0;
		m_red = hlsrgb.Red;
		m_blue = hlsrgb.Blue;
		m_green = hlsrgb.Green;
		m_luminance = hlsrgb.Luminance;
		m_hue = hlsrgb.Hue;
		m_saturation = hlsrgb.Saturation;
	}

	public HsbColorUtil()
	{
		m_red = 0;
		m_green = 0;
		m_blue = 0;
		m_hue = 0.0;
		m_luminance = 0.0;
		m_saturation = 0.0;
	}

	private void ToHLS()
	{
		byte b = Math.Min(m_red, Math.Min(m_green, m_blue));
		byte b2 = Math.Max(m_red, Math.Max(m_green, m_blue));
		double num = (double)(int)b2 * 1.0 - (double)(int)b * 1.0;
		double num2 = (double)(int)b2 * 1.0 + (double)(int)b * 1.0;
		m_luminance = num2 / 510.0;
		if (b2 == b)
		{
			m_saturation = 0.0;
			m_hue = 0.0;
			return;
		}
		double num3 = (double)(int)checked((byte)unchecked((uint)(b2 - m_red))) / num;
		double num4 = (double)(int)checked((byte)unchecked((uint)(b2 - m_green))) / num;
		double num5 = (double)(int)checked((byte)unchecked((uint)(b2 - m_blue))) / num;
		if (m_luminance <= 0.5)
		{
			m_saturation = num / num2;
		}
		else
		{
			m_saturation = num / (510.0 - num2);
		}
		if (m_red == b2)
		{
			m_hue = 60.0 * (6.0 + num5 - num4);
		}
		if (m_green == b2)
		{
			m_hue = 60.0 * (2.0 + num3 - num5);
		}
		if (m_blue == b2)
		{
			m_hue = 60.0 * (4.0 + num4 - num3);
		}
		if (m_hue > 360.0)
		{
			m_hue -= 360.0;
		}
	}

	private void ToRGB()
	{
		if (m_saturation == 0.0)
		{
			m_red = checked((byte)Math.Round(m_luminance * 255.0));
			m_green = m_red;
			m_blue = m_red;
		}
		else
		{
			double num = ((!(m_luminance <= 0.5)) ? (m_luminance + m_saturation - m_luminance * m_saturation) : (m_luminance + m_luminance * m_saturation));
			double rm = 2.0 * m_luminance - num;
			m_red = ToRGB1(rm, num, m_hue + 120.0);
			m_green = ToRGB1(rm, num, m_hue);
			m_blue = ToRGB1(rm, num, m_hue - 120.0);
		}
	}

	private byte ToRGB1(double rm1, double rm2, double rh)
	{
		if (rh > 360.0)
		{
			rh -= 360.0;
		}
		else if (rh < 0.0)
		{
			rh += 360.0;
		}
		if (rh < 60.0)
		{
			rm1 += (rm2 - rm1) * rh / 60.0;
		}
		else if (rh < 180.0)
		{
			rm1 = rm2;
		}
		else if (rh < 240.0)
		{
			rm1 += (rm2 - rm1) * (240.0 - rh) / 60.0;
		}
		return checked((byte)Math.Round(rm1 * 255.0));
	}
}
