#ifndef Morpheo_Debug_h
#define Morpheo_Debug_h

/*
 * $Id: Debug.h 138 2010-05-12 17:34:01Z rosiere $
 *
 * [ Description ]
 * 
 * function to help the debugging :
 *
 *  - log_printf
 *  - log_begin
 *  - log_end
 *  - log_function
 *  - msg_print
 *  - 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/Debug_type.h"
#include "Common/include/Systemc.h"
#include "Common/include/Message.h"
#include "Common/include/ChangeCase.h"
#include "Behavioural/include/Debug_component.h"
#include "Behavioural/include/Model.h"
#include "Behavioural/include/Simulation.h"
#include <systemc.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <sstream>
#include <string>
#include "Common/include/MemCheck.h"

namespace morpheo {

// typedef enum 
//   {
//     DEBUG_NONE ,
//     DEBUG_INFO ,
//     DEBUG_TRACE,
//     DEBUG_FUNC ,
//     DEBUG_ALL
//   } debug_verbosity_t;

  extern debug_verbosity_t debug;
  extern bool              debug_cycle_test;
  extern double            debug_cycle_start;
  extern double            debug_cycle_stop ;
  extern double            debug_idle_cycle;
  extern uint32_t          debug_idle_time;

  void        debug_init    (void);
  void        debug_init    (debug_verbosity_t level,
                             double            cycle_start,
                             double            cycle_stop ,
                             double            idle_cycle ,
                             uint32_t          idle_time  );

#ifdef SYSTEMC
#define debug_test_simulation_time                                      \
  (not debug_cycle_test or                                              \
  ((simulation_cycle() >= debug_cycle_start) and                        \
   ((simulation_cycle() <= debug_cycle_stop) or                         \
    (debug_cycle_stop == -1))))
#else
#define debug_test_simulation_time true
#endif
  
#ifdef DEBUG
# define log_printf(level, component, func, str... )			\
  do									\
    {									\
      debug_init();                                                     \
                                                                        \
      if (debug_test_simulation_time and                                \
          (( DEBUG_ ## level <= debug) and                              \
           ( morpheo::behavioural::_model.get_debug(NAME_ ## component)))) \
        {								\
          if (DEBUG_ ## level <= DEBUG_INFO)                            \
            {                                                           \
              msg("%s ",MSG_INFORMATION);                               \
            }                                                           \
          else                                                          \
            {                                                           \
              msg("%s ",MSG_DEBUG);                                     \
            }                                                           \
                                                                        \
          if (debug >= DEBUG_FUNC)					\
            {                                                           \
              msg(  "<%s> " ,func);			        	\
              msg(_("In file %s, "),__FILE__);                          \
              msg(_("at line %d " ),__LINE__);                          \
              msg(  ": " );				        	\
            }                                                           \
          msg(str);					        	\
          msg("\n");                                                    \
        }								\
    } while(0)

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

# define log_end(component, func)					\
  do									\
    {									\
      log_printf(FUNC,component,func,_("End"));				\
    } 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 log_function(component,func,name)                              \
  do									\
    {									\
      log_printf(TRACE,component,func,_("[%d] %s.%s"),static_cast<uint32_t>(simulation_cycle()),name,func); \
    } while(0)


#define msg_printf(type,str...)                                         \
  do                                                                    \
    {                                                                   \
      msg("%s ",MSG_ ## type);                                          \
      msg(str);								\
      msg("\n");							\
    } while(0)


#define breakpoint(str...)						\
  do									\
    {									\
      fmsg(_("%s "),MSG_BREAKPOINT);                                    \
      fmsg(_("Breakpoint in file %s, line %d.\n"),__FILE__,__LINE__);   \
      fmsg(_("%s "),MSG_NONE);                                          \
      fmsg(str);							\
      fmsg(_("\n"));                                                    \
      fmsg(_("%s "),MSG_NONE);                                          \
      fmsg(_("Enter any key to continue\n"));                           \
      getchar();							\
    } while(0)

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

}; // end namespace morpheo
#endif // !DEBUG_H
