// @(#)root/tmva $Id$
// Author: Attila Krasznahorkay, Andreas Hoecker, Joerg Stelzer, Eckhard von Toerne

/**********************************************************************************
 * Project: TMVA - a Root-integrated toolkit for multivariate data analysis       *
 * Package: TMVA                                                                  *
 * Class  : MsgLogger                                                             *
 * Web    : http://tmva.sourceforge.net                                           *
 *                                                                                *
 * Description:                                                                   *
 *      TMVA output logger class producing nicely formatted log messages          *
 *                                                                                *
 * Author:                                                                        *
 *      Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch> - CERN, Switzerland   *
 *      Andreas Hoecker       <Andreas.Hocker@cern.ch> - CERN, Switzerland        *
 *      Joerg Stelzer         <stelzer@cern.ch>        - DESY, Germany            *
 *      Eckhard v. Toerne     <evt@uni-bonn.de>        - U of Bonn, Germany       *
 *                                                                                *
 * Copyright (c) 2005-2011:                                                       *
 *      CERN, Switzerland                                                         *
 *      U. of Victoria, Canada                                                    *
 *      MPI-K Heidelberg, Germany                                                 *
 *      U. of Bonn, Germany                                                       *
 *                                                                                *
 * Redistribution and use in source and binary forms, with or without             *
 * modification, are permitted according to the terms listed in LICENSE           *
 * (http://tmva.sourceforge.net/LICENSE)                                          *
 **********************************************************************************/

#ifndef ROOT_TMVA_MsgLogger
#define ROOT_TMVA_MsgLogger

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// MsgLogger                                                            //
//                                                                      //
// ostringstream derivative to redirect and format output               //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

// STL include(s):
#include <string>
#include <sstream>
#include <iostream>
#include <map>
#if __cplusplus > 199711L
#include <atomic>
#endif

// ROOT include(s)
#ifndef ROOT_TObject
#include "TObject.h"
#endif

#ifndef ROOT_TMVA_Types
#include "TMVA/Types.h"
#endif

// Local include(s):

namespace TMVA {

   class MsgLogger : public std::ostringstream, public TObject {

   public:

      MsgLogger( const TObject* source, EMsgType minType = kINFO );
      MsgLogger( const std::string& source, EMsgType minType = kINFO );
      MsgLogger( EMsgType minType = kINFO );
      MsgLogger( const MsgLogger& parent );
      ~MsgLogger();

      // Accessors
      void        SetSource ( const std::string& source ) { fStrSource = source; }
      EMsgType    GetMinType()                      const { return fMinType; }
      void        SetMinType( EMsgType minType )          { fMinType = minType; }
      std::string GetSource()          const              { return fStrSource; }
      std::string GetPrintedSource()   const;
      std::string GetFormattedSource() const;

      static UInt_t GetMaxSourceSize()                    { return (const UInt_t)fgMaxSourceSize; }

      // Needed for copying
      MsgLogger& operator= ( const MsgLogger& parent );

      // Stream modifier(s)
      static MsgLogger& Endmsg( MsgLogger& logger );
      
      // Accept stream modifiers
      MsgLogger& operator<< ( MsgLogger& ( *_f )( MsgLogger& ) );
      MsgLogger& operator<< ( std::ostream& ( *_f )( std::ostream& ) );
      MsgLogger& operator<< ( std::ios& ( *_f )( std::ios& ) );
      
      // Accept message type specification
      MsgLogger& operator<< ( EMsgType type );
      
      // For all the "conventional" inputs
      template <class T> MsgLogger& operator<< ( T arg ) {
         *(std::ostringstream*)this << arg;
         return *this;
      }

      // Temporaly disables all the loggers (Caution! Use with care !)
      static void  InhibitOutput();
      static void  EnableOutput();

   private:

      // private utility routines
      void Send();
      void InitMaps();
      void WriteMsg( EMsgType type, const std::string& line ) const;

      const TObject*           fObjSource;        // the source TObject (used for name)
      std::string              fStrSource;        // alternative string source
      static const std::string fgPrefix;          // the prefix of the source name
      static const std::string fgSuffix;          // suffix following source name
      EMsgType                 fActiveType;       // active type
      static const UInt_t      fgMaxSourceSize;   // maximum length of source name
#if __cplusplus > 199711L
      static std::atomic<Bool_t> fgOutputSupressed; // disable the output globaly (used by generic booster)
      static std::atomic<Bool_t> fgInhibitOutput;   // flag to suppress all output

      static std::atomic<const std::map<EMsgType, std::string>*> fgTypeMap;   // matches output types with strings
      static std::atomic<const std::map<EMsgType, std::string>*> fgColorMap;  // matches output types with terminal colors
#else
      static Bool_t            fgOutputSupressed; // disable the output globaly (used by generic booster)
      static Bool_t            fgInhibitOutput;   // flag to suppress all output

      static const std::map<EMsgType, std::string>* fgTypeMap;   // matches output types with strings
      static const std::map<EMsgType, std::string>* fgColorMap;  // matches output types with terminal colors
#endif
      EMsgType                                fMinType;    // minimum type for output

      ClassDef(MsgLogger,0) // Ostringstream derivative to redirect and format logging output
   }; // class MsgLogger

   inline MsgLogger& MsgLogger::operator<< ( MsgLogger& (*_f)( MsgLogger& ) )
   {
      return (_f)(*this);
   }

   inline MsgLogger& MsgLogger::operator<< ( std::ostream& (*_f)( std::ostream& ) )
   {
      (_f)(*this);
      return *this;
   }

