/*****************************************************************************
 * Project: RooFit                                                           *
 * Package: RooFitCore                                                       *
 *    File: $Id: RooMsgService.h,v 1.2 2007/07/13 21:50:24 wouter Exp $
 * Authors:                                                                  *
 *   WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu       *
 *   DK, David Kirkby,    UC Irvine,         dkirkby@uci.edu                 *
 *                                                                           *
 * Copyright (c) 2000-2005, Regents of the University of California          *
 *                          and Stanford University. All rights reserved.    *
 *                                                                           *
 * Redistribution and use in source and binary forms,                        *
 * with or without modification, are permitted according to the terms        *
 * listed in LICENSE (http://roofit.sourceforge.net/license.txt)             *
 *****************************************************************************/
#ifndef ROO_MSG_SERVICE
#define ROO_MSG_SERVICE

#include "Riosfwd.h"
#include <assert.h>
#include "TObject.h"
#include <string>
#include <vector>
#include <stack>
#include <map>
#include "RooCmdArg.h"
#include "RooGlobalFunc.h"
class RooAbsArg ;
class RooWorkspace ;

// Shortcut definitions 
#define coutI(a) RooMsgService::instance().log(this,RooFit::INFO,RooFit::a) 
#define coutP(a) RooMsgService::instance().log(this,RooFit::PROGRESS,RooFit::a) 
#define coutW(a) RooMsgService::instance().log(this,RooFit::WARNING,RooFit::a) 
#define coutE(a) RooMsgService::instance().log(this,RooFit::ERROR,RooFit::a) 
#define coutF(a) RooMsgService::instance().log(this,RooFit::FATAL,RooFit::a) 

#define ccoutD(a) RooMsgService::instance().log(this,RooFit::DEBUG,RooFit::a,kTRUE) 
#define ccoutI(a) RooMsgService::instance().log(this,RooFit::INFO,RooFit::a,kTRUE) 
#define ccoutP(a) RooMsgService::instance().log(this,RooFit::PROGRESS,RooFit::a,kTRUE) 
#define ccoutW(a) RooMsgService::instance().log(this,RooFit::WARNING,RooFit::a,kTRUE) 
#define ccoutE(a) RooMsgService::instance().log(this,RooFit::ERROR,RooFit::a,kTRUE) 
#define ccoutF(a) RooMsgService::instance().log(this,RooFit::FATAL,RooFit::a,kTRUE) 

#define oocoutI(o,a) RooMsgService::instance().log(o,RooFit::INFO,RooFit::a) 
#define oocoutP(o,a) RooMsgService::instance().log(o,RooFit::PROGRESS,RooFit::a) 
#define oocoutW(o,a) RooMsgService::instance().log(o,RooFit::WARNING,RooFit::a) 
#define oocoutE(o,a) RooMsgService::instance().log(o,RooFit::ERROR,RooFit::a) 
#define oocoutF(o,a) RooMsgService::instance().log(o,RooFit::FATAL,RooFit::a) 

#define ooccoutD(o,a) RooMsgService::instance().log(o,RooFit::DEBUG,RooFit::a,kTRUE) 
#define ooccoutI(o,a) RooMsgService::instance().log(o,RooFit::INFO,RooFit::a,kTRUE) 
#define ooccoutP(o,a) RooMsgService::instance().log(o,RooFit::PROGRESS,RooFit::a,kTRUE) 
#define ooccoutW(o,a) RooMsgService::instance().log(o,RooFit::WARNING,RooFit::a,kTRUE) 
#define ooccoutE(o,a) RooMsgService::instance().log(o,RooFit::ERROR,RooFit::a,kTRUE) 
#define ooccoutF(o,a) RooMsgService::instance().log(o,RooFit::FATAL,RooFit::a,kTRUE) 

#ifndef _WIN32
#define ANYDEBUG (RooMsgService::_debugCount>0)
#else
#define ANYDEBUG (RooMsgService::anyDebug())
#endif

#define dologD(a) (ANYDEBUG && RooMsgService::instance().isActive(this,RooFit::a,RooFit::DEBUG))
#define dologI(a) (RooMsgService::instance().isActive(this,RooFit::a,RooFit::INFO))
#define dologP(a) (RooMsgService::instance().isActive(this,RooFit::a,RooFit::PROGRESS))
#define dologW(a) (RooMsgService::instance().isActive(this,RooFit::a,RooFit::WARNING))
#define dologE(a) (RooMsgService::instance().isActive(this,RooFit::a,RooFit::ERROR))
#define dologF(a) (RooMsgService::instance().isActive(this,RooFit::a,RooFit::FATAL))

