// @(#)root/proof:$Name:  $:$Id: TProofDraw.cxx,v 1.2 2004/07/09 01:34:51 rdm Exp $
// Author: Maarten Ballintijn   24/09/2003

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TProofDraw                                                           //
//                                                                      //
// Implement Tree drawing using PROOF.                                  //
//                                                                      //
//////////////////////////////////////////////////////////////////////////


#include "TProofDraw.h"


#include "TError.h"
#include "TH1F.h"
#include "TStatus.h"
#include "TTreeFormula.h"
#include "TTreeFormulaManager.h"
#include "TTree.h"


ClassImp(TProofDraw)


//______________________________________________________________________________
TProofDraw::TProofDraw()
   : fStatus(0), fManager(0), fSelFormula(0), fVarXFormula(0), fHistogram(0)
{
}


//______________________________________________________________________________
TProofDraw::~TProofDraw()
{
   ClearFormulas();
   // delete fHistogram;
}


//______________________________________________________________________________
void TProofDraw::ClearFormulas()
{
   fManager = 0; // we forget about it, refcounting will do cleanup
   delete fSelFormula; fSelFormula = 0;
   delete fVarXFormula; fVarXFormula = 0;
}


//______________________________________________________________________________
void TProofDraw::Init(TTree *tree)
{
Info("Init","Enter tree = %p", tree);

   ClearFormulas();

   fManager = new TTreeFormulaManager();

   fSelFormula = new TTreeFormula("Selection", fSelection, tree);
   if (fSelFormula->GetNdim() == 0) {
      SetError("Init", Form("selection invalid (%s)", fSelection.Data()));
      ClearFormulas();
      return;
   }

   if (fSelFormula->IsString()) {
      SetError("Init", Form("strings not supported, selection invalid (%s)", fSelection.Data()));
      ClearFormulas();
      return;
   }

   if (fSelFormula->EvalClass() != 0) {
      SetError("Init", Form("Objects not supported, selection invalid (%s)", fSelection.Data()));
      ClearFormulas();
      return;
   }

   fManager->Add(fSelFormula);

fSelFormula->Print();

   fVarXFormula = new TTreeFormula("VarX", fVarX, tree);
   if (fVarXFormula->GetNdim() == 0) {
      SetError("Init", Form("varX invalid (%s)", fVarX.Data()));
      ClearFormulas();
      return;
   }

   if (fVarXFormula->IsString()) {
      SetError("Init", Form("strings not supported, varX invalid (%s)", fVarX.Data()));
      ClearFormulas();
      return;
   }

   if (fVarXFormula->EvalClass() != 0) {
      SetError("Init", Form("Objects not supported, varX invalid (%s)", fVarX.Data()));
      ClearFormulas();
      return;
   }

   fManager->Add(fVarXFormula);

fVarXFormula->Print();

   fManager->Sync();

   fTree = tree;
}


//______________________________________________________________________________
Bool_t TProofDraw::Notify()
{
Info("Notify","Enter");
   if (fStatus == 0) {
      fStatus = dynamic_cast<TStatus*>(fOutput->FindObject("PROOF_Status"));
      Assert(fStatus);
   }

   if (!fStatus->IsOk()) return kFALSE;

   if (fVarXFormula) fVarXFormula->UpdateFormulaLeaves();
   if (fSelFormula) fSelFormula->UpdateFormulaLeaves();
   return kTRUE;
}


//______________________________________________________________________________
void TProofDraw::Begin(TTree *tree)
{
Info("Begin","Enter tree = %p", tree);

   fSelection = fInput->FindObject("selection")->GetTitle();
   fVarX = fInput->FindObject("varexp")->GetTitle();

   Info("Begin","selection: %s", fSelection.Data());
   Info("Begin","varexp: %s", fVarX.Data());

}


//______________________________________________________________________________
void TProofDraw::SlaveBegin(TTree *tree)
{
Info("SlaveBegin","Enter tree = %p", tree);

   fSelection = fInput->FindObject("selection")->GetTitle();
   fVarX = fInput->FindObject("varexp")->GetTitle();

   fHistogram = new TH1F("htemp", Form("%s {%s}", fVarX.Data(), fSelection.Data()),
                          100, 0., 0.);
   fHistogram->SetDirectory(0);   // take ownership
   fOutput->Add(fHistogram);      // release ownership

   Info("Begin","selection: %s", fSelection.Data());
   Info("Begin","varexp: %s", fVarX.Data());
}


//______________________________________________________________________________
Bool_t TProofDraw::Process(int entry)
{
//Info("Process","Enter entry = %d", entry);

   fTree->LoadTree(entry);
   Int_t ndata = fManager->GetNdata();

//Info("Process","ndata = %d", ndata);

   for (Int_t i=0;i<ndata;i++) {
      Double_t w = fSelFormula->EvalInstance(i);

//Info("Process","w[%d] = %f", i, w);

      if (w == 0.0) continue;
      Double_t x = fVarXFormula->EvalInstance(i);

//Info("Process","x[%d] = %f", i, x);
      fHistogram->Fill(x, w);
   }

   return kTRUE;
}


//______________________________________________________________________________
void TProofDraw::SlaveTerminate(void)
{
Info("SlaveTerminate","Enter");

}


//______________________________________________________________________________
void TProofDraw::Terminate(void)
{
Info("Terminate","Enter");
   if (fStatus == 0) {
      fStatus = dynamic_cast<TStatus*>(fOutput->FindObject("PROOF_Status"));
      Assert(fStatus);
   }

   if (!fStatus->IsOk()) {
      fStatus->Print();
      return;
   }

   fHistogram = (TH1F *) fOutput->FindObject("htemp");
   if (fHistogram == 0) {
      Error("Terminate","Did not find histogram?");
      return;
   }

   fHistogram->Draw();
}


//______________________________________________________________________________
void TProofDraw::SetError(const char *sub, const char *mesg)
{
   if (fStatus == 0) {
      fStatus = dynamic_cast<TStatus*>(fOutput->FindObject("PROOF_Status"));
      Assert(fStatus);
   }

   TString m;
   m.Form("%s::%s: %s", IsA()->GetName(), sub, mesg);
   fStatus->Add(m);
}

