/** @file psTrace.h
 *  \brief basic run-time trace facilities
 *  \ingroup LogTrace
 *
 *  This file will hold the prototypes for defining procedures to insert
 *  trace messages into the code.
 *
 *  @author Robert Lupton, Princeton University
 *  @author GLG, MHPCC
 *
 *  @version $Revision: 1.28 $ $Name: not supported by cvs2svn $
 *  @date $Date: 2004-11-24 20:12:28 $
 *
 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
 */
#if !defined(PS_TRACE_H)
#define PS_TRACE_H 1

#define PS_UNKNOWN_TRACE_LEVEL -9999   // we don't know this name's level
#define PS_DEFAULT_TRACE_LEVEL -1
#define PS_THE_OTHER_DEFAULT_TRACE_LEVEL 0

/** \addtogroup LogTrace
 *  \{
 */

/** Functions **************************************************************/

//#define PS_NO_TRACE 1   ///< to turn off all tracing

#if defined(PS_NO_TRACE)
#        define psTrace(facil, level, ...) (void)0
/* do nothing */
#        define p_psTrace(facil, level, ...)  (void)0
/* do nothing */
#        define psTraceSetLevel(facil,level) 0
#        define psTraceGetLevel(facil) 0
#        define psTraceReset() (void)0     /* do nothing */
#        define psTraceFree() (void)0      /* do nothing */
#        define psTracePrintLevels() (void)0
/* do nothing */
#        define psTraceSetDestination(fp) (void)0
/* do nothing */
#    else

    /** Basic structure for the component tree.  A component is a string of the
        form aaa.bbb.ccc, and may itself contain further subcomponents.  The
        Component structure doesn't in fact contain it's full name, but only the
        last part. */
    typedef struct p_psComponent
    {
        const char *name;           // last part of name of component
        psS32 level;                  // trace level for this component
        bool p_psSpecified;
        psS32 n;                      // number of subcomponents
        struct p_psComponent* *subcomp;     // next level of subcomponents
    }
p_psComponent;

#ifndef DOXYGEN
/// Send a trace message
void p_psTrace(const char *facil,       ///< facilty of interest
               psS32 myLevel,     ///< desired trace level
               ...)             ///< trace message arguments
;
#endif

/// Set trace level
psBool psTraceSetLevel(const char *facil,     ///< facilty of interest
                       psS32 level)     ///< desired trace level
;

/// Get the trace level
psS32 psTraceGetLevel(const char *facil)     ///< facilty of interest
;

/// Set all trace levels to zero (do not free nodes in the component tree).
void psTraceReset();

/// Free all nodes in the component tree.
void psTraceFree();

/// print trace levels
void psTracePrintLevels(void);

/// Set the destination of future trace messages.
void psTraceSetDestination(FILE * fp);

/* \} */// End of SystemGroup Functions

#define psTrace(facil, level, ...) p_psTrace(facil, level, __VA_ARGS__)
#endif

#endif
