#ifndef COLOR_H
#define COLOR_H

//==============================================================
//==============================================================

#include "def.h"
#include "ssVector.hpp"

//==============================================================
//==============================================================

#pragma pack( push, 1 )
class Color
{
public:
	inline Color( )													{ r=0; g=0; b=0; a=255; }
	inline Color( UINT32 argb )										{ set(argb); }
	inline Color( UINT8 ri, UINT8 gi, UINT8 bi, UINT8 ai=255 )		{ r=ri; g=gi; b=bi; a=ai; }
	inline Color( const Vector3 &v )								{ set( v ); }
	inline Color( const Vector4 &v )								{ set( v ); }
	inline void set( UINT8 ri, UINT8 gi, UINT8 bi, UINT8 ai )		{ r=ri; g=gi; b=bi; a=ai; }
	inline void set( UINT8 ri, UINT8 gi, UINT8 bi )					{ r=ri; g=gi; b=bi; }
	inline void setAlpha( UINT8 ai )								{ a=ai; }
	inline void set( const Vector3 &v )
	{
		int t;
		t = intFloor(v.x*255.0f);
		if( t > 255 ) t = 255; else if( t < 0 ) t = 0;
		r = t;
		t = intFloor(v.y*255.0f);
		if( t > 255 ) t = 255; else if( t < 0 ) t = 0;
		g = t;
		t = intFloor(v.z*255.0f);
		if( t > 255 ) t = 255; else if( t < 0 ) t = 0;
		b = t;
	}
	inline void set( const Vector4 &v )
	{
		int t;
		t = intFloor(v.x*255.0f);
		if( t > 255 ) t = 255; else if( t < 0 ) t = 0;
		r = t;
		t = intFloor(v.y*255.0f);
		if( t > 255 ) t = 255; else if( t < 0 ) t = 0;
		g = t;
		t = intFloor(v.z*255.0f);
		if( t > 255 ) t = 255; else if( t < 0 ) t = 0;
		b = t;
		t = intFloor(v.w*255.0f);
		if( t > 255 ) t = 255; else if( t < 0 ) t = 0;
		a = t;
	}
	inline void	set( UINT32 argb )									{ a=(char)((argb&0xff000000)>>24); r=(char)((argb&0xff0000)>>16);g=(char)((argb&0xff00)>>8);b=(char)(argb&0xff); }
	inline UINT32 getUINT32() const									{ return (a<<24)|(r<<16)|(g<<8)|b; }

	inline void operator=( const Vector3 &v )						{ set(v); }
	inline void operator=( const Vector4 &v )						{ set(v); }

