#pragma once

#include "memstrm.h"
#include "scalar.h"

//##########################################################################
//##############    RGBColor    ############################################
//##########################################################################

class RGBColor
{
	friend class RGBAColor;

public:
	Scalar Red, Green, Blue;

	#if defined(USE_SIGNATURE)
		friend int Is_Signature_Bad(const volatile RGBColor *p)
		{
			return False;
		}
	#endif


	RGBColor()
	{
		Red = Green = Blue = -1.0f;
	}

	RGBColor(Scalar r, Scalar g, Scalar b)
	{
		Red = r;
		Green = g;
		Blue = b;
	}

	Logical operator==(const RGBColor &a_RGBColor) const
	{
		return !memcmp(this, &a_RGBColor, sizeof(RGBColor));
	}
	Logical operator!=(const RGBColor &a_RGBColor) const
	{
		return memcmp(this, &a_RGBColor, sizeof(RGBColor));
	}

	Logical TestInstance() const;

	RGBColor operator+(const RGBColor &a_RGBColor) const		{ return RGBColor(Min(this->Red + a_RGBColor.Red, 1.0), Min(this->Green + a_RGBColor.Green, 1.0), Min(this->Blue + a_RGBColor.Blue, 1.0)); }
	Scalar Infrared() const										{ return 0.3 * this->Red + 0.5 * this->Green + 0.2 * this->Blue; }

//
// Support functions
//
	friend std::ostream& operator<<(std::ostream& stream, const RGBColor& C);
};


//~~~~~~~~~~~~~~~~~~~~~~~~~~ RGBColor functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

void Convert_From_Ascii(const char *str, RGBColor *color);

inline MemoryStream& MemoryStream_Read(MemoryStream* stream, RGBColor *output)			{ return stream->ReadBytes(output, sizeof(*output)); }
inline MemoryStream& MemoryStream_Write(MemoryStream* stream, const RGBColor *input)	{ return stream->WriteBytes(input, sizeof(*input)); }

//##########################################################################
//##############    RGBAColor    ###########################################
//##########################################################################

class RGBAColor : public RGBColor
{
public:
	Scalar Alpha;
	
	RGBAColor() : RGBColor()	{ Alpha = -1.0f; }

	RGBAColor(Scalar r, Scalar g, Scalar b, Scalar a) : RGBColor(r, g, b)	{ Alpha = a; }

	Logical operator==(const RGBAColor &a_RGBAColor) const		{ return !memcmp(this, &a_RGBAColor, sizeof(RGBAColor)); }
	Logical	operator!=(const RGBAColor &a_RGBAColor) const		{ return memcmp(this, &a_RGBAColor, sizeof(RGBAColor)); }

//
// Support functions
//
	friend std::ostream& operator<<(std::ostream& stream, const RGBAColor& c);
};

//~~~~~~~~~~~~~~~~~~~~~~~~~~ RGBAColor functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

void Convert_From_Ascii(const char *str, RGBAColor *color);

inline MemoryStream& MemoryStream_Read(MemoryStream* stream, RGBAColor *output)			{ return stream->ReadBytes(output, sizeof(*output)); }
inline MemoryStream& MemoryStream_Write(MemoryStream* stream, const RGBAColor *input)	{ return stream->WriteBytes(input, sizeof(*input)); }