#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>

#include "sopnamsp.h"
#include "histinit.h"
#include "dvlist.h"
#include "fitsswapper.h"
#include "fiosinit.h"
#include "swfitsdtable.h"

#include "datatable.h"
#include "fitshdtable.h"

void test_fdtable() ; 
static long NROW = 64;
static long NPRT = 10;

int main(int narg, char *arg[])
{
  SophyaInit();
  FitsIOServerInit();
  if (narg < 3) {
    cout << "Erreur arg/Usage: tswfits NRowTable NPRT" << endl;
    return 1;
  }
  NROW = atoi(arg[1]);
  NPRT = atoi(arg[2]);
  try {
    test_fdtable();
  }
  catch(PThrowable exc ) {
    cerr << "tswfits-main() , Catched exception: \n" << exc.Msg() << endl;
  }
  catch(std::exception ex) {
    cerr << "tswfits-main() , Catched exception ! " << (string)(ex.what()) << endl;
  }
  catch(...) {
    cerr << "tswfits-main() , Catched ... ! " << endl;
  }
  
}


void test_fdtable() 
{
  cout << "======= test_fdtable:  simple SwapOnFits test ======= " << endl;
    int SWSEGSZ = 4;
    vector<int_8> tags;
    {
      cout << "1/ Creation FITSDataSwapper<double> swout(so) avec swseg.fits " << endl;
      vector<string> ttype, tform, tunit;
      ttype.push_back("D-Col1");
      tform.push_back("D");
      tunit.push_back("");
      //      ttype.push_back("I-Col2");
      //      tform.push_back("J");
      //      tunit.push_back("");
      string tblnm = "SwapMyExt";
      FitsInOutFile fiosc("!swseg.fits", FitsInOutFile::Fits_Create);
      //      fiosc.MoveAbsToHDU(2);
      cout << " DBG-Appel CreateTable ... " << endl;
      fiosc.CreateTable(BINARY_TBL, "rzbintbl", ttype, tform, tunit);
      cout << " ---- Appel a FITSDataSwapper<double> --- " << endl;
      FITSDataSwapper<double> swout(fiosc, 1);
      SwSegDataBlock<double> swsd(swout, SWSEGSZ, 3);
      //      FITSDataSwapper<int_4> swout(&fiosc, 1);
      //      SwSegDataBlock<int_4> swsd(swout, SWSEGSZ, 3);
      double * fp = swsd.GetSegment(0);
      fp[0] = 6.54321;   fp[1] = 65.4321;  fp[2] = 654.321;  fp[3] = 6543.21;
      fp = swsd.GetSegment(1);
      fp[0] = 2.56789;   fp[1] = 25.6789;  fp[2] = 256.789;  fp[3] = 2567.89;
      fp = swsd.GetSegment(2);
      fp[0] = 12.567;   fp[1] = 225.67;  fp[2] = 3256.7;  fp[3] = 42567.;
      tags = swsd.GetSwapPosTagTable();
      cout << " Les pos-tags du FITS NbTag=" << tags.size() << endl;
      for (int kk=0; kk<tags.size(); kk++)  cout << tags[kk] << " ," ;
      cout << endl;
    }
    {
      cout << "2/ Creation FITSDataSwapper<double> avec lecture depuis swseg.fits" << endl;
      FitsInOutFile si("swseg.fits", FitsInOutFile::Fits_RO);
      si.MoveAbsToHDU(2);
      FITSDataSwapper<double> swin(si, 1);
      SwSegDataBlock<double> swsd(swin, tags, SWSEGSZ);
      cout <<"2.b/ Recopie ds SegDataBlock<double> depuis SwSegDataBlock<double> et print" << endl;
      SegDataBlock<double> segd;
      segd = swsd;
      segd.Print(cout, 4, "  ");
    }

    {
      cout << " ------------------------------------------------ " << endl;
      cout << "3/ Creation SwFitsDataTable sur myswtable.fits " << endl;
      FitsInOutFile so("!myswtable.fits", FitsInOutFile::Fits_Create);
      SwFitsDataTable dt(so, 45);
      // define table columns
      dt.AddFloatColumn("X0_f");
      dt.AddFloatColumn("X1_f");
      dt.AddDoubleColumn("X0X0pX1X1_d");
      cout << "3.b/ start fill " << endl;
      // Fill the table
      r_8 x[5];
      int pmod = NROW/50;
      if (pmod < 10) pmod = 10;
      for(int i=0; i<NROW; i++) {
	//	if (i%pmod == 0)  cout << " DBG - i= " << i << endl;
	x[0] = (i%9)-4.;  x[1] = (i/9)-3.;  x[2] = x[0]*x[0]+x[1]*x[1];
	dt.AddLine(x);
      }
      cout << "3.c/ End fill " << endl;
      
      // Printing table info
      cout << dt ;
      for(int k = 0; k<NPRT; k++) 
	cout << "Line[" << k << "] " << dt.LineToString(k) << endl ; 
     
    }
    {
      cout << " ------------------------------------------------ " << endl;
      cout << "4/ Lecture SwFitsDataTable depuis myswtable.fits " << endl;
      FitsInOutFile si("myswtable.fits", FitsInOutFile::Fits_RO);
      si.SkipEmptyFirstHDU();
      SwFitsDataTable dt(si,40,false);
      //      si >> dt;
      // Printing table info
      cout << dt ;
      for(int k = 0; k<NPRT; k++) 
	cout << "Line[" << k << "] " << dt.LineToString(k) << endl ; 
    }

  cout << "============ FIN  test_fdtable ======== ======= " << endl;  
}