	inline Color &operator+=(const Color &c)						{ int k;
													k = a + c.a; if( k > 255 ) k = 255; a = k;
													k = r + c.r; if( k > 255 ) k = 255; r = k;
													k = g + c.g; if( k > 255 ) k = 255; g = k;
													k = b + c.b; if( k > 255 ) k = 255; b = k;
													return *this; }
	inline Color &operator-=(const Color &c)						{ int k;
													k = a - c.a; if( k < 0 ) k = 0; a = k;
													k = r - c.r; if( k < 0 ) k = 0; r = k;
													k = g - c.g; if( k < 0 ) k = 0; g = k;
													k = b - c.b; if( k < 0 ) k = 0; b = k;
													return *this; }
	inline Color &operator*=(const Color &c)						{ int k;
													k = a * c.a; k = k >> 8; if( k > 255 ) k = 255; a = k;
													k = r * c.r; k = k >> 8; if( k > 255 ) k = 255; r = k;
													k = g * c.g; k = k >> 8; if( k > 255 ) k = 255; g = k;
													k = b * c.b; k = k >> 8; if( k > 255 ) k = 255; b = k;
													return *this; }
	inline Color &operator+=(float f)								{ float k; f *= 255.0f;
													k = a + f; if( k > 255 ) k = 255; else if( k < 0 ) k = 0; a = intFloor(k);
													k = r + f; if( k > 255 ) k = 255; else if( k < 0 ) k = 0; r = intFloor(k);
													k = g + f; if( k > 255 ) k = 255; else if( k < 0 ) k = 0; g = intFloor(k);
													k = b + f; if( k > 255 ) k = 255; else if( k < 0 ) k = 0; b = intFloor(k);
													return *this; }
	inline Color &operator*=(float f)								{ float k;
													k = a * f; if( k > 255 ) k = 255; else if( k < 0 ) k = 0; a = intFloor(k);
													k = r * f; if( k > 255 ) k = 255; else if( k < 0 ) k = 0; r = intFloor(k);
													k = g * f; if( k > 255 ) k = 255; else if( k < 0 ) k = 0; g = intFloor(k);
													k = b * f; if( k > 255 ) k = 255; else if( k < 0 ) k = 0; b = intFloor(k);
													return *this; }
	inline Color &operator+=(const Vector3 &v)					{ float k;
													k = r + v.x * 255.0f; if( k > 255 ) k = 255; else if( k < 0 ) k = 0; r = intFloor(k);
													k = g + v.y * 255.0f; if( k > 255 ) k = 255; else if( k < 0 ) k = 0; g = intFloor(k);
													k = b + v.z * 255.0f; if( k > 255 ) k = 255; else if( k < 0 ) k = 0; b = intFloor(k);
													return *this; }
	inline Color &operator*=(const Vector3 &v)					{ float k;
													k = r * v.x; if( k > 255 ) k = 255; else if( k < 0 ) k = 0; r = intFloor(k);
													k = g * v.y; if( k > 255 ) k = 255; else if( k < 0 ) k = 0; g = intFloor(k);
													k = b * v.z; if( k > 255 ) k = 255; else if( k < 0 ) k = 0; b = intFloor(k);
													return *this; }
	inline Color &operator+=(const Vector4 &v)					{ float k;
													k = r + v.x * 255.0f; if( k > 255 ) k = 255; else if( k < 0 ) k = 0; r = intFloor(k);
													k = g + v.y * 255.0f; if( k > 255 ) k = 255; else if( k < 0 ) k = 0; g = intFloor(k);
													k = b + v.z * 255.0f; if( k > 255 ) k = 255; else if( k < 0 ) k = 0; b = intFloor(k);
													k = a + v.w * 255.0f; if( k > 255 ) k = 255; else if( k < 0 ) k = 0; a = intFloor(k);
													return *this; }
	inline Color &operator*=(const Vector4 &v)					{ float k;
													k = r * v.x; if( k > 255 ) k = 255; else if( k < 0 ) k = 0; r = intFloor(k);
													k = g * v.y; if( k > 255 ) k = 255; else if( k < 0 ) k = 0; g = intFloor(k);
													k = b * v.z; if( k > 255 ) k = 255; else if( k < 0 ) k = 0; b = intFloor(k);
													k = a * v.w; if( k > 255 ) k = 255; else if( k < 0 ) k = 0; a = intFloor(k);
													return *this; }

	inline void toVector3( Vector3 &v ) const		{ v.x = float(r)*(1.0f/255.0f); v.y = float(g)*(1.0f/255.0f); v.z = float(b)*(1.0f/255.0f); }
	inline void toVector4( Vector4 &v ) const		{ v.x = float(r)*(1.0f/255.0f); v.y = float(g)*(1.0f/255.0f); v.z = float(b)*(1.0f/255.0f); v.w = float(a)*(1.0f/255.0f); }
	inline Vector3 toVector3( ) const				{ return Vector3(float(r)*(1.0f/255.0f), float(g)*(1.0f/255.0f), float(b)*(1.0f/255.0f)); }
	inline Vector4 toVector4( ) const				{ return Vector4(float(r)*(1.0f/255.0f), float(g)*(1.0f/255.0f), float(b)*(1.0f/255.0f), float(a)*(1.0f/255.0f)); }

	UINT8 b,g,r,a;	//Intel inverse byte order...
};
#pragma pack( pop )

//==============================================================
//==============================================================

#endif
