//this file looks like plain C, but it's actually -*- c++ -*-
#ifndef __TQ_LIBRARY__
#define __TQ_LIBRARY__

#include "TString.h"
#include "TMultiGraph.h"
#include "TGraph.h"
#include "TObject.h"

#include <iostream>
#include <stdarg.h>
#include "QFramework/TQStringUtils.h"
#include "QFramework/TQHistogramUtils.h"
#include "QFramework/TQMessageStream.h"
#include <cstdlib>

#if !defined(__CINT__) && !defined(__CLING__)
#ifdef _DEBUG_
#define DEBUG(...) TQLibrary::msgStream.sendMessage (TQMessageStream::DEBUG, __VA_ARGS__)
#define DEBUGfile(...) TQLibrary::msgStream.sendFileLineMessage (TQMessageStream::DEBUG,__FILE__,__LINE__, __VA_ARGS__)
#define DEBUGfunc(...) TQLibrary::msgStream.sendFunctionMessage (TQMessageStream::DEBUG,__FUNCTION__, __VA_ARGS__)
#define DEBUGclass(...) TQLibrary::msgStream.sendClassFunctionMessage (TQMessageStream::DEBUG,Class(),__FUNCTION__,__VA_ARGS__)
#define DEBUGfuncargs(...) TQLibrary::msgStream.sendFunctionArgsMessage (TQMessageStream::DEBUG,__FUNCTION__, __VA_ARGS__)
#define DEBUGclassargs(...) TQLibrary::msgStream.sendClassFunctionArgsMessage (TQMessageStream::DEBUG,Class(),__FUNCTION__,__VA_ARGS__)
#else
#define DEBUG(...)
#define DEBUGfile(...)
#define DEBUGfunc(...)
#define DEBUGclass(...)
#define DEBUGfuncargs(...)
#define DEBUGclassargs(...)
#endif