#define oodologD(o,a) (ANYDEBUG && RooMsgService::instance().isActive(o,RooFit::a,RooFit::DEBUG))
#define oodologI(o,a) (RooMsgService::instance().isActive(o,RooFit::a,RooFit::INFO))
#define oodologP(o,a) (RooMsgService::instance().isActive(o,RooFit::a,RooFit::PROGRESS))
#define oodologW(o,a) (RooMsgService::instance().isActive(o,RooFit::a,RooFit::WARNING))
#define oodologE(o,a) (RooMsgService::instance().isActive(o,RooFit::a,RooFit::ERROR))
#define oodologF(o,a) (RooMsgService::instance().isActive(o,RooFit::a,RooFit::FATAL))

// Shortcuts definitions with conditional execution of print expression -- USE WITH CAUTION 

#define cxcoutD(a) if (ANYDEBUG && RooMsgService::instance().isActive(this,RooFit::a,RooFit::DEBUG)) RooMsgService::instance().log(this,RooFit::DEBUG,RooFit::a) 
#define ccxcoutD(a) if (ANYDEBUG && RooMsgService::instance().isActive(this,RooFit::a,RooFit::DEBUG)) RooMsgService::instance().log(this,RooFit::DEBUG,RooFit::a,kTRUE) 
#define oocxcoutD(o,a) if (ANYDEBUG && RooMsgService::instance().isActive(o,RooFit::a,RooFit::DEBUG)) RooMsgService::instance().log(o,RooFit::DEBUG,RooFit::a) 
#define ooccxcoutD(o,a) if (ANYDEBUG && RooMsgService::instance().isActive(o,RooFit::a,RooFit::DEBUG)) RooMsgService::instance().log(o,RooFit::DEBUG,RooFit::a,kTRUE) 
#define cxcoutI(a) if (RooMsgService::instance().isActive(this,RooFit::a,RooFit::INFO)) RooMsgService::instance().log(this,RooFit::INFO,RooFit::a) 
#define ccxcoutI(a) if (RooMsgService::instance().isActive(this,RooFit::a,RooFit::INFO)) RooMsgService::instance().log(this,RooFit::INFO,RooFit::a,kTRUE) 
#define oocxcoutI(o,a) if (RooMsgService::instance().isActive(o,RooFit::a,RooFit::INFO)) RooMsgService::instance().log(o,RooFit::INFO,RooFit::a) 
#define ooccxcoutI(o,a) if (RooMsgService::instance().isActive(o,RooFit::a,RooFit::INFO)) RooMsgService::instance().log(o,RooFit::INFO,RooFit::a,kTRUE) 
#define cxcoutP(a) if (RooMsgService::instance().isActive(this,RooFit::a,RooFit::PROGRESS)) RooMsgService::instance().log(this,RooFit::INFO,RooFit::a) 
#define ccxcoutP(a) if (RooMsgService::instance().isActive(this,RooFit::a,RooFit::PROGRESS)) RooMsgService::instance().log(this,RooFit::INFO,RooFit::a,kTRUE) 
#define oocxcoutP(o,a) if (RooMsgService::instance().isActive(o,RooFit::a,RooFit::PROGRESS)) RooMsgService::instance().log(o,RooFit::INFO,RooFit::a) 
#define ooccxcoutP(o,a) if (RooMsgService::instance().isActive(o,RooFit::a,RooFit::PROGRESS)) RooMsgService::instance().log(o,RooFit::INFO,RooFit::a,kTRUE) 
#define cxcoutW(a) if (RooMsgService::instance().isActive(this,RooFit::a,RooFit::WARNING)) RooMsgService::instance().log(this,RooFit::WARNING,RooFit::a) 
#define ccxcoutW(a) if (RooMsgService::instance().isActive(this,RooFit::a,RooFit::WARNING)) RooMsgService::instance().log(this,RooFit::WARNING,RooFit::a,kTRUE) 
#define oocxcoutW(o,a) if (RooMsgService::instance().isActive(o,RooFit::a,RooFit::WARNING)) RooMsgService::instance().log(o,RooFit::WARNING,RooFit::a) 
#define ooccxcoutW(o,a) if (RooMsgService::instance().isActive(o,RooFit::a,RooFit::WARNING)) RooMsgService::instance().log(o,RooFit::WARNING,RooFit::a,kTRUE) 
#define cxcoutE(a) if (RooMsgService::instance().isActive(this,RooFit::a,RooFit::ERROR)) RooMsgService::instance().log(this,RooFit::ERROR,RooFit::a) 
#define ccxcoutE(a) if (RooMsgService::instance().isActive(this,RooFit::a,RooFit::ERROR)) RooMsgService::instance().log(this,RooFit::ERROR,RooFit::a,kTRUE) 
#define oocxcoutE(o,a) if (RooMsgService::instance().isActive(o,RooFit::a,RooFit::ERROR)) RooMsgService::instance().log(to,RooFit::ERROR,RooFit::a) 
#define ooccxcoutE(o,a) if (RooMsgService::instance().isActive(o,RooFit::a,RooFit::ERROR)) RooMsgService::instance().log(o,RooFit::ERROR,RooFit::a,kTRUE) 
#define cxcoutF(a) if (RooMsgService::instance().isActive(this,RooFit::a,RooFit::FATAL)) RooMsgService::instance().log(this,RooFit::FATAL,RooFit::a) 
#define ccxcoutF(a) if (RooMsgService::instance().isActive(this,RooFit::a,RooFit::FATAL)) RooMsgService::instance().log(this,RooFit::FATAL,RooFit::a,kTRUE) 
#define oocxcoutF(o,a) if (RooMsgService::instance().isActive(o,RooFit::a,RooFit::FATAL)) RooMsgService::instance().log(o,RooFit::FATAL,RooFit::a) 
#define ooccxcoutF(o,a) if (RooMsgService::instance().isActive(o,RooFit::a,RooFit::FATAL)) RooMsgService::instance().log(o,RooFit::FATAL,RooFit::a,kTRUE) 

