/****************************************************************************************

		LayerTypes.h

		Copyright: (c) 2001 Eovia Corp. All rights reserved.


		Revision History

		when		who			what & why
		==========	==========	======================================================
		06/10/99	dsm			added kMsgKind_BoundsChanged message
		04/06/99	del			Moved ChangeManager message concerning layers here
		03/26/99	Mathieu		IsRGB() and IsCMYK() for easy channel id
		03/25/99	del			Added CUSTOM_CHANNEL type
		2/17/99		psq			Added ETileAccess
		1/22/99		psq			changed ELayerColorType
		12/28/98	scooper		add mask and selection channel types
		10/27/98	cph			added class TChannelID 
		10/21/98	cph/tsh		renamed LayerColorTypeEnum to ELayerColorType; 
								moved EChannelType here from IShChannel.h

*****************************************************************************************/

#ifndef __LayerTypes__
#define __LayerTypes__

#include "MCPixelBucket.h"

// Layer change messages.
const FourCharT kLayerChangeChannel					= 'layr';
const FourCharT kContent_LayerChangeChannel			= 'Cont';
const FourCharT kLayerVisibilityChanged				= 'layv';
const FourCharT kLayerPropertyChanged				= 'layp';

// Channel change messages.
const FourCharT kMsgKind_AddChannel					= 'AChn';
const FourCharT kMsgKind_DeleteChannel				= 'DChn';
const FourCharT kMsgKind_BeActiveChannel			= 'BChn';
const FourCharT kMsgKind_DeActivateChannel			= 'NChn';
const FourCharT kMsgKind_ChannelPropertiesChange	= 'PChn';
const FourCharT kMsgKind_BoundsChanged				= 'Boun';
const FourCharT kMsgKind_LayerAdded					= 'ALay';
const FourCharT kMsgKind_LayerRemoved				= 'RLay';
const FourCharT kChannelVisibilityChanged			= 'VChn';
const FourCharT kChannelDataChanged					= 'IChn';

enum ELayerColorType
{
	eLayerHasAlpha	= 0x10,
	eLayerUNKNOWN	= 0,
	eLayerRGB		= 1,
	eLayerRGBA		= 1|eLayerHasAlpha,
	eLayerGRAY		= 2,
	eLayerAGRAY		= 2|eLayerHasAlpha,
	eLayerCMYK		= 3,
	eLayerACMYK		= 3|eLayerHasAlpha
};

//psq: may need a better place for ETileAccess
enum ETileAccess
{
	eTileRead		= 1,
	eTileWrite		= 2,			// this flag means that you are going to lock
									// a tile (or a rect on a raster layer) and your
									// are going to write on it EVERYWHERE. This
									// flags tells to the system that the old values
									// of that tile are going to be overwritten so
									// it doesn't need to restore the old values.
	eTileReadWrite	= eTileRead | eTileWrite,
	eTileDisplay	= 4 | eTileRead
};


/// Gives the ID of an image channel. Used by IShChannel::GetID and IShChannel::SetID
///
class TChannelID //please synchronized with STR# kStrImageChannels in Image.r and ImageDefines.h
{
public:

	enum EChannelType 
	{
		eANY = 0,			///< must be 0
		eRED_CHANNEL,
		eGREEN_CHANNEL,
		eBLUE_CHANNEL,
		
		eCYAN_CHANNEL,
		eMAGENTA_CHANNEL,
		eYELLOW_CHANNEL,
		eBLACK_CHANNEL,		///< K channel of CMYK

		eGRAY_CHANNEL,
		eALPHA_CHANNEL,
		eSELECTION_CHANNEL,
		eMASK_CHANNEL,
		eCUSTOM_CHANNEL,
		eARGB_CHANNEL,
		eUNKNOWN,
		eINVALID
	};

	TChannelID() {} ;
	TChannelID(EChannelType type, uint16 enumerator) { fType = type; fEnumerator = enumerator; }
	TChannelID(const TChannelID& source) : fType(source.fType), fEnumerator(source.fEnumerator) {}

	static const TChannelID kInvalidChID;

	TChannelID& operator=	(const TChannelID& id2) { fType = id2.fType; fEnumerator = id2.fEnumerator; return (*this); }
	boolean		operator==	(const TChannelID& id2) const { return (fType == id2.fType) && (fEnumerator == id2.fEnumerator); }
	boolean		operator!=	(const TChannelID& id2) const { return !operator==(id2); }

	// Match returns true if type and enumerator are the same, or if 
	boolean		Match		(const TChannelID& id2) const { return (&id2 == this) || (((fType == id2.fType) || (fType == eANY) || (id2.fType == eANY)) && ((fEnumerator == id2.fEnumerator) || (fEnumerator == 0) || (id2.fEnumerator == 0))); }
	boolean		IsColor		() const { return fType <= eGRAY_CHANNEL; }
	boolean		IsRGB		() const { return ((fType == eRED_CHANNEL) || (fType == eGREEN_CHANNEL) || (fType == eBLUE_CHANNEL)); }
	boolean		IsCMYK		() const { return ((fType == eCYAN_CHANNEL) || (fType == eMAGENTA_CHANNEL) || (fType == eYELLOW_CHANNEL) || (fType == eBLACK_CHANNEL)); }

	inline		PixelBucketType GetByteFormat(uint16 bitdepth) const;

	EChannelType fType;
	uint16 fEnumerator;

};

const TChannelID kChannelIDsRGBA[4]  = {TChannelID(TChannelID::eRED_CHANNEL, 1), TChannelID(TChannelID::eGREEN_CHANNEL, 1), TChannelID(TChannelID::eBLUE_CHANNEL, 1), TChannelID(TChannelID::eALPHA_CHANNEL, 1)};
const TChannelID kChannelIDsCMYKA[5] = {TChannelID(TChannelID::eCYAN_CHANNEL, 1), TChannelID(TChannelID::eMAGENTA_CHANNEL, 1), TChannelID(TChannelID::eYELLOW_CHANNEL, 1), TChannelID(TChannelID::eBLACK_CHANNEL, 1), TChannelID(TChannelID::eALPHA_CHANNEL, 1)};

// inlines

inline PixelBucketType TChannelID::GetByteFormat(uint16 bitdepth) const
{
	PixelBucketType type;
	boolean def = false;
	if (fType >= eRED_CHANNEL && fType < eUNKNOWN)
	{
		switch (bitdepth)
		{
		case 8:
			type = eGrayScale;
			break;
		case 16:
			type = eChannel2_14;
			break;
		default:
			def = true;
		}
	}
	else
	{
		def = true;
	}

	if (def)
	{
		switch (bitdepth)
		{
		case 8:
			type = eGrayScale;
			break;
		case 16:
			type = eChannel16;
			break;
		default:
			type = eDefault;
		}
	}
	return type;
}


#endif