//-----------------------------------------------------------------------------------------------
// BasicTypes.hpp
//
#pragma once
#ifndef include_BasicTypes
#define include_BasicTypes

//-----------------------------------------------------------------------------------------------
#include "Engine/Core/PlatformDefines.hpp"
#include "Engine/Core/STL.hpp"


//-----------------------------------------------------------------------------------------------
// Typedefs
//
typedef unsigned char							byte_t;
typedef unsigned short							word_t;
typedef unsigned int							dword_t;
typedef unsigned long							bitflags_t;


//-----------------------------------------------------------------------------------------------
// Markers and tags
//
//#define OUT // means nothing, just a marker; used in function args to denote a "return value" output parm
#define EXTERN // means nothing, just a marker; used in CPPs on extern'd members (e.g. theApplication)
#define STATIC // means nothing, just a marker; used in CPPs on static member and method definitions
#define VIRTUAL // means nothing, just a marker; used in CPPs to denote virtual functions
#define UNUSED( x ) (void)(x) // used to suppress compiler warnings for intentionally unused variables

#ifndef NULL
#define NULL 0
#endif

#define NAMESPACE_BEGIN( x ) namespace x {
#define NAMESPACE_END( x ) };


/////////////////////////////////////////////////////////////////////////////////////////////////
enum HorizontalAlignment
{
	HORIZONTAL_ALIGNMENT_INVALID = -1,
	HORIZONTAL_ALIGNMENT_LEFT,
	HORIZONTAL_ALIGNMENT_CENTER,
	HORIZONTAL_ALIGNMENT_RIGHT,
	HORIZONTAL_ALIGNMENT_UNALIGNED,
};


/////////////////////////////////////////////////////////////////////////////////////////////////
enum VerticalAlignment
{
	VERTICAL_ALIGNMENT_INVALID = -1,
	VERTICAL_ALIGNMENT_TOP,
	VERTICAL_ALIGNMENT_CENTER,
	VERTICAL_ALIGNMENT_BOTTOM,
	VERTICAL_ALIGNMENT_UNALIGNED,
};


/////////////////////////////////////////////////////////////////////////////////////////////////
enum Alignment2D
{
	ALIGNMENT_2D_INVALID = -1,
	ALIGNMENT_2D_TOPLEFT,
	ALIGNMENT_2D_TOPCENTER,
	ALIGNMENT_2D_TOPRIGHT,
	ALIGNMENT_2D_CENTERRIGHT,
	ALIGNMENT_2D_BOTTOMRIGHT,
	ALIGNMENT_2D_BOTTOMCENTER,
	ALIGNMENT_2D_BOTTOMLEFT,
	ALIGNMENT_2D_CENTERLEFT,
	ALIGNMENT_2D_CENTER,
	ALIGNMENT_2D_UNALIGNED,
};


/////////////////////////////////////////////////////////////////////////////////////////////////
enum Alignment1D
{
	ALIGNMENT_1D_INVALID = -1,
	ALIGNMENT_1D_MINIMUM,
	ALIGNMENT_1D_MIDDLE,
	ALIGNMENT_1D_MAXIMUM,
	ALIGNMENT_1D_UNALIGNED,
};


/////////////////////////////////////////////////////////////////////////////////////////////////
enum BlendFactor
{
	BLENDFACTOR_ZERO,
	BLENDFACTOR_ONE,
	BLENDFACTOR_SRC_COLOR,
	BLENDFACTOR_ONE_MINUS_SRC_COLOR,	// only valid for destination factor
	BLENDFACTOR_SRC_ALPHA,
	BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
	BLENDFACTOR_DST_COLOR,
	BLENDFACTOR_ONE_MINUS_DST_COLOR,	// only valid for source factor
	BLENDFACTOR_DST_ALPHA,				// only valid for source factor
	BLENDFACTOR_ONE_MINUS_DST_ALPHA,
	NUM_BLENDFACTORS,
};


//-----------------------------------------------------------------------------------------------
inline const char* GetBlendModeStringFromBlendFactors( BlendFactor& srcBlendFactor, BlendFactor& dstBlendFactor )
{
	const char* blendModeString = "custom";
	if( srcBlendFactor == BLENDFACTOR_SRC_ALPHA && dstBlendFactor == BLENDFACTOR_ONE )
		blendModeString = "add";
	else if( srcBlendFactor == BLENDFACTOR_ZERO && dstBlendFactor == BLENDFACTOR_SRC_COLOR )
		blendModeString = "multiply";
	else if( srcBlendFactor == BLENDFACTOR_DST_COLOR && dstBlendFactor == BLENDFACTOR_ZERO )
		blendModeString = "multiply";
	else if( srcBlendFactor == BLENDFACTOR_SRC_ALPHA && dstBlendFactor == BLENDFACTOR_ONE_MINUS_SRC_ALPHA )
		blendModeString ="alpha";

	return blendModeString ;
}


//-----------------------------------------------------------------------------------------------
inline Alignment1D GetAlignment1DForHorizontalAlignment( HorizontalAlignment horizontalAlignment )
{
	switch( horizontalAlignment )
	{
		case HORIZONTAL_ALIGNMENT_INVALID:		return ALIGNMENT_1D_INVALID;
		case HORIZONTAL_ALIGNMENT_LEFT:			return ALIGNMENT_1D_MINIMUM;
		case HORIZONTAL_ALIGNMENT_CENTER:		return ALIGNMENT_1D_MIDDLE;
		case HORIZONTAL_ALIGNMENT_RIGHT:		return ALIGNMENT_1D_MAXIMUM;
		case HORIZONTAL_ALIGNMENT_UNALIGNED:	return ALIGNMENT_1D_UNALIGNED;
		default:								return ALIGNMENT_1D_INVALID;
	}
}


//-----------------------------------------------------------------------------------------------
inline Alignment1D GetAlignment1DForVerticalAlignment( VerticalAlignment verticalAlignment )
{
	switch( verticalAlignment )
	{
		case VERTICAL_ALIGNMENT_INVALID:		return ALIGNMENT_1D_INVALID;
		case VERTICAL_ALIGNMENT_TOP:			return ALIGNMENT_1D_MINIMUM;
		case VERTICAL_ALIGNMENT_CENTER:			return ALIGNMENT_1D_MIDDLE;
		case VERTICAL_ALIGNMENT_BOTTOM:			return ALIGNMENT_1D_MAXIMUM;
		case VERTICAL_ALIGNMENT_UNALIGNED:		return ALIGNMENT_1D_UNALIGNED;
		default:								return ALIGNMENT_1D_INVALID;
	}
}


//-----------------------------------------------------------------------------------------------
// Special values
//
enum
{
	ID_INVALID		= -1,
	INDEX_INVALID	= -1
};


//-----------------------------------------------------------------------------------------------
// Macros
//
#define BIT(x) (1<<(x))



#endif // include_BasicTypes
