#pragma implementation
using namespace std;
#include "hindextable.h"
#include "hlocation.h"
#include "hdebug.h"
#include "Rtypes.h"
#include <iostream> 
#include <iomanip>
ClassImp(HIndexTable)
HIndexTable::HIndexTable(void) {
  
}
HIndexTable::~HIndexTable(void) {
  
}
void HIndexTable::setDimensions(Int_t nDim,Int_t *sizes) {
  
  
  
  
  
  
#if DEBUG_LEVEL>2
  gDebuger->enterFunc("HIndexTable::setDimensions");
  gDebuger->message("nDim= %i",nDim);
#endif
  Int_t prod=1,i=0;
  fSizes.Set(nDim,sizes);
  for (i=0;i<nDim;i++) { prod*=sizes[i];}
#if DEBUG_LEVEL>2
  gDebuger->message("Setting index array");
#endif
  fCompactTable.setCapacity(prod);
  fIndexArray.Set(prod);
  for (Int_t i=0;i<prod;i++) fIndexArray.fArray[i]=-1;
#if DEBUG_LEVEL > 2
  gDebuger->leaveFunc("HIndexTable::setDimensions");
#endif
}
void HIndexTable::Clear(Option_t *) {
  
  
 
  register Int_t i=0;
  for (i=0;i<fCompactTable.getN();i++) {
    fIndexArray.fArray[fCompactTable.getIndex1(i)]=-1;
  }
  fCompactTable.clear();
}
Bool_t HIndexTable::checkLocation(HLocation &aLoc) {
  
  Int_t i;
  for (i=0;i<fSizes.fN;i++) {
    if (aLoc[i]>=fSizes.fArray[i]) return kFALSE;
  }
  return kTRUE;
}
Int_t HIndexTable::gotoLocation(HLocation &aLoc) {
  
  
  
  
  
  
  
  
  Int_t n=1,i=0;
  if (aLoc.getNIndex()==fSizes.fN) 
    n=1;
  else {
    n=1;
    for(i=aLoc.getNIndex();i<fSizes.fN;i++) 
      n*=fSizes[i];
  }
  fCurrentPos=aLoc.getLinearIndex(&fSizes);
  return n;
}
Int_t HIndexTable::gotoBegin(void) {
  
  
  fCurrentPos=0;
  return fIndexArray.fN;
}
Int_t HIndexTable::next(void) {
  
  
  
  
  
  Int_t idx;
  idx=fIndexArray[fCurrentPos];
  if (fCurrentPos<fIndexArray.fN-1) fCurrentPos++;
  return idx;
}
void HIndexTable::Streamer(TBuffer &R__b)
{
   
   if (R__b.IsReading()) {
     Int_t prod=1;
     Version_t R__v = R__b.ReadVersion(); if (R__v) { }
     TObject::Streamer(R__b);
     fSizes.Streamer(R__b);
     if (R__v==1) {
       fIndexArray.Streamer(R__b);
       for (Int_t i=0;i<fSizes.fN;i++) { prod*=fSizes.fArray[i];}
       fCompactTable.setCapacity(prod);
       fCompactTable.clear();
       for (Int_t i=0;i<fIndexArray.fN;i++) {
	 if (fIndexArray.fArray[i]!=-1) {
	   fCompactTable.add(i,fIndexArray.fArray[i]);
	 }
       }
     } else if (R__v==2) {
       for (Int_t i=0;i<fSizes.fN;i++) { prod*=fSizes.fArray[i];}
       fIndexArray.Set(prod);
       for (Int_t i=0;i<prod;i++) fIndexArray.fArray[i]=-1;
       fCompactTable.Streamer(R__b);
       
       for (Int_t i=0;i<fCompactTable.getN();i++) {
	 fIndexArray.fArray[fCompactTable.getIndex1(i)]=
	   (fCompactTable.getIndex2(i) == kMaxUInt)?-1:fCompactTable.getIndex2(i);
       }
     } else {
       Error("Streamer","Object version not known");
     }
   } else {
      R__b.WriteVersion(HIndexTable::IsA());
      TObject::Streamer(R__b);
      fSizes.Streamer(R__b);
      fCompactTable.Streamer(R__b);
   }
}
ClassImp(HPairListI)
void HPairListI::setCapacity(Int_t n) {
  if (fCapacity!=n) {
    fCapacity=n;
    delete[] fArray[0];
    delete[] fArray[1];
    if (fCapacity>0) {
      fArray[0]=new UInt_t[n];
      fArray[1]=new UInt_t[n];
    }
  }
  clear();
}
void HPairListI::Streamer(TBuffer & b) {
  if (b.IsReading()) {
    Int_t cap;
    b >> cap;
    setCapacity(cap);
    b >> fN;
    if (fN>0) {
      b.ReadFastArray(fArray[0],fN);
      b.ReadFastArray(fArray[1],fN);
    }
  } else {
    b << fCapacity;
    b << fN;
    if (fN>0) {
      b.WriteFastArray(fArray[0],fN);
      b.WriteFastArray(fArray[1],fN);
    }
  }
}
void HPairListI::remove(Int_t idx) {
  
}