/*------------------------------------------------------------------------------*/
/** 
 *  \file   GW_Config.h
 *  \brief  Main configuration file.
 *  \author Gabriel Peyr
 *  \date   10-26-2002
 */ 
/*------------------------------------------------------------------------------*/

#ifndef _GW_CONFIG_H_
#define _GW_CONFIG_H_


// #include "stdafx.h"
#include <float.h>
#include <stdio.h>

namespace GW {

#define GW_VERSION 100
#undef WIN32
#define WIN32

//-------------------------------------------------------------------------
/** \name debug & inline directive */
//-------------------------------------------------------------------------
//@{ 
#ifdef _DEBUG
	#ifndef GW_DEBUG
		#define GW_DEBUG
	#endif // GW_DEBUG
#endif // _DEBUG
	
#ifndef GW_DEBUG
	#ifndef GW_USE_INLINE
		#define GW_USE_INLINE
	#endif // GW_USE_INLINE
#endif // GW_DEBUG
	
#ifdef GW_USE_INLINE
	#ifndef GW_INLINE
		#define GW_INLINE inline
	#endif // GWION3D_INLINE
#else
	#ifndef GW_INLINE
		#define GW_INLINE 
	#endif // GW_INLINE	
#endif // GW_USE_INLINE
//@}

//-------------------------------------------------------------------------
/** \name Name space management */
//-------------------------------------------------------------------------
//@{
#define GW_BEGIN_NAMESPACE		namespace GW {
#define GW_END_NAMESPACE		}
//@}
	
	
//-------------------------------------------------------------------------
/** \name Basic types */
//-------------------------------------------------------------------------
//@{
#ifdef __UNIX__
	typedef char					GW_I8;
	typedef unsigned char           GW_U8;
	typedef short					GW_I16;
	typedef unsigned short			GW_U16;
	typedef long                    GW_I32;
	typedef unsigned long           GW_U32;
	typedef long long int           GW_I64;
	typedef unsigned long long int  GW_U64;
	typedef float                   GW_Real32;
	typedef double                  GW_Real64;
	typedef bool                    GW_Bool;
	typedef GW_Real64              GW_Float;
#elif defined (WIN32)
	typedef char                GW_I8;
	typedef unsigned char       GW_U8;
	typedef short				GW_I16;
	typedef unsigned short		GW_U16;
	typedef long                GW_I32;
	typedef unsigned long       GW_U32;
	//typedef __int64             GW_I64;
	//typedef unsigned __int64    GW_U64;
	typedef float               GW_Real32;
	typedef double              GW_Real64;
	typedef bool                GW_Bool;
	typedef GW_Real64			GW_Float;
#elif defined (_PS2_)
	typedef char                GW_I8;
	typedef unsigned char       GW_U8;
	typedef short				GW_I16;
	typedef unsigned short		GW_U16;
	typedef int                 GW_I32;
	typedef unsigned int        GW_U32;
	typedef long long           GW_I64;
	typedef unsigned long long  GW_U64;
	typedef float               GW_Real32;
	typedef double              GW_Real64;
	typedef GW_I8              GW_Bool;
	typedef GW_Real64          GW_Float;
#else
	#error "Unknown architecture !"
#endif
	
	typedef void*				GW_UserData;
	
