// @(#)root/treeviewer:$Name:  $:$Id: TTVSession.cxx,v 1.5 2003/11/25 13:17:33 brun Exp $
//Author : Andrei Gheata   21/02/01

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/


#include "Riostream.h"
#include "TTVSession.h"
#include "TTreeViewer.h"
#include "TTVLVContainer.h"
#include "TClonesArray.h"
#include "TInterpreter.h"


ClassImp(TTVRecord)

//______________________________________________________________________________
TTVRecord::TTVRecord()
{
   // TTVRecord default constructor
   fName = "";
   fScanRedirected = kFALSE;
   fCutEnabled     = kTRUE;
   fUserCode = "";
   fAutoexec = kFALSE;
}
//______________________________________________________________________________
void TTVRecord::ExecuteUserCode()
{
// Execute user-defined code
   if (fUserCode.Length()) {
      char code[250];
      code[0] = 0;
      sprintf(code, "%s", fUserCode.Data());
      gInterpreter->ProcessLine(code);
   }
}
//______________________________________________________________________________
void TTVRecord::FormFrom(TTreeViewer *tv)
{
   if (!tv)  return;
   fX        = tv->ExpressionItem(0)->GetTrueName();
   fXAlias   = tv->ExpressionItem(0)->GetAlias();
   fY        = tv->ExpressionItem(1)->GetTrueName();
   fYAlias   = tv->ExpressionItem(1)->GetAlias();
   fZ        = tv->ExpressionItem(2)->GetTrueName();
   fZAlias   = tv->ExpressionItem(2)->GetAlias();
   fCut      = tv->ExpressionItem(3)->GetTrueName();
   fCutAlias = tv->ExpressionItem(3)->GetAlias();
   fOption   = tv->GetGrOpt();
   fScanRedirected = tv->IsScanRedirected();
   fCutEnabled = tv->IsCutEnabled();
}
//______________________________________________________________________________
void TTVRecord::PlugIn(TTreeViewer *tv)
{
   // Change treeviewer status to this record
   TTVLVEntry *item;
   // change X expression
   item = tv->ExpressionItem(0);
   item->SetExpression(fX.Data(), fXAlias.Data());
   item = tv->ExpressionItem(1);
   item->SetExpression(fY.Data(), fYAlias.Data());
   item = tv->ExpressionItem(2);
   item->SetExpression(fZ.Data(), fZAlias.Data());
   item = tv->ExpressionItem(3);
   item->SetExpression(fCut.Data(), fCutAlias.Data());
   tv->SetGrOpt(fOption.Data());
   tv->SetScanRedirect(fScanRedirected);
   tv->SetCutMode(fCutEnabled);
   if (fCutEnabled)
      item->SetSmallPic(gClient->GetPicture("cut_t.xpm"));
   else
      item->SetSmallPic(gClient->GetPicture("cut-disable_t.xpm"));
}
//______________________________________________________________________________
void TTVRecord::SaveSource(ofstream &out)
{
   char quote = '"';
   out <<"//--- tree viewer record"<<endl;
   out <<"   tv_record = tv_session->AddRecord(kTRUE);"<<endl;
   out <<"   tv_session->SetRecordName("<<quote<<GetName()<<quote<<");"<<endl;
   out <<"   tv_record->fX        = "<<quote<<fX.Data()<<quote<<";"<<endl;
   out <<"   tv_record->fY        = "<<quote<<fY.Data()<<quote<<";"<<endl;
   out <<"   tv_record->fZ        = "<<quote<<fZ.Data()<<quote<<";"<<endl;
   out <<"   tv_record->fCut      = "<<quote<<fCut.Data()<<quote<<";"<<endl;
   out <<"   tv_record->fXAlias   = "<<quote<<fXAlias.Data()<<quote<<";"<<endl;
   out <<"   tv_record->fYAlias   = "<<quote<<fYAlias.Data()<<quote<<";"<<endl;
   out <<"   tv_record->fZAlias   = "<<quote<<fZAlias.Data()<<quote<<";"<<endl;
   out <<"   tv_record->fCutAlias = "<<quote<<fCutAlias.Data()<<quote<<";"<<endl;
   out <<"   tv_record->fOption   = "<<quote<<fOption.Data()<<quote<<";"<<endl;
   if (fScanRedirected)
      out <<"   tv_record->fScanRedirected = kTRUE;"<<endl;
   else
      out <<"   tv_record->fScanRedirected = kFALSE;"<<endl;
   if (fCutEnabled)
      out <<"   tv_record->fCutEnabled = kTRUE;"<<endl;
   else
      out <<"   tv_record->fCutEnabled = kFALSE;"<<endl;
   if (fUserCode.Length()) {
      out <<"   tv_record->SetUserCode(\""<<fUserCode.Data()<<"\");"<<endl;
      if (fAutoexec) {
         out <<"   tv_record->SetAutoexec();"<<endl;
      }
   }
}

