//----------------------------------------------------
/**
	\file		ctk/inc/dbgwdef.h
	\ingroup	debug
	\ingroup	all

	\brief		Knihovna definic pro ladeni aplikace sledovanim/nastavenim urcenych promenych
				<<< ALL >>>
			
	\author		ConTeK s.r.o., Ing. Petr Cernin
	\version	01.01
	\date		12.01.2007
*/
//----------------------------------------------------

#ifndef _DBGWDEF_H_
#define _DBGWDEF_H_

#include <ctktypes.h>

//----------------------------------------------------
//!	\name	Konstanty pro definovani typu sledovane promene DBGW_ITEM
//@{

#define WT_FUNC			0x80	//!<Priznak funkce

#define WT_TYPE_INT		0x00	//!<int8/16/32/64
#define WT_TYPE_UINT	0x10	//!<uint8/16/32/64
#define WT_TYPE_FLOAT	0x20	//!<float
#define WT_TYPE_BOOL	0x30	//!<float

#define WT_TYPE_MASK	0x70	//!<Maska bitovych priznaku typu

#define WT_SIZE_1		0x00	//!<Velikost 1B
#define WT_SIZE_2		0x01	//!<Velikost 2B
#define WT_SIZE_4		0x03	//!<Velikost 4B
#define WT_SIZE_8		0x07	//!<Velikost 8B

#define WT_SIZE_MASK	0x07	//!<Maska bitovych priznaku velikosti

#define WT_UNKNOWN		WT_TYPE_BOOL | WT_SIZE_8	//!<neznamy typ
//@}

//----------------------------------------------------
//!	Typ univerzalni promene

typedef union
{
	void * var;
	int8_t vint8;
	uint8_t vuint8;
	int16_t vint16;
	uint16_t vuint16;
	int32_t vint32;
	uint32_t vuint32;
	int64_t vint64;
	uint64_t vuint64;
	float_t vfloat;
	bool_t vbool;

} DBGWVAL;

//----------------------------------------------------
//!	Typ ukazatele na funkci navracejici dany typ promene

typedef union
{
	void * var;
	int8_t (* func_int8) ( void );
	uint8_t (* func_uint8) ( void );
	int16_t (* func_int16) ( void );
	uint16_t (* func_uint16) ( void );
	int32_t (* func_int32) ( void );
	uint32_t (* func_uint32) ( void );
	int64_t (* func_int64) ( void );
	uint64_t (* func_uint64) ( void );
	float_t (* func_float) ( void );
	bool_t (* func_bool) ( void );

} DBGWPTR;

//----------------------------------------------------
//!	Polozka sledovane promene

typedef struct
{
	//! Identifikator sledovane promenne
	pvoidptr_t ItemName;
	//! Typ sledovane promenne/hodnoty funkce
	const uint8_t	ItemType;
	//! Ukazatel na promennou/funkci
	DBGWPTR Ptr;

} DBGWITEM;



//----------------------------------------------------
//!	Zahlavi skupiny sledovanych promenych

typedef struct
{
	//! Identifikator bloku
	pvoidptr_t GroupName;

	//! Sledovane promenne bloku

#if defined(MSVC) && !defined(__GNUG__) && !defined(__GNUC__)
 #pragma warning( push )
 #pragma warning( disable: 4200 )
#endif // MSVC

	const DBGWITEM Items[];

#if defined(MSVC) && !defined(__GNUG__) && !defined(__GNUC__)
 #pragma warning( pop )
#endif // MSVC
	
} DBGWGROUP;


//----------------------------------------------------
//!	Zahlavi sledovanych promenych

typedef struct
{
	//! nic tu neni
	const uint8_t x;

#if defined(MSVC) && !defined(__GNUG__) && !defined(__GNUC__)
 #pragma warning( push )
 #pragma warning( disable: 4200 )
#endif // MSVC

	//! Ukazatele na bloky sledovanych promennych
	const DBGWGROUP * Groups[];

#if defined(MSVC) && !defined(__GNUG__) && !defined(__GNUC__)
 #pragma warning( pop )
#endif // MSVC

} DBGWDESC;


//----------------------------------------------------
/**
	\brief	Blok kontrol indexu
*/
//----------------------------------------------------

