// @(#)root/foam:$Id$
// Author: S. Jadach <mailto:Stanislaw.jadach@ifj.edu.pl>, P.Sawicki <mailto:Pawel.Sawicki@ifj.edu.pl>

//_________________________________________________________________________________
//
// Class TFoamCell  used in TFoam
// ==============================
// Objects of this class are hyper-rectangular cells organized in the binary tree.
// Special algorithm for encoding relative positioning of the cells
// allow to save total memory allocation needed for the system of cells.
//
//_________________________________________________________________________________

#include "Riostream.h"
#include "TFoamCell.h"
#include "TFoamVect.h"


ClassImp(TFoamCell);

//________________________________________________________________________________
TFoamCell::TFoamCell()
{
// Default constructor for streamer

   fParent  = 0;
   fDaught0 = 0;
   fDaught1 = 0;
}

//_________________________________________________________________________________
TFoamCell::TFoamCell(Int_t kDim)
{
// User constructor allocating single empty Cell
   if (  kDim >0) {
      //---------=========----------
      fDim     = kDim;
      fSerial   = 0;
      fStatus   = 1;
      fParent   = 0;
      fDaught0  = 0;
      fDaught1  = 0;
      fXdiv     = 0.0;
      fBest     = 0;
      fVolume   = 0.0;
      fIntegral = 0.0;
      fDrive    = 0.0;
      fPrimary  = 0.0;
   } else
      Error("TFoamCell","Dimension has to be >0 \n ");
}

//_________________________________________________________________________________
TFoamCell::TFoamCell(TFoamCell &From): TObject(From)
{
// Copy constructor (not tested!)

   Error("TFoamCell", "+++++ NEVER USE Copy constructor for TFoamCell \n");
   fStatus      = From.fStatus;
   fParent      = From.fParent;
   fDaught0     = From.fDaught0;
   fDaught1     = From.fDaught1;
   fXdiv        = From.fXdiv;
   fBest        = From.fBest;
   fVolume      = From.fVolume;
   fIntegral    = From.fIntegral;
   fDrive       = From.fDrive;
   fPrimary     = From.fPrimary;
}

//___________________________________________________________________________________
TFoamCell::~TFoamCell()
{
// Destructor
}

//___________________________________________________________________________________
TFoamCell& TFoamCell::operator=(const TFoamCell &From)
{
// Substitution operator = (never used)

   Info("TFoamCell", "operator=\n ");
   if (&From == this) return *this;
   fStatus      = From.fStatus;
   fParent      = From.fParent;
   fDaught0     = From.fDaught0;
   fDaught1     = From.fDaught1;
   fXdiv        = From.fXdiv;
   fBest        = From.fBest;
   fVolume      = From.fVolume;
   fIntegral    = From.fIntegral;
   fDrive       = From.fDrive;
   fPrimary     = From.fPrimary;
   return *this;
}


//___________________________________________________________________________________
void TFoamCell::Fill(Int_t Status, TFoamCell *Parent, TFoamCell *Daugh1, TFoamCell *Daugh2)
{
// Fills in certain data into newly allocated cell

   fStatus  = Status;
   fParent  = Parent;
   fDaught0 = Daugh1;
   fDaught1 = Daugh2;
}

////////////////////////////////////////////////////////////////////////////////
//              GETTERS/SETTERS
////////////////////////////////////////////////////////////////////////////////

//_____________________________________________________________________________________
void    TFoamCell::GetHcub( TFoamVect &cellPosi, TFoamVect &cellSize)  const
{
// Provides size and position of the cell
// These parameter are calculated by analyzing information in all parents
// cells up to the root cell. It takes time but saves memory.
   if(fDim<1) return;
   const TFoamCell *pCell,*dCell;
   cellPosi = 0.0; cellSize=1.0; // load all components
   dCell = this;
   while(dCell != 0) {
      pCell = dCell->GetPare();
      if( pCell== 0) break;
      Int_t    kDiv = pCell->fBest;
      Double_t xDivi = pCell->fXdiv;
      if(dCell == pCell->GetDau0()  ) {
         cellSize[kDiv] *=xDivi;
         cellPosi[kDiv] *=xDivi;
      } else if(   dCell == pCell->GetDau1()  ) {
         cellSize[kDiv] *=(1.0-xDivi);
         cellPosi[kDiv]  =cellPosi[kDiv]*(1.0-xDivi)+xDivi;
      } else {
         Error("GetHcub ","Something wrong with linked tree \n");
      }
      dCell=pCell;
   }//while
}//GetHcub

//______________________________________________________________________________________
void    TFoamCell::GetHSize( TFoamVect &cellSize)  const
{
// Provides size of the cell
// Size parameters are calculated by analyzing information in all parents
// cells up to the root cell. It takes time but saves memory.
   if(fDim<1) return;
   const TFoamCell *pCell,*dCell;
   cellSize=1.0; // load all components
   dCell = this;
   while(dCell != 0) {
      pCell = dCell->GetPare();
      if( pCell== 0) break;
      Int_t    kDiv = pCell->fBest;
      Double_t xDivi = pCell->fXdiv;
      if(dCell == pCell->GetDau0() ) {
         cellSize[kDiv]=cellSize[kDiv]*xDivi;
      } else if(dCell == pCell->GetDau1()  ) {
         cellSize[kDiv]=cellSize[kDiv]*(1.0-xDivi);
      } else {
         Error("GetHSize ","Something wrong with linked tree \n");
      }
      dCell=pCell;
   }//while
}//GetHSize