class RooMsgService : public TObject {
public:

  virtual ~RooMsgService() ;

  struct StreamConfig {
    public:

    void addTopic(RooFit::MsgTopic newTopic) {
      topic |= newTopic ;
    }

    void removeTopic(RooFit::MsgTopic oldTopic) {
      topic &= ~oldTopic ;
    }


    friend class RooMsgService ;
    
    Bool_t match(RooFit::MsgLevel level, RooFit::MsgTopic facility, const RooAbsArg* obj) ;
    Bool_t match(RooFit::MsgLevel level, RooFit::MsgTopic facility, const TObject* obj) ;
    
    Bool_t active ;
    Bool_t universal ;
    
    RooFit::MsgLevel minLevel ;
    Int_t    topic ;
    std::string objectName ;
    std::string className ;
    std::string baseClassName ;
    std::string tagName ;
    Color_t color ;
    Bool_t prefix ;
    
    std::ostream* os ;

  } ;

  // Access to instance
  static RooMsgService& instance() ;
  static Bool_t anyDebug() ;

  // User interface -- Add or delete reporting streams ;
  Int_t addStream(RooFit::MsgLevel level, const RooCmdArg& arg1=RooCmdArg(), const RooCmdArg& arg2=RooCmdArg(), const RooCmdArg& arg3=RooCmdArg(),
                    		  const RooCmdArg& arg4=RooCmdArg(), const RooCmdArg& arg5=RooCmdArg(), const RooCmdArg& arg6=RooCmdArg()); 
  void deleteStream(Int_t id) ;
  StreamConfig& getStream(Int_t id) { return _streams[id] ; }

  Int_t numStreams() const { return _streams.size() ; }
  void setStreamStatus(Int_t id, Bool_t active) ;
  Bool_t getStreamStatus(Int_t id) const ;

  void reset() { cleanup() ; }

  void setGlobalKillBelow(RooFit::MsgLevel level) { _globMinLevel = level ; }
  RooFit::MsgLevel globalKillBelow() const { return _globMinLevel ; }

  void Print(Option_t *options= 0) const ;
  void showPid(Bool_t flag) { _showPid = flag ; }

  // Back end -- Send message or check if particular logging configuration is active
  std::ostream& log(const RooAbsArg* self, RooFit::MsgLevel level, RooFit::MsgTopic facility, Bool_t forceSkipPrefix=kFALSE) ;
  std::ostream& log(const TObject* self, RooFit::MsgLevel level, RooFit::MsgTopic facility, Bool_t forceSkipPrefix=kFALSE) ;
  Bool_t isActive(const RooAbsArg* self, RooFit::MsgTopic facility, RooFit::MsgLevel level) ;
  Bool_t isActive(const TObject* self, RooFit::MsgTopic facility, RooFit::MsgLevel level) ;

