//
//	Copyright © 2005 Nemetschek North America 
//	All Rights Reserved.
//
// Created by Vladislav Stanev

#include "StdAfx.h"

using namespace VWFC::Tools;

CRGBColor::CRGBColor()
{
	this->red		= 0;
	this->green		= 0;
	this->blue		= 0;
}

CRGBColor::CRGBColor(UInt8 r, UInt8 g, UInt8 b)
{
	this->red		= (r << 8) | r;
	this->green		= (g << 8) | g;
	this->blue		= (b << 8) | b;
}

CRGBColor::CRGBColor(const RGBColor& clr)
{
	this->red		= clr.red;
	this->green		= clr.green;
	this->blue		= clr.blue;
}

CRGBColor::CRGBColor(const CRGBColor& clr)
{
	this->red		= clr.red;
	this->green		= clr.green;
	this->blue		= clr.blue;
}

// create gradient color from 'leftColor' to 'rightColor' using percentage
// 0% = leftColor; 100% = rightColor
CRGBColor::CRGBColor(const CRGBColor& leftColor, const CRGBColor& rightColor, double dPercent)
{

	UInt8	r	= (UInt8) ( (double)( rightColor.GetRed() - leftColor.GetRed() ) * (dPercent/100) + leftColor.GetRed() );
	UInt8	g	= (UInt8) ( (double)( rightColor.GetGreen() - leftColor.GetGreen() ) * (dPercent/100) + leftColor.GetGreen() );
	UInt8	b	= (UInt8) ( (double)( rightColor.GetBlue() - leftColor.GetBlue() ) * (dPercent/100) + leftColor.GetBlue() );

	this->SetColor( r, g, b );
}

CRGBColor::CRGBColor(ColorRef colorIndex)
{
	::GS_ColorIndexToRGB( gCBP, colorIndex, *this );
}

CRGBColor::~CRGBColor()
{
}

CRGBColor& CRGBColor::operator=(const RGBColor& clr)
{
	this->red		= clr.red;
	this->green		= clr.green;
	this->blue		= clr.blue;
	return *this;
}

CRGBColor& CRGBColor::operator=(const CRGBColor& clr)
{
	this->red		= clr.red;
	this->green		= clr.green;
	this->blue		= clr.blue;
	return *this;
}

bool CRGBColor::operator==(const CRGBColor& clr) const
{
	return
		this->red == clr.red &&
		this->green == clr.green &&
		this->blue == clr.blue ;
}

bool CRGBColor::operator!=(const CRGBColor& clr) const
{
	return ! ( this->operator == ( clr ) );
}

UInt8 CRGBColor::GetRed() const
{
	return (this->red >> 8) & 0xFF;
}

void CRGBColor::SetRed(UInt8 red)
{
	this->red		= (red << 8) | red;
}

UInt8 CRGBColor::GetGreen() const
{
	return (this->green >> 8) & 0xFF;
}

void CRGBColor::SetGreen(UInt8 green)
{
	this->green		= (green << 8) | green;
}

UInt8 CRGBColor::GetBlue() const
{
	return (this->blue >> 8) & 0xFF;
}

void CRGBColor::SetBlue(UInt8 blue)
{
	this->blue		= (blue << 8) | blue;
}

void CRGBColor::GetColor(UInt8& r, UInt8& g, UInt8& b) const
{
	r = this->red >> 8;
	g = this->green >> 8;
	b = this->blue >> 8;
}

void CRGBColor::SetColor(UInt8 r, UInt8 g, UInt8 b)
{
	this->red		= (r << 8) | r;
	this->green		= (g << 8) | g;
	this->blue		= (b << 8) | b;
}

void CRGBColor::SetColor(ColorRef colorIndex)
{
	::GS_ColorIndexToRGB( gCBP, colorIndex, *this );
}

ColorRef CRGBColor::GetColorIndex(bool bMatchBlackBkgr) const
{
	ColorRef		colorIndex;

	// When in black background, 'GS_RGBToColorIndex' reverses black and white.
	// If the caller doesn't want this reveresal, we need to un-swap black & white.
	bool bReverseBlackAndWhite = false;

	if ( bMatchBlackBkgr ) {
		::GS_GetProgramVariable( gCBP, varBlackBackground, & bReverseBlackAndWhite );
	}

	if ( bReverseBlackAndWhite ) {
		const CRGBColor kRGBWhite(255,255,255);
		const CRGBColor kRGBBlack(0,0,0);

		if (*this == kRGBBlack)
			::GS_RGBToColorIndex( gCBP, kRGBWhite, colorIndex );
		else if (*this == kRGBWhite)
			::GS_RGBToColorIndex( gCBP, kRGBBlack, colorIndex );
		else
			::GS_RGBToColorIndex( gCBP, *this, colorIndex );
	}
	else {
		::GS_RGBToColorIndex( gCBP, *this, colorIndex );
	}

	return colorIndex;
}