//_________________________________________________________________________________________
void TFoamCell::CalcVolume(void)
{
// Calculates volume of the cell using size params which are calculated

   Int_t k;
   Double_t volu=1.0;
   if(fDim>0) {         // h-cubical subspace
      TFoamVect cellSize(fDim);
      GetHSize(cellSize);
      for(k=0; k<fDim; k++) volu *= cellSize[k];
   }
   fVolume =volu;
}

//__________________________________________________________________________________________
void TFoamCell::Print(Option_t *option) const
{
// Printout of the cell geometry parameters for the debug purpose

   if(!option) Error("Print", "No option set\n");

   std::cout <<  " Status= "<<     fStatus   <<",";
   std::cout <<  " Volume= "<<     fVolume   <<",";
   std::cout <<  " TrueInteg= " << fIntegral <<",";
   std::cout <<  " DriveInteg= "<< fDrive    <<",";
   std::cout <<  " PrimInteg= " << fPrimary  <<",";
   std::cout<< std::endl;
   std::cout <<  " Xdiv= "<<fXdiv<<",";
   std::cout <<  " Best= "<<fBest<<",";
   std::cout <<  " Parent=  {"<< (GetPare() ? GetPare()->GetSerial() : -1) <<"} "; // extra DEBUG
   std::cout <<  " Daught0= {"<< (GetDau0() ? GetDau0()->GetSerial() : -1 )<<"} "; // extra DEBUG
   std::cout <<  " Daught1= {"<< (GetDau1() ? GetDau1()->GetSerial()  : -1 )<<"} "; // extra DEBUG
   std::cout<< std::endl;
   //
   //
   if(fDim>0 ) {
      TFoamVect cellPosi(fDim); TFoamVect cellSize(fDim);
      GetHcub(cellPosi,cellSize);
      std::cout <<"   Posi= "; cellPosi.Print("1"); std::cout<<","<< std::endl;
      std::cout <<"   Size= "; cellSize.Print("1"); std::cout<<","<< std::endl;
   }
}
///////////////////////////////////////////////////////////////////
//        End of  class  TFoamCell                               //
///////////////////////////////////////////////////////////////////
 TFoamCell.cxx:1
 TFoamCell.cxx:2
 TFoamCell.cxx:3
 TFoamCell.cxx:4
 TFoamCell.cxx:5
 TFoamCell.cxx:6
 TFoamCell.cxx:7
 TFoamCell.cxx:8
 TFoamCell.cxx:9
 TFoamCell.cxx:10
 TFoamCell.cxx:11
 TFoamCell.cxx:12
 TFoamCell.cxx:13
 TFoamCell.cxx:14
 TFoamCell.cxx:15
 TFoamCell.cxx:16
 TFoamCell.cxx:17
 TFoamCell.cxx:18
 TFoamCell.cxx:19
 TFoamCell.cxx:20
 TFoamCell.cxx:21
 TFoamCell.cxx:22
 TFoamCell.cxx:23
 TFoamCell.cxx:24
 TFoamCell.cxx:25
 TFoamCell.cxx:26
 TFoamCell.cxx:27
 TFoamCell.cxx:28
 TFoamCell.cxx:29
 TFoamCell.cxx:30
 TFoamCell.cxx:31
 TFoamCell.cxx:32
 TFoamCell.cxx:33
 TFoamCell.cxx:34
 TFoamCell.cxx:35
 TFoamCell.cxx:36
 TFoamCell.cxx:37
 TFoamCell.cxx:38
 TFoamCell.cxx:39
 TFoamCell.cxx:40
 TFoamCell.cxx:41
 TFoamCell.cxx:42
 TFoamCell.cxx:43
 TFoamCell.cxx:44
 TFoamCell.cxx:45
 TFoamCell.cxx:46
 TFoamCell.cxx:47
 TFoamCell.cxx:48
 TFoamCell.cxx:49
 TFoamCell.cxx:50
 TFoamCell.cxx:51
 TFoamCell.cxx:52
 TFoamCell.cxx:53
 TFoamCell.cxx:54
 TFoamCell.cxx:55
 TFoamCell.cxx:56
 TFoamCell.cxx:57
 TFoamCell.cxx:58
 TFoamCell.cxx:59
 TFoamCell.cxx:60
 TFoamCell.cxx:61
 TFoamCell.cxx:62
 TFoamCell.cxx:63
 TFoamCell.cxx:64
 TFoamCell.cxx:65
 TFoamCell.cxx:66
 TFoamCell.cxx:67
 TFoamCell.cxx:68
 TFoamCell.cxx:69
 TFoamCell.cxx:70
 TFoamCell.cxx:71
 TFoamCell.cxx:72
 TFoamCell.cxx:73
 TFoamCell.cxx:74
 TFoamCell.cxx:75
 TFoamCell.cxx:76
 TFoamCell.cxx:77
 TFoamCell.cxx:78
 TFoamCell.cxx:79
 TFoamCell.cxx:80
 TFoamCell.cxx:81
 TFoamCell.cxx:82
 TFoamCell.cxx:83
 TFoamCell.cxx:84
 TFoamCell.cxx:85
 TFoamCell.cxx:86
 TFoamCell.cxx:87
 TFoamCell.cxx:88
 TFoamCell.cxx:89
 TFoamCell.cxx:90
 TFoamCell.cxx:91
 TFoamCell.cxx:92
 TFoamCell.cxx:93
 TFoamCell.cxx:94
 TFoamCell.cxx:95
 TFoamCell.cxx:96
 TFoamCell.cxx:97
 TFoamCell.cxx:98
 TFoamCell.cxx:99
 TFoamCell.cxx:100
 TFoamCell.cxx:101
 TFoamCell.cxx:102
 TFoamCell.cxx:103
 TFoamCell.cxx:104
 TFoamCell.cxx:105
 TFoamCell.cxx:106
 TFoamCell.cxx:107
 TFoamCell.cxx:108
 TFoamCell.cxx:109
 TFoamCell.cxx:110
 TFoamCell.cxx:111
 TFoamCell.cxx:112
 TFoamCell.cxx:113
 TFoamCell.cxx:114
 TFoamCell.cxx:115
 TFoamCell.cxx:116
 TFoamCell.cxx:117
 TFoamCell.cxx:118
 TFoamCell.cxx:119
 TFoamCell.cxx:120
 TFoamCell.cxx:121
 TFoamCell.cxx:122
 TFoamCell.cxx:123
 TFoamCell.cxx:124
 TFoamCell.cxx:125
 TFoamCell.cxx:126
 TFoamCell.cxx:127
 TFoamCell.cxx:128
 TFoamCell.cxx:129
 TFoamCell.cxx:130
 TFoamCell.cxx:131
 TFoamCell.cxx:132
 TFoamCell.cxx:133
 TFoamCell.cxx:134
 TFoamCell.cxx:135
 TFoamCell.cxx:136
 TFoamCell.cxx:137
 TFoamCell.cxx:138
 TFoamCell.cxx:139
 TFoamCell.cxx:140
 TFoamCell.cxx:141
 TFoamCell.cxx:142
 TFoamCell.cxx:143
 TFoamCell.cxx:144
 TFoamCell.cxx:145
 TFoamCell.cxx:146
 TFoamCell.cxx:147
 TFoamCell.cxx:148
 TFoamCell.cxx:149
 TFoamCell.cxx:150
 TFoamCell.cxx:151
 TFoamCell.cxx:152
 TFoamCell.cxx:153
 TFoamCell.cxx:154
 TFoamCell.cxx:155
 TFoamCell.cxx:156
 TFoamCell.cxx:157
 TFoamCell.cxx:158
 TFoamCell.cxx:159
 TFoamCell.cxx:160
 TFoamCell.cxx:161
 TFoamCell.cxx:162
 TFoamCell.cxx:163
 TFoamCell.cxx:164
 TFoamCell.cxx:165
 TFoamCell.cxx:166
 TFoamCell.cxx:167
 TFoamCell.cxx:168
 TFoamCell.cxx:169
 TFoamCell.cxx:170
 TFoamCell.cxx:171
 TFoamCell.cxx:172
 TFoamCell.cxx:173
 TFoamCell.cxx:174
 TFoamCell.cxx:175
 TFoamCell.cxx:176
 TFoamCell.cxx:177
 TFoamCell.cxx:178
 TFoamCell.cxx:179
 TFoamCell.cxx:180
 TFoamCell.cxx:181
 TFoamCell.cxx:182
 TFoamCell.cxx:183
 TFoamCell.cxx:184
 TFoamCell.cxx:185
 TFoamCell.cxx:186
 TFoamCell.cxx:187
 TFoamCell.cxx:188
 TFoamCell.cxx:189
 TFoamCell.cxx:190
 TFoamCell.cxx:191
 TFoamCell.cxx:192
 TFoamCell.cxx:193
 TFoamCell.cxx:194
 TFoamCell.cxx:195
 TFoamCell.cxx:196
 TFoamCell.cxx:197
 TFoamCell.cxx:198
 TFoamCell.cxx:199
 TFoamCell.cxx:200
 TFoamCell.cxx:201
 TFoamCell.cxx:202
 TFoamCell.cxx:203
 TFoamCell.cxx:204
 TFoamCell.cxx:205
 TFoamCell.cxx:206
 TFoamCell.cxx:207
 TFoamCell.cxx:208
 TFoamCell.cxx:209
 TFoamCell.cxx:210
 TFoamCell.cxx:211
 TFoamCell.cxx:212