typedef struct
{
	//!Index bloku
	uint8_t GrpIdx;
	//!Index polozky
	uint8_t ItmCnt;

} DBGWHSDSC;

typedef struct
{
	//! Pocet skupin
	uint8_t GrpCnt;
	//! Cache index
	uint8_t CacheIdx;
	//! Cache tabulka poctu polozek skupin
	DBGWHSDSC GrpItmCnt[ DBGW_CACHE_ITEMCOUNT ];

} DBGWDSC;


#ifdef DBGW_DEBUG

extern DBGWDSC gDBGWI;
extern const DBGWDESC gpDBGW;

//----------------------------------------------------
//!	\name	Makra pro definici polozek
//@{

#define DBGW_VAR_U8( _txtName, _varName ) \
	{  dbgws_##_txtName, WT_TYPE_UINT | WT_SIZE_1, {  (void *) &_varName } },

#define DBGW_VAR_I8( _txtName, _varName ) \
	{ dbgws_##_txtName, WT_TYPE_INT | WT_SIZE_1, {  (void *) &_varName } },

#define DBGW_VAR_U16( _txtName, _varName ) \
	{ dbgws_##_txtName, WT_TYPE_UINT | WT_SIZE_2, {  (void *) &_varName } },

#define DBGW_VAR_I16( _txtName, _varName ) \
	{ dbgws_##_txtName, WT_TYPE_INT | WT_SIZE_2, {  (void *) &_varName } },

#define DBGW_VAR_U32( _txtName, _varName ) \
	{ dbgws_##_txtName, WT_TYPE_UINT | WT_SIZE_4, {  (void *) &_varName } },

#define DBGW_VAR_I32( _txtName, _varName ) \
	{ dbgws_##_txtName, WT_TYPE_INT | WT_SIZE_4, {  (void *) &_varName } },

#define DBGW_VAR_U64( _txtName, _varName ) \
	{ dbgws_##_txtName, WT_TYPE_UINT | WT_SIZE_8, {  (void *) &_varName } },

#define DBGW_VAR_I64( _txtName, _varName ) \
	{ dbgws_##_txtName, WT_TYPE_INT | WT_SIZE_8, {  (void *) &_varName } },

#define DBGW_VAR_FLOAT( _txtName, _varName ) \
	{ dbgws_##_txtName, WT_TYPE_FLOAT | WT_SIZE_4, {  (void *) &_varName } },

#define DBGW_VAR_BOOL( _txtName, _varName ) \
	{ dbgws_##_txtName, WT_TYPE_BOOL | WT_SIZE_1, {  (void *) &_varName } },


#define DBGW_FUN_U8( _txtName, _funcName ) \
	{ dbgws_##_txtName, WT_FUNC | WT_TYPE_UINT | WT_SIZE_1, { &_funcName } },

#define DBGW_FUN_I8( _txtName, _funcName ) \
	{ dbgws_##_txtName, WT_FUNC | WT_TYPE_INT | WT_SIZE_1, { &_funcName } },

#define DBGW_FUN_U16( _txtName, _funcName ) \
	{ dbgws_##_txtName, WT_FUNC | WT_TYPE_UINT | WT_SIZE_2, { &_funcName } },

#define DBGW_FUN_I16( _txtName, _funcName ) \
	{ dbgws_##_txtName, WT_FUNC | WT_TYPE_INT | WT_SIZE_2, { &_funcName } },

#define DBGW_FUN_U32( _txtName, _funcName ) \
	{ dbgws_##_txtName, WT_FUNC | WT_TYPE_UINT | WT_SIZE_4, { &_funcName } },

#define DBGW_FUN_I32( _txtName, _funcName ) \
	{ dbgws_##_txtName, WT_FUNC | WT_TYPE_INT | WT_SIZE_4, { &_funcName } },

#define DBGW_FUN_U64( _txtName, _funcName ) \
	{ dbgws_##_txtName, WT_FUNC | WT_TYPE_UINT | WT_SIZE_8, { &_funcName } },

#define DBGW_FUN_I64( _txtName, _funcName ) \
	{ dbgws_##_txtName, WT_FUNC | WT_TYPE_INT | WT_SIZE_8, { &_funcName } },

#define DBGW_FUN_FLOAT( _txtName, _funcName ) \
	{ dbgws_##_txtName, WT_FUNC | WT_TYPE_FLOAT | WT_SIZE_4, { &_funcName } },

#define DBGW_FUN_BOOL( _txtName, _funcName ) \
	{ dbgws_##_txtName, WT_FUNC | WT_TYPE_BOOL | WT_SIZE_1, { &_funcName } },
//@}

//----------------------------------------------------
//!	\name	Makra pro definici retezcu v programove pameti
//@{

#define DBGW_STR( _name, _text ) \
	static const char_t PCONST dbgws_##_name[] = _text
//@}

//----------------------------------------------------
//!	\name	Makra pro definici skupin
//@{

#define DBGW_GROUP_BEGIN( _groupName, _text ) \
	const char_t PCONST dbgwgs_##_groupName[] = _text; \
	const DBGWGROUP PCONST dbgwn_##_groupName = { dbgwgs_##_groupName, \
		{

#define DBGW_GROUP_END \
			{ NULL, WT_UNKNOWN, { NULL } } \
		} \
	}
//@}

//----------------------------------------------------
//!	\name	Makra pro zpristupneni skupin
//@{

#define DBGW_GROUP( _groupName ) \
	extern const DBGWGROUP PCONST dbgwn_##_groupName
//@}

//----------------------------------------------------
//!	\name	Makra pro vytvoreni struktury gDBGW
//@{

#define DBGW_BEGIN \
	DBGWDSC gDBGWI = { 0, 0, {} }; \
	const DBGWDESC PCONST gpDBGW = { 0, \
		{

#define	DBGW_ADD( _id ) \
			&dbgwn_##_id,

#define DBGW_END \
			NULL \
		} \
	};
//@}

#else // DBGW_DEBUG

//----------------------------------------------------
//! \name	Prazdna makra
//@{

#define DBGW_VAR_U8( _txtName, _varName )
#define DBGW_VAR_I8( _txtName, _varName )
#define DBGW_VAR_U16( _txtName, _varName )
#define DBGW_VAR_I16( _txtName, _varName )
#define DBGW_VAR_U32( _txtName, _varName )
#define DBGW_VAR_I32( _txtName, _varName )
#define DBGW_VAR_U64( _txtName, _varName )
#define DBGW_VAR_I64( _txtName, _varName )
#define DBGW_VAR_FLOAT( _txtName, _varName )
#define DBGW_VAR_BOOL( _txtName, _varName )
#define DBGW_FUN_U8( _txtName, _funcName )
#define DBGW_FUN_I8( _txtName, _funcName )
#define DBGW_FUN_U16( _txtName, _funcName )
#define DBGW_FUN_I16( _txtName, _funcName )
#define DBGW_FUN_U32( _txtName, _funcName )
#define DBGW_FUN_I32( _txtName, _funcName )
#define DBGW_FUN_U64( _txtName, _funcName )
#define DBGW_FUN_I64( _txtName, _funcName )
#define DBGW_FUN_FLOAT( _txtName, _funcName )
#define DBGW_FUN_BOOL( _txtName, _funcName )
#define DBGW_GROUP_END
#define DBGW_BEGIN( _count )
#define	DBGW_ADD( _id )
#define DBGW_END
//@}

#endif // DBGW_DEBUG

/*  pouziti:

typedef struct {
	uint8_t	Pepik;
	uint16_t Jarda[2];
} MYSTRUCT;

MYSTRUCT MyVar;

DBGW_STR( Pepik, "Pepik" )
DBGW_STR( Jarda0, "Jarda[0]" )
DBGW_STR( Jarda1, "Jarda[1]" )

DBGW_GROUP_BEGIN( MyVar, "MyVar", 3 )
	DBGW_VAR_U8( Pepik, MyVar.Pepik )
	DBGW_VAR_U16( Jarda0, MyVar.Jarda[0] )
	DBGW_VAR_U16( Jarda1, MyVar.Jarda[1] )
DBGW_GROUP_END;

DBGW_BEGIN( 1 )
	DBGW_ADD( MyVar )
DBGW_END;

*/

#endif // _DBGDEF_H_