#define VERBOSE(...) TQLibrary::msgStream.sendMessage (TQMessageStream::VERBOSE, __VA_ARGS__)
#define VERBOSEfile(...) TQLibrary::msgStream.sendFileLineMessage (TQMessageStream::VERBOSE,__FILE__,__LINE__, __VA_ARGS__)
#define VERBOSEfunc(...) TQLibrary::msgStream.sendFunctionMessage (TQMessageStream::VERBOSE,__FUNCTION__, __VA_ARGS__)
#define VERBOSEclass(...) TQLibrary::msgStream.sendClassFunctionMessage (TQMessageStream::VERBOSE,Class(),__FUNCTION__,__VA_ARGS__)
#define VERBOSEfuncargs(...) TQLibrary::msgStream.sendFunctionArgsMessage (TQMessageStream::VERBOSE,__FUNCTION__, __VA_ARGS__)
#define VERBOSEclassargs(...) TQLibrary::msgStream.sendClassFunctionArgsMessage(TQMessageStream::VERBOSE,Class(),__FUNCTION__,__VA_ARGS__)
#define INFO(...) TQLibrary::msgStream.sendMessage (TQMessageStream::INFO, __VA_ARGS__)
#define INFOfile(...) TQLibrary::msgStream.sendFileLineMessage (TQMessageStream::INFO,__FILE__,__LINE__, __VA_ARGS__)
#define INFOfunc(...) TQLibrary::msgStream.sendFunctionMessage (TQMessageStream::INFO,__FUNCTION__, __VA_ARGS__)
#define INFOclass(...) TQLibrary::msgStream.sendClassFunctionMessage (TQMessageStream::INFO,Class(),__FUNCTION__,__VA_ARGS__)
#define INFOfuncargs(...) TQLibrary::msgStream.sendFunctionArgsMessage (TQMessageStream::INFO,__FUNCTION__, __VA_ARGS__)
#define INFOclassargs(...) TQLibrary::msgStream.sendClassFunctionArgsMessage(TQMessageStream::INFO,Class(),__FUNCTION__,__VA_ARGS__)
#define WARN(...) TQLibrary::msgStream.sendMessage (TQMessageStream::WARNING, __VA_ARGS__)
#define WARNfile(...) TQLibrary::msgStream.sendFileLineMessage (TQMessageStream::WARNING,__FILE__,__LINE__, __VA_ARGS__)
#define WARNfunc(...) TQLibrary::msgStream.sendFunctionMessage (TQMessageStream::WARNING,__FUNCTION__, __VA_ARGS__)
#define WARNclass(...) TQLibrary::msgStream.sendClassFunctionMessage (TQMessageStream::WARNING,Class(),__FUNCTION__,__VA_ARGS__)
#define WARNfuncargs(...) TQLibrary::msgStream.sendFunctionArgsMessage (TQMessageStream::WARNING,__FUNCTION__, __VA_ARGS__)
#define WARNclassargs(...) TQLibrary::msgStream.sendClassFunctionArgsMessage(TQMessageStream::WARNING,Class(),__FUNCTION__,__VA_ARGS__)
#define ERROR(...) TQLibrary::msgStream.sendMessage (TQMessageStream::ERROR, __VA_ARGS__)
#define ERRORfile(...) TQLibrary::msgStream.sendFileLineMessage (TQMessageStream::ERROR,__FILE__,__LINE__, __VA_ARGS__)
#define ERRORfunc(...) TQLibrary::msgStream.sendFunctionMessage (TQMessageStream::ERROR,__FUNCTION__, __VA_ARGS__)
#define ERRORclass(...) TQLibrary::msgStream.sendClassFunctionMessage (TQMessageStream::ERROR,Class(),__FUNCTION__,__VA_ARGS__)
#define ERRORfuncargs(...) TQLibrary::msgStream.sendFunctionArgsMessage (TQMessageStream::ERROR,__FUNCTION__, __VA_ARGS__)
#define ERRORclassargs(...) TQLibrary::msgStream.sendClassFunctionArgsMessage(TQMessageStream::ERROR,Class(),__FUNCTION__,__VA_ARGS__)
#define CRITERROR(...) TQLibrary::msgStream.sendMessage (TQMessageStream::CRITICAL, __VA_ARGS__)
#define CRITERRORfile(...) TQLibrary::msgStream.sendFileLineMessage (TQMessageStream::CRITICAL,__FILE__,__LINE__, __VA_ARGS__)
#define CRITERRORfunc(...) TQLibrary::msgStream.sendFunctionMessage (TQMessageStream::CRITICAL,__FUNCTION__, __VA_ARGS__)
#define CRITERRORclass(...) TQLibrary::msgStream.sendClassFunctionMessage (TQMessageStream::CRITICAL,Class(),__FUNCTION__,__VA_ARGS__)
#define CRITERRORfuncargs(...) TQLibrary::msgStream.sendFunctionArgsMessage (TQMessageStream::CRITICAL,__FUNCTION__, __VA_ARGS__)
#define CRITERRORclassargs(...) TQLibrary::msgStream.sendClassFunctionArgsMessage(TQMessageStream::CRITICAL,Class(),__FUNCTION__,__VA_ARGS__)
#define BREAK(...) TQLibrary::msgStream.sendMessage (TQMessageStream::BREAK, __VA_ARGS__)
#define BREAKfile(...) TQLibrary::msgStream.sendFileLineMessage (TQMessageStream::BREAK,__FILE__,__LINE__, __VA_ARGS__)
#define BREAKfunc(...) TQLibrary::msgStream.sendFunctionMessage (TQMessageStream::BREAK,__FUNCTION__, __VA_ARGS__)
#define BREAKclass(...) TQLibrary::msgStream.sendClassFunctionMessage (TQMessageStream::BREAK,Class(),__FUNCTION__,__VA_ARGS__)
#define BREAKfuncargs(...) TQLibrary::msgStream.sendFunctionArgsMessage (TQMessageStream::BREAK,__FUNCTION__, __VA_ARGS__)
#define BREAKclassargs(...) TQLibrary::msgStream.sendClassFunctionArgsMessage(TQMessageStream::BREAK,Class(),__FUNCTION__,__VA_ARGS__)

//more verbose tracebacks in case runtime_errors are thrown within some funtion call. Will catch the error and re-throw it with additional information (message) prepended to the previously thrown error
#define TRY(code,message) try{ code ; } catch (const std::exception& error) { throw std::runtime_error( (TQStringUtils::makePink(TString::Format("[%s, line %i] " , __FILE__, __LINE__ )) + TString(message) + TString(" Preceeding error: \n -> ")+TString(error.what())).Data() ); }

#endif

class TQLibrary {

protected:
  const TString libversion;
  const TString rootversion;
  const TString gccversion;
  TString tqpath;
  TString eosmgmurl;
  TString eoscmd;
  TString localGroupDiskIdentifier;
  TString dq2PathHead;
  TString dCachePathHead;
  TString dq2cmd;
  TString website;
  TString appName;
  TString procStatPath;
  TString workingDirectory;
  TString pdfFontEmbedCommand;
  bool pdfFontEmbedEnabled;
  TString exiftoolPath;
  bool exiftoolEnabled;
  TString libXMLpath;
  int consoleWidth;
  unsigned long timeOfConstruction;
  bool snowflakeMode = false;
  unsigned int maxWarningsAllowed = 0;
  std::vector<unsigned long> rssUsageTimestamps;
  std::vector<size_t> rssUsageMemory;
  std::vector<short> rssUsageColors;
  std::vector<std::string> packages;
  static bool isInitialized;
  static int stdoutfd;
  static int stderrfd;
  static bool stdoutfd_isRedirected;
  static bool stderrfd_isRedirected;
  static bool stdoutfd_allowRedirection;
  static bool stderrfd_allowRedirection;
  static bool stdoutstr_isCaptured;
  static bool stderrstr_isCaptured;
  static bool stdouterrstr_areCaptured;
  static bool stdoutstr_allowCapturing;
  static bool stderrstr_allowCapturing;
  static std::streambuf* defaultStdoutStreamBuf;
  static std::streambuf* defaultStderrStreamBuf;
  static std::stringstream* capturingStdoutStream;
  static std::stringstream* capturingStderrStream;
  static std::stringstream* capturingStdoutStderrStream;