ClassImp(TTVSession)

//______________________________________________________________________________
TTVSession::TTVSession(TTreeViewer *tv)
{
   fName    = "";
   fList    = new TClonesArray("TTVRecord", 100); // is 100 enough ?
   fViewer  = tv;
   fCurrent = 0;
   fRecords = 0;
}
//______________________________________________________________________________
TTVSession::~TTVSession()
{
   fList->Delete();
   delete fList;
}
//______________________________________________________________________________
TTVRecord *TTVSession::AddRecord(Bool_t fromFile)
{
   TClonesArray &list = *fList;
   TTVRecord *newrec = new(list[fRecords++])TTVRecord();
   if (!fromFile) newrec->FormFrom(fViewer);
   fCurrent = fRecords - 1;
   if (fRecords > 1) fViewer->ActivateButtons(kTRUE, kTRUE, kFALSE, kTRUE);
   else              fViewer->ActivateButtons(kTRUE, kFALSE, kFALSE, kTRUE);
   if (!fromFile) {
      TString name = "";
      if (strlen(newrec->GetZ())) name += newrec->GetZ();
      if (strlen(newrec->GetY())) {
         if (name.Length()) name += ":";
         name += newrec->GetY();
      }
      if (strlen(newrec->GetX())) {
         if (name.Length()) name += ":";
         name += newrec->GetX();
      }
      SetRecordName(name.Data());
   }      
   return newrec;
}
//______________________________________________________________________________
TTVRecord *TTVSession::GetRecord(Int_t i)
{
   if (!fRecords) return 0;
   fCurrent = i;
   if (i < 0)           fCurrent = 0;
   if (i > fRecords-1)  fCurrent = fRecords - 1;
   if (fCurrent>0 && fCurrent<fRecords-1)
      fViewer->ActivateButtons(kTRUE, kTRUE, kTRUE, kTRUE);
   if (fCurrent == 0) {
      if (fRecords > 1) fViewer->ActivateButtons(kTRUE, kFALSE, kTRUE, kTRUE);
      else              fViewer->ActivateButtons(kTRUE, kFALSE, kFALSE, kTRUE);
   }
   if (fCurrent == fRecords-1) {
      if (fRecords > 1) fViewer->ActivateButtons(kTRUE, kTRUE, kFALSE, kTRUE);
      else              fViewer->ActivateButtons(kTRUE, kFALSE, kFALSE, kTRUE);
   }
   fViewer->SetCurrentRecord(fCurrent);
   return (TTVRecord *)fList->UncheckedAt(fCurrent);
}
//______________________________________________________________________________
void TTVSession::SetRecordName(const char *name)
{
   Int_t crt = fCurrent;
   TTVRecord *current = GetRecord(fCurrent);
   current->SetName(name);
   fViewer->UpdateCombo();
   fCurrent = crt;
   fViewer->SetCurrentRecord(fCurrent);
}
//______________________________________________________________________________
void TTVSession::RemoveLastRecord()
{
//--- Remove current record from list
   if (!fRecords) return;
   TTVRecord *rec = (TTVRecord *)fList->UncheckedAt(fRecords);
   delete rec;
   fList->RemoveAt(fRecords--);
   if (fCurrent > fRecords-1) fCurrent = fRecords - 1;
   Int_t crt = fCurrent;
   fViewer->UpdateCombo();
   fCurrent = crt;
   if (!fRecords) {
      fViewer->ActivateButtons(kFALSE, kFALSE, kFALSE, kFALSE);
      return;
   }
   GetRecord(fCurrent);
}
//______________________________________________________________________________
void TTVSession::Show(TTVRecord *rec)
{
   rec->PlugIn(fViewer);
   fViewer->ExecuteDraw();
   if (rec->HasUserCode() && rec->MustExecuteCode()) rec->ExecuteUserCode();
   fViewer->SetHistogramTitle(rec->GetName());
}
//______________________________________________________________________________
void TTVSession::SaveSource(ofstream &out)
{
   out<<"//--- session object"<<endl;
   out<<"   tv_session = new TTVSession(treeview);"<<endl;
   out<<"   treeview->SetSession(tv_session);"<<endl;
   TTVRecord *record;
   for (Int_t i=0; i<fRecords; i++) {
      record = GetRecord(i);
      record->SaveSource(out);
   }
   out<<"//--- Connect first record"<<endl;
   out<<"   tv_session->First();"<<endl;
}
//______________________________________________________________________________
void TTVSession::UpdateRecord(const char *name)
{
//--- Updates current record according to new X, Y, Z settings
   TTVRecord *current = (TTVRecord *)fList->UncheckedAt(fCurrent);
   current->FormFrom(fViewer);
   SetRecordName(name);
}

