/* -----------------------------------------------------------------------------
	GSFramework
	Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */


#ifndef	__NCOLOR__
#define	__NCOLOR__


		#include "math/vector.h"


namespace GS {

/*!
	@short	The base color object.
	@author	Emmanuel Julien (ejulien@gsworks.fr)
*/
struct	Color : public Vector4
{
		bool		operator == (const Vector4 &b) const	{	return Math::TestEqual(x, b.x) && Math::TestEqual(y, b.y) && Math::TestEqual(z, b.z) && Math::TestEqual(w, b.w);	}
		bool		operator != (const Vector4 &b) const	{	return !Math::TestEqual(x, b.x) || !Math::TestEqual(y, b.y) || !Math::TestEqual(z, b.z) || !Math::TestEqual(w, b.w);	}

		/// Standard C++ operators.
		void		operator += (const Color &b)		{	x += b.x; y += b.y; z += b.z; w += b.w;	};
		void		operator += (const float k)			{	x += k; y += k; z += k; w += k;			};
		void		operator -= (const Color &b)		{	x -= b.x; y -= b.y; z -= b.z; w -= b.w;	};
		void		operator -= (const float k)			{	x -= k; y -= k; z -= k;	w -= k;			};
		void		operator *= (const Color &b)		{	x *= b.x; y *= b.y; z *= b.z; w *= b.w;	};
		void		operator *= (const float k)			{	x *= k; y *= k; z *= k;	w *= k;			};
		void		operator /= (const Color &b)		{	x /= b.x; y /= b.y; z /= b.z; w /= b.w;	};
		void		operator /= (const float k)			{	float	k_ = 1.0f / k; x *= k_; y *= k_; z *= k_; w *= k_;	};

		Color		operator + (const Color &b) const	{	return Color(x + b.x, y + b.y, z + b.z, w + b.w);	}
		Color		operator + (const float v) const	{	return Color(x + v, y + v, z + v, w + v);		}
		Color		operator - (const Color &b) const	{	return Color(x - b.x, y - b.y, z - b.z, w - b.w);	}
		Color		operator - (const float v) const	{	return Color(x - v, y - v, z - v, w - v);		}
		Color		operator * (const Color &b) const	{	return Color(x * b.x, y * b.y, z * b.z, w * b.w);	}
		Color		operator * (const float v) const	{	return Color(x * v, y * v, z * v, w * v);		}
		Color		operator / (const Color &b) const	{	return Color(x / b.x, y / b.y, z / b.z, w / b.w);	}
		Color		operator / (const float v) const	{	return Color(x / v, y / v, z / v, w / v);		}

		void		operator = (const Vector4 &v)		{	x = v.x; y = v.y; z = v.z; w = v.w;	}

		/*!
			@short	Return a grayscale value representing this color.

			The grayscale value is computed accounting for the human eye color intensity perception.
			@see	FastGray().
		*/
inline	float		Grayscale()	const
		{	return 0.3f * x + 0.59f * y + 0.11f * z;	}
		/*!
			@short	Return a grayscale value representing this color.

			@note	This function is not optically accurate.
			@see	Grayscale().
		*/
inline	float		Fastgray() const
		{	return (x + y + z) / 3.f;	}

		/// Return the color object as an RGBA value.
		uint		AsInteger() const;
		/// Load the color object from an RGBA value.
		void		FromInteger(uint value);

/*!
	@name	Static color objects.
	@{
*/
static	Color		White;
static	Color		Grey;
static	Color		Black;
static	Color		Red;
static	Color		Green;
static	Color		Blue;
static	Color		Yellow;
static	Color		Purple;
/// @}

		/// Scale color not alpha.
		Color		ScaleChroma(float k) const
		{	return Color(x * k, y * k, z * k, w);	}

		/// Return a color object from a vector object.
static	Color		FromVector(Vector4 &v)
		{	return Color(v.x, v.y, v.z, v.w);	}

static	uint		ARGBtoRGBA(uint argb)
		{	return ((argb & 0xff) << 24) + (((argb >> 8) & 0xff) << 16) + (((argb >> 16) & 0xff) << 8) + ((argb >> 24) & 0xff);	}

		Color(const Vector4 &v)
		{	*this = v;	}
		Color(uint rgba32)
		{	FromInteger(rgba32);	}

		Color(float r, float g, float b, float a = 1) : Vector4(r, g, b, a) {}
		Color() {}
};

} // GS


#endif	// __NCOLOR__

