#include "pexceptions.h"
#include "fitsntuple.h"
///////////////////////////////////////////////////////////
//   Les objets delegues pour la gestion de persistance sur fichiers fits 
//    pout NTuple
///////////////////////////////////////////////////////////


#define LONNOM 8
#define LONNOM1  (LONNOM+1)


/*!
  \class SOPHYA::FITS_NTuple
  \ingroup FitsIOServer
  FITS format I/O handler for SOPHYA::NTuple objects.
*/

FITS_NTuple::FITS_NTuple()
{
  dobj_ = new NTuple;
  InitNull();
  ownobj_ = true;
}

FITS_NTuple::FITS_NTuple(char inputfile[],int hdunum)
{
  dobj_ = new NTuple;
  InitNull();
  ownobj_ = true; 

  Read(inputfile,hdunum);
}


FITS_NTuple::FITS_NTuple(const NTuple & obj) 
{ 
  dobj_ = new NTuple(obj);
  InitNull();
  ownobj_ = true; 
}
FITS_NTuple::FITS_NTuple(NTuple* obj) 
{ 
  dobj_ = obj;
  InitNull();
  ownobj_ = false; 
}


FITS_NTuple::~FITS_NTuple()
{
  if (ownobj_ && dobj_ != NULL) delete dobj_;
  //  if (column_ != NULL) delete [] column_;
}

//void FITS_NTuple::Read(char inputfile[],int hdunum)
//{
//  ReadF(inputfile,hdunum);
//}
void FITS_NTuple::ReadLines(char inputfile[],int firstLine, int numberOfLines,int hdunum)
{
  fistLineToBeRead_ = firstLine;
  numberOfLinesToBeRead_ = numberOfLines;
  Read(inputfile,hdunum);
}



//void FITS_NTuple::Write(char outputfile[], bool OldFile)
//{
//  WriteF(outputfile, OldFile);
//}

void FITS_NTuple::ReadFromFits(FitsInFile& is)
{
  if (!is.IsFitsTable())
    {
      throw PException("ReadFromFits: the fits file seems not to be a bintable nor ASCII table");
    }
  int nbcols, nbentries;
  nbcols = is.NbColsFromFits();
  nbentries = 0;
  int k;
  for (k=0; k<nbcols; k++) nbentries=max( nbentries, is.NentriesFromFits(k) );
  
  char ** ColName = new char*[nbcols];
  
  for (k=0; k<nbcols;k++) 
    {
      ColName[k] = new char[LONNOM1]; 
      strncpy(ColName[k], is.ColNameFromFits(k).c_str(),LONNOM);
      ColName[k][LONNOM] =  '\0';
    }
  for (k=0; k<nbcols;k++)
    {
      FitsFile::FitsDataType ss= is.ColTypeFromFits(k);
      string type;
      if (ss !=  FitsFile::FitsDataType_float) 
	{
	  if (ss == FitsFile::FitsDataType_double) type= string("double");
	  else
	    if (ss == FitsFile::FitsDataType_int) type= string("integer");
	    else
	      if (ss == FitsFile::FitsDataType_char) type = string("char*");
	      else
		type = string("unknown");
	  cout << " WARNING: the column " << k << " on fits file is not float but : " << type << endl;
	} 
    }
  if(dobj_ == NULL) 
    { 
      dobj_= new NTuple(nbcols,ColName);
      ownobj_ = true;      
    }
  else 
    {
      dobj_->Clean();
      (*dobj_) = NTuple(nbcols,ColName);
    }
  for (k=0; k<nbcols;k++) 
    {
      delete [] ColName[k];
    }
  delete [] ColName;

  float* ligne = new float[nbcols];

  int firstln, lastln;
  if (numberOfLinesToBeRead_ > 0) 
    {
      firstln = fistLineToBeRead_;
      lastln = firstln + numberOfLinesToBeRead_;
    }
  else
    {
      firstln = 0;
      lastln  = nbentries;
    }
  int numLigne;
  for (numLigne=firstln; numLigne < lastln; numLigne++)
    {
      is.GetBinTabLine(numLigne, ligne);
      dobj_->Fill((r_4*)ligne);
    }
  delete [] ligne;

  dobj_->Info()=is.DVListFromFits();
}

void FITS_NTuple::WriteToFits(FitsOutFile& os) 
{
  if(dobj_ == NULL) 
    {
      cout << " WriteToFits:: dobj_= null " << endl;
      return;
    }

  // table will have 'ncols'  columns
  int ncols = dobj_->NVar();

  // table will have 'nrows' rows
  int nentries = dobj_->NEntry();

  // get names and values from the join DVList object
  DVList dvl= dobj_->Info();
  dvl["Content"]= "NTuple";
  dvl.SetComment("Content", "name of SOPHYA object");
  // extension name
  string extname("NTuple_Binary_tbl"); 

  vector<string> Noms(ncols);   
  int k;
  for (k=0; k< ncols; k++)
    {
      Noms[k]= dobj_->NomIndex(k);
    }

  string type(ncols, 'E');
  vector<int> dummy;

  os.makeHeaderBntblOnFits(type,Noms, nentries, ncols, &dvl, extname, dummy);
   float* column =  new float[nentries];
   for (k=0; k<ncols;k++)
     {
       int j;
       for(j = 0; j < nentries; j++) column[j]= dobj_->GetVal(j,k);
       os.PutColToFits(k, nentries, column);
     }
   delete [] column;

}