  static Int_t _debugCount ;
  std::map<int,std::string> _levelNames ;
  std::map<int,std::string> _topicNames ;

  static void cleanup() ;

  // Print level support for RooFit-related messages that are not routed through RooMsgService (such as Minuit printouts)
  Bool_t silentMode() const { return _silentMode ; }  
  void setSilentMode(Bool_t flag) { _silentMode = flag ; }

  Int_t errorCount() const { return _errorCount ; }
  void clearErrorCount() { _errorCount = 0 ; }

  void saveState() ; 
  void restoreState() ;
  
  RooWorkspace* debugWorkspace() ;

  Int_t& debugCode() { return _debugCode ; }

protected:

  Int_t activeStream(const RooAbsArg* self, RooFit::MsgTopic facility, RooFit::MsgLevel level) ;
  Int_t activeStream(const TObject* self, RooFit::MsgTopic facility, RooFit::MsgLevel level) ;

  std::vector<StreamConfig> _streams ;
  std::stack<std::vector<StreamConfig> > _streamsSaved ;
  std::ostream* _devnull ;

  std::map<std::string,std::ostream*> _files ;
  RooFit::MsgLevel _globMinLevel ;
  RooFit::MsgLevel _lastMsgLevel ;

  Bool_t _silentMode ; 
  Bool_t _showPid ;

  Int_t _errorCount ;  

  // Private ctor -- singleton class
  RooMsgService() ;
  RooMsgService(const RooMsgService&) ;

  static RooMsgService* _instance ;

  RooWorkspace* _debugWorkspace ;

  Int_t _debugCode ;
  
  ClassDef(RooMsgService,0) // RooFit Message Service Singleton class
};

extern RooMsgService* gMsgService ;