	/** value returned by function to indicates error GW GW_OK */
	typedef GW_I32 GW_RETURN_CODE;

//@}

//-------------------------------------------------------------------------
/** \name numerical macros */
//-------------------------------------------------------------------------
//@{
#undef		MIN
#undef		MAX
#define		MIN(a, b)       ((a) < (b) ? (a) : (b))			//!<	Returns the min value between a and b
#define		MAX(a, b)       ((a) > (b) ? (a) : (b))			//!<	Returns the max value between a and b
#define		MAXMAX(a,b,c)   ((a) > (b) ? MAX (a,c) : MAX (b,c))
#define		GW_MIN(a, b)       MIN(a,b)						//!<	Returns the min value between a and b
#undef		GW_MAX	// already defined by Windows.h ...
#define		GW_MAX(a, b)       MAX(a,b)						//!<	Returns the max value between a and b
#define		GW_MAXMAX(a,b,c)   MAXMAX(a,b,c)
	
#define GW_SCALE_01(x,rMin,rMax) ((x-rMin)/(rMax-rMin))

#define		GW_ABS(a)       ((a) > 0 ? (a) : -(a))			//!<	Returns the absolute value a
	
#define		SQR(x)			((x)*(x))						//!<	Returns x square
#define		CUBE(x)			((x)*(x)*(x))					//!<	Returns x cube
#define		GW_SQR(x)		SQR(x)							//!<	Returns x square
#define		GW_CUBE(x)		CUBE(x)							//!<	Returns x cube

#define GW_CLAMP_01(x)	if( (x)<0 ) x=0; if( (x)>1 ) x=1
#define GW_CLAMP(x, a,b)	if( (x)<a ) x=a; if( (x)>b ) x=b

#define GW_SWAP(x,y) x^=y; y^=x; x^=y
#define GW_ORDER(x,y) if(x>y){ GW_SWAP(x,y); }
//@}

//-------------------------------------------------------------------------
/** \name generic macros */
//-------------------------------------------------------------------------
//@{
/** a random number in [0-1] */
#undef GW_RAND
#define GW_RAND ((GW_Float) (rand()%10000))/10000
/** a random number in [a,b] */
#define GW_RAND_RANGE(a,b) (a)+((b)-(a))*((GW_Float) (rand()%10000))/10000
/** delete a single pointer */
#define GW_DELETE(p) {if (p!=NULL) delete p; p=NULL;}
/** delete an array pointer */
#define GW_DELETEARRAY(p) {if (p!=NULL) delete [] p; p=NULL;}
//@}

//-------------------------------------------------------------------------
/** \name some constants */
//-------------------------------------------------------------------------
//@{
#define GW_True  true
#define GW_False false
/** to make aproximate computations (derivation, GW_Float comparaisons ...) */
#define GW_EPSILON 1e-9
/** very big number */
#define GW_INFINITE 1e9
/** space coords */
enum GW_Coord_XYZW { X, Y, Z, W };
/** color coords */
enum GW_Coord_RVBA { R, V, B, A };
/** The temporary file we use to launch debug test involving stream I/O */
#define GW_TEST_FILE "test.bin"
//@}

//-------------------------------------------------------------------------
/** \name numerical  constants */
//-------------------------------------------------------------------------
//@{
/** pi */
#define GW_PI		3.1415926535897932384626433832795028841971693993751f
/** pi/2 */
#define GW_HALFPI	1.57079632679489661923f
/** 2*pi */
#define GW_TWOPI	6.28318530717958647692f
/** 1/pi */
#define GW_INVPI	0.31830988618379067154f
/** 180/pi */
#define GW_RADTODEG(x)	(x)*57.2957795130823208768f
/** pi/180 */
#define GW_DEGTORAD(x)	(x)*0.01745329251994329577f
/** e */
#define GW_EXP		2.71828182845904523536f
/** 1/log10(2) */
#define GW_ILOG2	3.32192809488736234787f
/** 1/3 */
#define GW_INV3		0.33333333333333333333f
/** 1/6 */
#define GW_INV6		0.16666666666666666666f
/** 1/9 */
#define GW_INV7		0.14285714285714285714f
/** 1/9 */
#define GW_INV9		0.11111111111111111111f
/** 1/255 */
#define GW_INV255	0.00392156862745098039f
/** sqrt(2) */
#define GW_SQRT2    1.41421356237f
//@}

//-------------------------------------------------------------------------
/** \name assertion macros */
//-------------------------------------------------------------------------
//@{
#ifdef GW_DEBUG
	#define GW_ASSERT(expr) _ASSERT(expr)
	#define GW_DEBUG_ONLY(expr) expr
#else
	#define GW_ASSERT(expr)	// if(!(expr)) cerr << "Error in file " << __FILE__ << " line " << __LINE__ << "." << endl 
	#define GW_DEBUG_ONLY(expr)
#endif // GW_DEBUG
//@}

//-------------------------------------------------------------------------
/** \name GW return codes */
//-------------------------------------------------------------------------
//@{
#define GW_OK							0
#define GW_ERROR						-9
#define GW_Invalid_Argument				-10
#define GW_Unknown_Argument				-11
#define GW_Error_Opening_File			-14
#define GW_Error_File_Not_Supported		-15
#define GW_Error_Argument_OutOfRange	-17
#define GW_Error_Buffer_OverFlow		-18
//@}

//-------------------------------------------------------------------------
/** \name The different kind of transform we suppport for the moment. */
//-------------------------------------------------------------------------
//@{
enum T_WaveletTransformType
{
	T_IntegralDataChunk
};
//@}

/*------------------------------------------------------------------------------*/
/** \name a vector of GW_Float */
/*------------------------------------------------------------------------------*/
//@{
typedef std::vector<GW_Float> T_FloatVector;
typedef T_FloatVector::iterator IT_FloatVector;
typedef T_FloatVector::reverse_iterator RIT_FloatVector;
typedef T_FloatVector::const_iterator CIT_FloatVector;
typedef T_FloatVector::const_reverse_iterator CRIT_FloatVector;
//@}

/*------------------------------------------------------------------------------*/
/** \name a map of GW_Float */
/*------------------------------------------------------------------------------*/
//@{
typedef std::map<GW_U32, GW_Float> T_FloatMap;
typedef T_FloatMap::iterator IT_FloatMap;
typedef T_FloatMap::reverse_iterator RIT_FloatMap;
typedef T_FloatMap::const_iterator CIT_FloatMap;
typedef T_FloatMap::const_reverse_iterator CRIT_FloatMap;
//@}

/*------------------------------------------------------------------------------*/
/** \name a list of string */
/*------------------------------------------------------------------------------*/
//@{
typedef std::list<std::string> T_StringList;
typedef T_StringList::iterator IT_StringList;
typedef T_StringList::reverse_iterator RIT_StringList;
typedef T_StringList::const_iterator CIT_StringList;
typedef T_StringList::const_reverse_iterator CRIT_StringList;
//@}

/*------------------------------------------------------------------------------*/
/** \name a vector of string */
/*------------------------------------------------------------------------------*/
//@{
typedef std::vector<std::string> T_StringVector;
typedef T_StringVector::iterator IT_StringVector;
typedef T_StringVector::reverse_iterator RIT_StringVector;
typedef T_StringVector::const_iterator CIT_StringVector;
typedef T_StringVector::const_reverse_iterator CRIT_StringVector;
//@}

/*------------------------------------------------------------------------------*/
/** \name a map of GW_U32 */
/*------------------------------------------------------------------------------*/
//@{
typedef std::map<GW_U32, GW_U32> T_U32Map;
typedef T_U32Map::iterator IT_U32Map;
typedef T_U32Map::reverse_iterator RIT_U32Map;
typedef T_U32Map::const_iterator CIT_U32Map;
typedef T_U32Map::const_reverse_iterator CRIT_U32Map;
//@}


/*------------------------------------------------------------------------------*/
/** \name a vector of GW_U32 */
/*------------------------------------------------------------------------------*/
//@{
typedef std::vector<GW_U32> T_U32Vector;
typedef T_U32Vector::iterator IT_U32Vector;
typedef T_U32Vector::reverse_iterator RIT_U32Vector;
typedef T_U32Vector::const_iterator CIT_U32Vector;
typedef T_U32Vector::const_reverse_iterator CRIT_U32Vector;
//@}



//-------------------------------------------------------------------------
/** \name Tests for maths operations. */
//-------------------------------------------------------------------------
//@{
inline
void TestMathBit()
{
#if 0
	GW_U32 bit = _clearfp();
	if( bit>1 )
	{
//		GW_ASSERT(GW_False);
		if( (bit&_SW_UNDERFLOW)==_SW_UNDERFLOW )
			cerr << "Math operation problem : underflow." << endl;
		if( (bit&_SW_OVERFLOW)==_SW_OVERFLOW )
			cerr << "Math operation problem : overflow." << endl;
		if( (bit&_SW_ZERODIVIDE)==_SW_ZERODIVIDE )
			cerr << "Math operation problem : zero divide." << endl;
		if( (bit&_SW_INVALID)==_SW_INVALID )
			cerr << "Math operation problem : invalid." << endl;	
	}
#endif
}

#ifdef GW_DEBUG
	#define GW_CHECK_MATHSBIT() TestMathBit()
#else
	#define GW_CHECK_MATHSBIT()
#endif // GW_DEBUG
//@}


/** callback that informs on the evolution of an algorithm */
typedef void (*T_EvolutionCallback)( GW_Float rPerCent, const char* message );

/*------------------------------------------------------------------------------*/
/** \name a vector of GW_NodeMap */
/*------------------------------------------------------------------------------*/
//@{
typedef std::vector<class GW_NodeMap*> T_NodeMapVector;
typedef T_NodeMapVector::iterator IT_NodeMapVector;
typedef T_NodeMapVector::reverse_iterator RIT_NodeMapVector;
typedef T_NodeMapVector::const_iterator CIT_NodeMapVector;
typedef T_NodeMapVector::const_reverse_iterator CRIT_NodeMapVector;
//@}

//-------------------------------------------------------------------------
/** \name output direction. */
//-------------------------------------------------------------------------
//@{
extern string gw_alinea;
extern string gw_endl;
extern FILE* GW_OutputStream;


void GW_OutputComment( const char* str );
//@}


} // End namespace GW

#ifdef GW_DEBUG
#define new new(_NORMAL_BLOCK,__FILE__, __LINE__)
#endif

#endif // _GW_CONFIG_H_


///////////////////////////////////////////////////////////////////////////////
//  Copyright (C) 2009 Gabriel Peyre
