#include "machdefs.h"
#include "fitslocalmap.h" 
///////////////////////////////////////////////////////////
//   Les objets delegues pour la gestion de persistance sur fichiers fits 
//    pout LocalMap
///////////////////////////////////////////////////////////

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

using namespace SOPHYA;

template <class T>
FITS_LocalMap<T>::FITS_LocalMap()
{
  dobj_= NULL;
  ownobj_=false;
}

template <class T>
FITS_LocalMap<T>::FITS_LocalMap(char inputfile[],int hdunum)
{
  dobj_=NULL;
  ownobj_=false; 
  Read(inputfile,hdunum);
}

template <class T>
FITS_LocalMap<T>::FITS_LocalMap(const LocalMap<T> & obj) 
{ 
    dobj_ = new LocalMap<T>(obj);
  ownobj_=true; 
}

template <class T>
FITS_LocalMap<T>::FITS_LocalMap(LocalMap<T> *obj) 
{ 
  dobj_ = obj;
  ownobj_=false; 
}


template <class T>
FITS_LocalMap<T>::~FITS_LocalMap()
{
  if (ownobj_ && dobj_) delete dobj_;
}


template <class T>
AnyDataObj* FITS_LocalMap<T>::DataObj()
{
  return(dobj_);
}


template <class T>
void   FITS_LocalMap<T>::SetDataObj(AnyDataObj & o) 
  {   
    LocalMap<T>* po = dynamic_cast<  LocalMap<T>* >(& o); 
    if (po == NULL) return;
    if (ownobj_ && dobj_) delete dobj_;  
    dobj_ = po; 
    ownobj_ = false; 
  }    

template <class T>
void FITS_LocalMap<T>::ReadFromFits(FitsInFile& is)
{
  if(dobj_ == NULL) 
    {
      dobj_= new LocalMap<T>;
      ownobj_= true;      
    }
  int nbcols, nbentries;
  nbcols = is.NbColsFromFits();
  if (nbcols != 1) 
    {
      throw IOExc("le fichier fits n'est pas une LocalMap");
    }
  DVList dvl=is.DVListFromFits();

  nbentries = is.NentriesFromFits(0);
  int_4 nSzX = dvl.GetI("NSZX");
  int_4 nSzY = dvl.GetI("NSZY");
  int_4 nPix = dvl.GetI("NPIX");
  if (nPix != nbentries)
    {
      throw IOExc("longueur datablock incompatible avec nPix");
    }
  dobj_->ReSize(nSzX, nSzY); 
  int_4 localMappingDone = dvl.GetI("LCMP");
  if (localMappingDone)
    {
      int_4 x0 = dvl.GetI("X0");
      int_4 y0 = dvl.GetI("Y0");
      double theta = dvl.GetD("THETA");
      double phi   = dvl.GetD("PHI");
      double angle = dvl.GetD("ANGLE");
      dobj_->SetOrigin(theta, phi, x0, y0, angle);
      double angleX = dvl.GetD("ANGLEX");
      double angleY = dvl.GetD("ANGLEY");
      dobj_->SetSize(angleX, angleY);
    }
  // On lit les DataBlocks;
  dobj_->DataBlock().ReSize(nPix);
  is.GetSingleColumn(dobj_->DataBlock().Data(),nPix);

  // dvlist de LocalMap
  dobj_->Info()  = is.DVListFromFits();
}

template <class T>
void FITS_LocalMap<T>::WriteToFits(FitsOutFile& os) 
{
  if(dobj_ == NULL) 
    { 
      cout << " WriteToFits:: dobj_= null " << endl;
      return;
    }

  DVList dvl( dobj_->Info() );  
  dvl["NSZX"] = dobj_->Size_x();
  dvl.SetComment("NSZX", "number of pixels in x direction");
  dvl["NSZY"] = dobj_->Size_y();
  dvl.SetComment("NSZY", "number of pixels in y direction");
  dvl["NPIX"] = dobj_->NbPixels();
  dvl.SetComment("NPIX", "number of pixels in local map");

  if(dobj_->LocalMap_isDone())
    {
      dvl["LCMP"] = (int_4) 1;
      dvl.SetComment("LCMP", "local mapping 1= done, 0= not done");
      int_4 x0 = 0;
      int_4 y0 = 0;
      double theta = 0.;
      double  phi = 0.;
      double  angle = 0.;
      dobj_->Origin(theta, phi, x0, y0, angle);
      dvl["X0"]     = x0;
      dvl.SetComment("X0", "number of pixel of the origin, x direction");
      dvl["Y0"]     = y0;
      dvl.SetComment("Y0", "number of pixel of the origin, y direction");
      dvl["THETA"]  = theta;
      dvl.SetComment("THETA", "theta position of the map-origin");
      dvl["PHI"]    = phi;
      dvl.SetComment("PHI", "phi position of the map origin");
      dvl["ANGLE"]  = angle;
      dvl.SetComment("ANGLE", "angle between max x axis and sphere phi-axis");

      double angleX =0.;
      double angleY = 0.;
      dobj_->Aperture(angleX, angleY);
      dvl["ANGLEX"] = angleX;
      dvl.SetComment("ANGLEX", "sphere angle covered by map x-extension ");
      dvl["ANGLEY"] = angleY;
      dvl.SetComment("ANGLEY", "sphere angle covered by map y-extension ");
    }
  else
    {
      dvl["LCMP"] = (int_4) 0;
    }
  dvl["Content"]= "LocalMap";
  dvl.SetComment("Content", "name of SOPHYA object");
  // On ecrit les dataBlocks 
  vector<string> Noms;   
  Noms.push_back(dvl.GetS("Content"));
  string extname("SIMULATION");

  string Type;
  if (typeid(T) == typeid(r_8) ) Type+='D';
  else 
    if (typeid(T) == typeid(r_4) )  Type+='E';
    else
      {
	cout <<  " type de la LocalMap = " <<  typeid(T).name() << endl;
	throw IOExc("FITS_LocalMap:: unknown type");
      }
  vector<int> dummy;
  os.makeHeaderBntblOnFits(Type, Noms, dobj_->NbPixels(), 1, &dvl, extname, dummy);
  os.PutColToFits(0,  dobj_->NbPixels(), dobj_->DataBlock().Data()); 

}

#ifdef __CXX_PRAGMA_TEMPLATES__
#pragma define_template FITS_LocalMap<r_8>
#pragma define_template FITS_LocalMap<r_4>
#pragma define_template FITS_LocalMap<int_4>
#endif
#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
template class FITS_LocalMap<r_8>;
template class FITS_LocalMap<r_4>;
template class FITS_LocalMap<int_4>;
#endif