#endif
 RooMsgService.h:1
 RooMsgService.h:2
 RooMsgService.h:3
 RooMsgService.h:4
 RooMsgService.h:5
 RooMsgService.h:6
 RooMsgService.h:7
 RooMsgService.h:8
 RooMsgService.h:9
 RooMsgService.h:10
 RooMsgService.h:11
 RooMsgService.h:12
 RooMsgService.h:13
 RooMsgService.h:14
 RooMsgService.h:15
 RooMsgService.h:16
 RooMsgService.h:17
 RooMsgService.h:18
 RooMsgService.h:19
 RooMsgService.h:20
 RooMsgService.h:21
 RooMsgService.h:22
 RooMsgService.h:23
 RooMsgService.h:24
 RooMsgService.h:25
 RooMsgService.h:26
 RooMsgService.h:27
 RooMsgService.h:28
 RooMsgService.h:29
 RooMsgService.h:30
 RooMsgService.h:31
 RooMsgService.h:32
 RooMsgService.h:33
 RooMsgService.h:34
 RooMsgService.h:35
 RooMsgService.h:36
 RooMsgService.h:37
 RooMsgService.h:38
 RooMsgService.h:39
 RooMsgService.h:40
 RooMsgService.h:41
 RooMsgService.h:42
 RooMsgService.h:43
 RooMsgService.h:44
 RooMsgService.h:45
 RooMsgService.h:46
 RooMsgService.h:47
 RooMsgService.h:48
 RooMsgService.h:49
 RooMsgService.h:50
 RooMsgService.h:51
 RooMsgService.h:52
 RooMsgService.h:53
 RooMsgService.h:54
 RooMsgService.h:55
 RooMsgService.h:56
 RooMsgService.h:57
 RooMsgService.h:58
 RooMsgService.h:59
 RooMsgService.h:60
 RooMsgService.h:61
 RooMsgService.h:62
 RooMsgService.h:63
 RooMsgService.h:64
 RooMsgService.h:65
 RooMsgService.h:66
 RooMsgService.h:67
 RooMsgService.h:68
 RooMsgService.h:69
 RooMsgService.h:70
 RooMsgService.h:71
 RooMsgService.h:72
 RooMsgService.h:73
 RooMsgService.h:74
 RooMsgService.h:75
 RooMsgService.h:76
 RooMsgService.h:77
 RooMsgService.h:78
 RooMsgService.h:79
 RooMsgService.h:80
 RooMsgService.h:81
 RooMsgService.h:82
 RooMsgService.h:83
 RooMsgService.h:84
 RooMsgService.h:85
 RooMsgService.h:86
 RooMsgService.h:87
 RooMsgService.h:88
 RooMsgService.h:89
 RooMsgService.h:90
 RooMsgService.h:91
 RooMsgService.h:92
 RooMsgService.h:93
 RooMsgService.h:94
 RooMsgService.h:95
 RooMsgService.h:96
 RooMsgService.h:97
 RooMsgService.h:98
 RooMsgService.h:99
 RooMsgService.h:100
 RooMsgService.h:101
 RooMsgService.h:102
 RooMsgService.h:103
 RooMsgService.h:104
 RooMsgService.h:105
 RooMsgService.h:106
 RooMsgService.h:107
 RooMsgService.h:108
 RooMsgService.h:109
 RooMsgService.h:110
 RooMsgService.h:111
 RooMsgService.h:112
 RooMsgService.h:113
 RooMsgService.h:114
 RooMsgService.h:115
 RooMsgService.h:116
 RooMsgService.h:117
 RooMsgService.h:118
 RooMsgService.h:119
 RooMsgService.h:120
 RooMsgService.h:121
 RooMsgService.h:122
 RooMsgService.h:123
 RooMsgService.h:124
 RooMsgService.h:125
 RooMsgService.h:126
 RooMsgService.h:127
 RooMsgService.h:128
 RooMsgService.h:129
 RooMsgService.h:130
 RooMsgService.h:131
 RooMsgService.h:132
 RooMsgService.h:133
 RooMsgService.h:134
 RooMsgService.h:135
 RooMsgService.h:136
 RooMsgService.h:137
 RooMsgService.h:138
 RooMsgService.h:139
 RooMsgService.h:140
 RooMsgService.h:141
 RooMsgService.h:142
 RooMsgService.h:143
 RooMsgService.h:144
 RooMsgService.h:145
 RooMsgService.h:146
 RooMsgService.h:147
 RooMsgService.h:148
 RooMsgService.h:149
 RooMsgService.h:150
 RooMsgService.h:151
 RooMsgService.h:152
 RooMsgService.h:153
 RooMsgService.h:154
 RooMsgService.h:155
 RooMsgService.h:156
 RooMsgService.h:157
 RooMsgService.h:158
 RooMsgService.h:159
 RooMsgService.h:160
 RooMsgService.h:161
 RooMsgService.h:162
 RooMsgService.h:163
 RooMsgService.h:164
 RooMsgService.h:165
 RooMsgService.h:166
 RooMsgService.h:167
 RooMsgService.h:168
 RooMsgService.h:169
 RooMsgService.h:170
 RooMsgService.h:171
 RooMsgService.h:172
 RooMsgService.h:173
 RooMsgService.h:174
 RooMsgService.h:175
 RooMsgService.h:176
 RooMsgService.h:177
 RooMsgService.h:178
 RooMsgService.h:179
 RooMsgService.h:180
 RooMsgService.h:181
 RooMsgService.h:182
 RooMsgService.h:183
 RooMsgService.h:184
 RooMsgService.h:185
 RooMsgService.h:186
 RooMsgService.h:187
 RooMsgService.h:188
 RooMsgService.h:189
 RooMsgService.h:190
 RooMsgService.h:191
 RooMsgService.h:192
 RooMsgService.h:193
 RooMsgService.h:194
 RooMsgService.h:195
 RooMsgService.h:196
 RooMsgService.h:197
 RooMsgService.h:198
 RooMsgService.h:199
 RooMsgService.h:200
 RooMsgService.h:201
 RooMsgService.h:202
 RooMsgService.h:203
 RooMsgService.h:204
 RooMsgService.h:205
 RooMsgService.h:206
 RooMsgService.h:207
 RooMsgService.h:208
 RooMsgService.h:209
 RooMsgService.h:210
 RooMsgService.h:211
 RooMsgService.h:212
 RooMsgService.h:213
 RooMsgService.h:214
 RooMsgService.h:215
 RooMsgService.h:216
 RooMsgService.h:217
 RooMsgService.h:218
 RooMsgService.h:219
 RooMsgService.h:220
 RooMsgService.h:221
 RooMsgService.h:222
 RooMsgService.h:223
 RooMsgService.h:224