
#include <iostream>
#include <string.h>
#include <map>
#include <vector>

#include "TROOT.h"
#include "TKey.h"
#include "TFile.h"
#include "TCanvas.h"
#include "TH1D.h"
#include "TH2D.h"
#include "TSystem.h"
#include "TTimer.h"

using std::cout;
using std::cerr;
using std::endl;

namespace RichTB
{
  // sleep time in ms
  const int sleepTime = 5000 ;

  typedef std::map<std::string,TCanvas*> CanvasMap;
  static CanvasMap canvasMap;

  static bool OK = true ;
  int maxRuns = 100, nRuns = 0;
  std::string moniFile;
  TTimer timer(sleepTime, kFALSE);

//_____________________________________________________________

  void plotObject( TObject * obj )
  {
    // get canvas for this object
    TCanvas * canvas = canvasMap[ obj->GetName() ];
    if ( NULL == canvas )
    {
      canvasMap[obj->GetName()] = canvas = new TCanvas(obj->GetTitle(),obj->GetName());
    }
    canvas->cd();
    TH1 * th1Obj = (TH1*)obj;
    th1Obj->Draw("zcol");
    canvas->Modified();
    canvas->Update();
    gSystem->ProcessEvents();
  }
//_____________________________________________________________

  void dirScan ( TDirectory* dir )
  {
    dir->cd(); // change searching directory
    TList * olist = dir->GetListOfKeys();
    for ( int oidx = 0; oidx < olist->GetSize(); ++oidx )
    {
      // get objects in this directory
      TKey* key = (TKey*)olist->At(oidx);

      // read object from key
      TObject* obj = key->ReadObj();
      cout << "Found " << obj->ClassName() << " object, id = " << obj->GetName() << endl;
      if (obj->InheritsFrom ("TH1")) 
      {
         TH1* h = (TH1*)obj;
         h->SetDirectory(gROOT);
      // Plot this object on its own canvas
         plotObject( obj );
      }
    }

  }
//_____________________________________________________________

  void updateHists(  ) {
   if (!OK || nRuns >= maxRuns) {
      RichTB::timer.Stop(); 
      // delete canvas
      for ( CanvasMap::iterator i = canvasMap.begin(); i != canvasMap.end(); ++i )
      {
      delete (*i).second;
      }
      canvasMap.clear();
   } else { 
      RichTB::timer.Reset();
     // try to open input file
      TFile * fin = new TFile( moniFile.c_str() );
      if ( fin->IsOpen() )
      {
         cout << "Processing input file : " << fin->GetName() << endl;
         dirScan(gDirectory);
         ++nRuns;
      }
      else
      {
        cout << "WARNING : input file " << fin->GetName() << " does not exist yet" << endl;
      }
      delete fin;
    }
  }
//_____________________________________________________________

  void runMoni()
  {
     moniFile = "hpdOnlineHits.root";
     RichTB::timer.SetCommand("RichTB::updateHists();");
     RichTB::timer.Start();
  }

}


