#ifndef __COLOR_H__
#define __COLOR_H__

#include "public.h"
#include "tuple.h"
//
// Color class
//
namespace xrt
{
	class Color 
	{
	public:
		union
		{
			struct { float r, g, b, a; };
			float c[4];
		};
		Color( float c = 0.0f ) { r = g = b = c; }
		Color( int c ) { r = g = b = (float)c; }
		Color( float r, float g, float b ): r(r), g(g), b(b) {}
		Color( float r, float g, float b, float a ): r(r), g(g), b(b), a(a) {}
		Color( const Color &c ) { r = c.r; g = c.g; b = c.b; }
		Color( const float *v )   { r = v[0];  g = v[1];  b = v[2]; }
		Color( const Tuple &t )   { r = t[0];  g = t[1];  b = t[2]; }

		friend Color operator+( const Color &c1, const Color &c2 )
		{ return Color( c1.r + c2.r, c1.g + c2.g, c1.b + c2.b ); }

		friend Color operator+( const Color &c, float f )
		{ return Color( c.r + f, c.g + f, c.b + f ); }

		friend Color operator-( const Color &c1, const Color &c2 )
		{ return Color( c1.r - c2.r, c1.g - c2.g, c1.b - c2.b ); }

		friend Color operator-( const Color &c, float f )
		{ return Color( c.r - f, c.g - f, c.b - f ); }

		friend Color operator*( float f, const Color &c )
		{ return Color( f * c.r, f * c.g, f * c.b); }

		friend Color operator*( const Color &c, float f )
		{ return Color( c.r * f, c.g * f, c.b * f ); }

		friend Color operator*( const Color &c1, const Color &c2 )
		{ return Color( c1.r * c2.r, c1.g * c2.g, c1.b * c2.b ); }

		friend Color operator/( const Color &c, float f )
		{ if ( f != 0.0f ) return Color( c.r / f, c.g / f, c.b / f ); else return Color( 0.0f ); }

		friend Color operator/( const Color &c1, const Color &c2 )
		{ return Color ( c2.r != 0.0f ? c1.r / c2.r : 0.0f,
			c2.g != 0.0f ? c1.g / c2.g : 0.0f, c2.b != 0.0f ? c1.b / c2.b : 0.0f ); }

		friend bool operator==( const Color &c1, const Color &c2 )
		{ return c1.r == c2.r && c1.g == c2.g && c1.b == c2.b; }
		
		friend bool operator!=( const Color &c1, const Color &c2 )
		{ return c1.r != c2.r || c1.g != c2.g || c1.b != c2.b; }

		Color &operator=( const Color &c )
		{ r = c.r; g = c.g; b = c.b; return *this; }

		Color &operator= ( const float f) 
		{ r = g = b = f; return *this; }

		Color &operator+=( const Color &c )
		{ r += c.r; g += c.g; b += c.b; return *this; }

		Color &operator-=( const Color &c )
		{ r -= c.r; g -= c.g; b -= c.b; return *this; }

		Color &operator*=( float f )
		{ r *= f; g *= f; b *= f; return *this; }

		Color &operator*=( const Color &c )
		{ r *= c.r; g *= c.g; b *= c.b; return *this; }

		Color &operator/=( float f )
		{ if ( f != 0.0f ) { r /= f; g /= f; b /= f; } return *this; }

		Color &operator/=( const Color &c )
		{ if ( c.r != 0.0f ) r /= c.r; if ( c.g != 0.0f ) g /= c.g; 
			if ( c.b != 0.0f ) b /= c.b; return *this; }

		float  operator[] (int i) const { return c[i]; }
		float &operator[] (int i) { return c[i]; }

		Color rgbTohsv() const;
		Color hsvTorgb() const;
		Color rgbTohsl() const;
		Color hslTorgb() const;
		Color rgbToXYZ() const;
		Color XYZTorgb() const;
		Color rgbToxyY() const;
		Color xyYTorgb() const;
		Color rgbToYIQ() const;
		Color YIQTorgb() const;
		//friend float comp( Color&, float );
		//friend void setcomp( Color&, float, float );

	};
};

#endif //__COLOR_H__