   inline MsgLogger& MsgLogger::operator<< ( std::ios& ( *_f )( std::ios& ) )
   {
      (_f)(*this);
      return *this;
   }

   inline MsgLogger& MsgLogger::operator<< ( EMsgType type )
   {
      fActiveType = type;
      return *this;
   }

   // Shortcut
   inline MsgLogger& Endl(MsgLogger& ml) { return MsgLogger::Endmsg(ml); }

}

#endif // TMVA_MsgLogger
 MsgLogger.h:1
 MsgLogger.h:2
 MsgLogger.h:3
 MsgLogger.h:4
 MsgLogger.h:5
 MsgLogger.h:6
 MsgLogger.h:7
 MsgLogger.h:8
 MsgLogger.h:9
 MsgLogger.h:10
 MsgLogger.h:11
 MsgLogger.h:12
 MsgLogger.h:13
 MsgLogger.h:14
 MsgLogger.h:15
 MsgLogger.h:16
 MsgLogger.h:17
 MsgLogger.h:18
 MsgLogger.h:19
 MsgLogger.h:20
 MsgLogger.h:21
 MsgLogger.h:22
 MsgLogger.h:23
 MsgLogger.h:24
 MsgLogger.h:25
 MsgLogger.h:26
 MsgLogger.h:27
 MsgLogger.h:28
 MsgLogger.h:29
 MsgLogger.h:30
 MsgLogger.h:31
 MsgLogger.h:32
 MsgLogger.h:33
 MsgLogger.h:34
 MsgLogger.h:35
 MsgLogger.h:36
 MsgLogger.h:37
 MsgLogger.h:38
 MsgLogger.h:39
 MsgLogger.h:40
 MsgLogger.h:41
 MsgLogger.h:42
 MsgLogger.h:43
 MsgLogger.h:44
 MsgLogger.h:45
 MsgLogger.h:46
 MsgLogger.h:47
 MsgLogger.h:48
 MsgLogger.h:49
 MsgLogger.h:50
 MsgLogger.h:51
 MsgLogger.h:52
 MsgLogger.h:53
 MsgLogger.h:54
 MsgLogger.h:55
 MsgLogger.h:56
 MsgLogger.h:57
 MsgLogger.h:58
 MsgLogger.h:59
 MsgLogger.h:60
 MsgLogger.h:61
 MsgLogger.h:62
 MsgLogger.h:63
 MsgLogger.h:64
 MsgLogger.h:65
 MsgLogger.h:66
 MsgLogger.h:67
 MsgLogger.h:68
 MsgLogger.h:69
 MsgLogger.h:70
 MsgLogger.h:71
 MsgLogger.h:72
 MsgLogger.h:73
 MsgLogger.h:74
 MsgLogger.h:75
 MsgLogger.h:76
 MsgLogger.h:77
 MsgLogger.h:78
 MsgLogger.h:79
 MsgLogger.h:80
 MsgLogger.h:81
 MsgLogger.h:82
 MsgLogger.h:83
 MsgLogger.h:84
 MsgLogger.h:85
 MsgLogger.h:86
 MsgLogger.h:87
 MsgLogger.h:88
 MsgLogger.h:89
 MsgLogger.h:90
 MsgLogger.h:91
 MsgLogger.h:92
 MsgLogger.h:93
 MsgLogger.h:94
 MsgLogger.h:95
 MsgLogger.h:96
 MsgLogger.h:97
 MsgLogger.h:98
 MsgLogger.h:99
 MsgLogger.h:100
 MsgLogger.h:101
 MsgLogger.h:102
 MsgLogger.h:103
 MsgLogger.h:104
 MsgLogger.h:105
 MsgLogger.h:106
 MsgLogger.h:107
 MsgLogger.h:108
 MsgLogger.h:109
 MsgLogger.h:110
 MsgLogger.h:111
 MsgLogger.h:112
 MsgLogger.h:113
 MsgLogger.h:114
 MsgLogger.h:115
 MsgLogger.h:116
 MsgLogger.h:117
 MsgLogger.h:118
 MsgLogger.h:119
 MsgLogger.h:120
 MsgLogger.h:121
 MsgLogger.h:122
 MsgLogger.h:123
 MsgLogger.h:124
 MsgLogger.h:125
 MsgLogger.h:126
 MsgLogger.h:127
 MsgLogger.h:128
 MsgLogger.h:129
 MsgLogger.h:130
 MsgLogger.h:131
 MsgLogger.h:132
 MsgLogger.h:133
 MsgLogger.h:134
 MsgLogger.h:135
 MsgLogger.h:136
 MsgLogger.h:137
 MsgLogger.h:138
 MsgLogger.h:139
 MsgLogger.h:140
 MsgLogger.h:141
 MsgLogger.h:142
 MsgLogger.h:143
 MsgLogger.h:144
 MsgLogger.h:145
 MsgLogger.h:146
 MsgLogger.h:147
 MsgLogger.h:148
 MsgLogger.h:149
 MsgLogger.h:150
 MsgLogger.h:151
 MsgLogger.h:152
 MsgLogger.h:153
 MsgLogger.h:154
 MsgLogger.h:155
 MsgLogger.h:156
 MsgLogger.h:157
 MsgLogger.h:158
 MsgLogger.h:159
 MsgLogger.h:160
 MsgLogger.h:161
 MsgLogger.h:162
 MsgLogger.h:163
 MsgLogger.h:164
 MsgLogger.h:165
 MsgLogger.h:166