#ifndef DEBUG_H
#define DEBUG_H

/*
 * $Id: Debug.h 83 2008-05-09 18:00:21Z rosiere $
 *
 * [ Description ]
 * 
 * function to help the debugging :
 *
 *  - debug_tab
 *  - log_printf
 *  - log_begin
 *  - log_end
 *  - breakpoint
 *
 *  Debug's Level :
 *  - None    : print elementary information
 *  - Info    : print basic information
 *  - Trace   : trace internal variable
 *  - Func    : trace call and return function
 *  - All     : print all information
 */

#include "Common/include/Message.h"
#include "Behavioural/include/Debug_component.h"
#include "Behavioural/include/Environment.h"
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <sstream>
#include <string>

enum _debug_verbosity 
  {
    DEBUG_NONE ,
    DEBUG_INFO ,
    DEBUG_TRACE,
    DEBUG_FUNC ,
    DEBUG_ALL
  };

std::string debug_tab     (void);
void        debug_tab_inc (void);
void        debug_tab_dec (void);

#ifdef DEBUG
# define log_printf(level, component, func, str... )			\
  do									\
    {									\
      if ((DEBUG == DEBUG_ALL ) or					\
	  (DEBUG_ ## level == DEBUG_NONE) or				\
	  (( DEBUG_ ## level     <= DEBUG) and				\
	   ( DEBUG_ ## component == true )) )				\
	{								\
	  if (DEBUG >= DEBUG_FUNC)					\
	    {								\
	      msg(_("%s"),debug_tab().c_str());				\
	    }								\
	  if (DEBUG >= DEBUG_ALL )					\
	    {								\
	      switch (DEBUG_ ## level)					\
		{							\
		case DEBUG_NONE  : msg(_("(none       ) ")); break;	\
		case DEBUG_INFO  : msg(_("(information) ")); break;	\
		case DEBUG_TRACE : msg(_("(trace      ) ")); break;	\
		case DEBUG_FUNC  : msg(_("(function   ) ")); break;	\
		case DEBUG_ALL   : msg(_("(all        ) ")); break;	\
		default          : msg(_("(undefine   ) ")); break;	\
		}							\
	    }								\
	  if (DEBUG >= DEBUG_FUNC)					\
	    {								\
	      msg(_("<%s> "),func);					\
	      msg(_("In file %s, "),__FILE__);				\
	      msg(_("at line %d " ),__LINE__);				\
	      msg(_(": "));						\
	    }								\
	  msg(str);							\
	  msg(_("\n"));							\
	  fflush (stdout);						\
	}								\
    } while(0)

# define log_begin(component, func)					\
  do									\
    {									\
      debug_tab_inc ();							\
      log_printf(FUNC,component,func,"Begin");				\
    } while(0)

# define log_end(component, func)					\
  do									\
    {									\
      log_printf(FUNC,component,func,"End");				\
      debug_tab_dec ();							\
    } while(0)

#else
# define log_printf(level, component, func, str... )			\
  do									\
    {									\
    } while(0)

# define log_begin(component, func)					\
  do									\
    {									\
    } while(0)

# define log_end(component, func)					\
  do									\
    {									\
    } while(0)

#endif // DEBUG

#define breakpoint(str...)						\
  do									\
    {									\
      msg(_("Breakpoint : file %s, line %d. Enter Any key to continue\n"),__FILE__,__LINE__); \
      msg(str);								\
      getchar();							\
    } while(0)

#ifdef DEBUG_TEST
#define TEST_PTR(x)							\
  do									\
    {									\
      if (x == NULL)							\
	err(_("%s File %s, Line %d, this pointeur is null\n"),MSG_ERROR,__FILE__,__LINE__); \
    }									\
  while (0)
#else
#define TEST_PTR(x)	 \
  do			 \
    {			 \
    }			 \
  while (0)
#endif


#endif // !DEBUG_H