  static TQLibrary gQFramework;

public:

  TQLibrary();
  virtual ~TQLibrary();
  ClassDef(TQLibrary, 0);

  static TQMessageStream msgStream;
  static TQLibrary* getQLibrary();
  static TString getEOScmd();
  void setEOScmd(TString neweoscmd);
  void setEOSurl(TString neweoscmd);
  static void printMessage();
  static const TString& getVersion();
  static int getVersionNumber();
  static const TString& getROOTVersion();
  static float getROOTVersionNumber();
  static const TString& getlibXMLpath();
  static const TString& getGCCVersion();
  static float getGCCVersionNumber();
  static int redirect_stdout(const TString& fname, bool append=false);
  static int redirect_stderr(const TString& fname, bool append=false);
  static int redirect(const TString& fname, bool append=false);
  static int restore_stdout();
  static int restore_stderr();
  static bool restore();
  static int captureStdout();
  static int captureStderr();
  static int captureStdoutStderr();
  static TString readCapturedStdout();
  static int resetCapturedStdout();
  static TString readAndResetCapturedStdout();
  static TString readCapturedStderr();
  static int resetCapturedStderr();
  static TString readAndResetCapturedStderr();
  static TString readCapturedStdoutStderr();
  static int resetCapturedStdoutStderr();
  static TString readAndResetCapturedStdoutStderr();

  static void allowRedirection_stdout(bool allow=true);
  static void allowRedirection_stderr(bool allow=true);
  static void allowRedirection(bool allow=true);
  static void allowCapturing_stdout(bool allow=true);
  static void allowCapturing_stderr(bool allow=true);
  static void allowCapturing(bool allow=true);

  static const TString& getApplicationName();
  void setApplicationName(TString newName);

  static const TString& getProcStatPath();
  void setProcStatPath(TString newpath);

  static const TString& getEXIFtoolPath();
  void setEXIFtoolPath(TString newpath);
  static bool enableEXIFsupport(bool val = true);
  static bool hasEXIFsupport();
  static bool setEXIF(const TString& fname, const TString& title, const TString& keywords = "ROOT ATLAS HSG3");

  static const TString& getPDFfontEmbedCommand();
  void setPDFfontEmbedCommand(TString newpath);
  static bool enablePDFfontEmbedding(bool val = true);
  static bool hasPDFfontEmbedding();
  static bool embedFonts(const TString& filename, bool verbose=false);

  static const TString& getTQPATH();
  void setTQPATH(TString newpath);

  static TString getAbsolutePath(const TString& path);
  static const TString& getWorkingDirectory();
  void setWorkingDirectory(TString newpath);
  static const TString& pwd();
  void cd(TString newpath);

  static const TString& getWebsite();

	static Long64_t getVirtualMemory();
  static void printMemory(); //print memory usage as found in ProcStatPath, likely to only work under linux
  static void recordMemory(short color=1); //adds a point (TQUtils::getCurrentTime(),TQUtils::getCurrentRSS()) to an internal registry. TQUtils::getCurrentRSS uses precompiler statements to provide a mostly platform independent retrieval of memory usage.
  static TMultiGraph* getMemoryGraph(bool differential=false);

  static void setMessageStream(std::ostream& os, bool allowColors = true);
  static void setMessageStream(std::ostream* os = NULL, bool allowColors=true);
  static bool openLogFile(const TString& fname, bool allowColors = false);
  static bool closeLogFile();

  static const TString& getLocalGroupDisk();
  static const TString& getDQ2PathHead();
  static const TString& getdCachePathHead();
  static const TString& getDQ2cmd();
  void setLocalGroupDisk(const TString&);
  void setDQ2PathHead (const TString&);
  void setdCachePathHead(const TString&);
  void setDQ2cmd (const TString&);

  static int getConsoleWidth();
  static void setConsoleWidth(int width);
  void findConsoleWidth();

  static bool hasPackage(const char* pkgname);
  static std::vector<std::string> getListOfPackages();

  static TString findLibrary(const TString& filename);

  static void printGlobMessageCount();
  static void printGlobAlertMessageCount();

  void setSnowflakeMode(bool snowflakeMode, unsigned int maxWarningsAllowed = 0);
  bool getSnowflakeMode();

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