//   Class for managing sky scanning
//        R. Ansari , G. Le Meur   1998-2000
// DAPNIA/SPP (Saclay) / CEA    LAL - IN2P3/CNRS  (Orsay)

#ifndef SCAN_H_SEEN
#define SCAN_H_SEEN


#include "ppersist.h"
#include <iostream>
#include "dvlist.h"
#include "ndatablock.h"

namespace SOPHYA {  

class FIO_Scan;

//!   Storage and treatment of data for a scanning of a part of the sky with a set of given values for parameters (see constructor)

class Scan :  public AnyDataObj  {
    friend class FIO_Scan;
  public  :
    /* 
arguments du constructeur : 
  . ouverture (radians), 
  . un tableau de 3 reels (deux angles-en radians- definissant la direction de 
                      l'axe de rotation du satellite + vitesse de rotation 
                      en radians/s),
  . frequence d'echantillonnage (Hz), 
  . instant final de prise de donnees (s),
deux arguments optionnels :
  . instant initial pour la prise de donnees
  . offset d'antenne en angle phi
  */

    /*!
\verbatim
    * Ouv      = aperture angle (rad)
    * Omega[3] = direction of rotation axis of the satellite (teta,phi)
                 and rotation velocity (rad/s)
    * Fech     = sampling frequency  (Hz)
    * T        = total time of data acquistion (s)
    * t0       = starting time (s)
    * phi0     = offset of antenna (rad)
\endverbatim
    */
Scan(float,float*,float,float,float,float);
Scan(const Scan&,  bool share=false );
Scan() { 
  InitNull();
}
~Scan();

// ------------ Persistence handling

//     enum {classId = 0xF003 };
//int_4                  ClassId() const        { return classId; }

//virtual void           WriteSelf(POutPersist&) const;
//virtual void           ReadSelf(PInPersist&);

/*!   Return the number of points in the scan */
int_4     NbPoints() const;
/*!    Return total nomber of turns */
int_4     NbTours() const;
/*!    Return  nomber of points for 1 turn */
int_4     NbPts1Tr() const; 
/*!    Return index of pixel associated to time t */
int_4     ValueIndex(float) const;
/*!    Return  (teta,phi) coordinate of pixel related to time t */
void    Direction(float, float& ,float& );
/*!    Return  (teta,phi) coordinates of  pixel with index k */
void    DirectionIndex(int_4,float& ,float& );
/*!    Return value of pixel with index k */
r_8  & PixelValue(int_4 k) ;
/*!    const version of previous method */
r_8 const & PixelValue(int_4 k) const;

/* Surcharge de la parenthese a un indice entier : remplit ou/et renvoie */
/* la valeur du contenu du pixel d'indice k                              */ 
  
  inline  r_8&    operator()(int_4 k)
                                      { return(PixelValue(k)) ; } ;
  inline  r_8 const &    operator()(int_4 k) const
                                      { return(PixelValue(k)) ; } ;
  Scan& operator = (const Scan& s);
//++
DVList&  Info()
//
//      Renvoie une reference sur l'objet DVList Associe
//--
{  
if (mInfo_ == NULL)  mInfo_ = new DVList;
return(*mInfo_);
}

const DVList*  ptrInfo() const
  {
    return mInfo_;
  }





  private :
    
    //void          Clear();
void          InitNull();

/*  Acces to the DataBlock  */
inline       NDataBlock<r_8>& DataBlock()       {return sPix_;}
inline const NDataBlock<r_8>& DataBlock() const {return sPix_;}

inline  void  SetIntParams(int_4 NmaxPts, int_4 NmaxTrs, int_4 NPts1Tr)
  {
    NmaxPts_=NmaxPts;
    NmaxTrs_=NmaxTrs;
    NPts1Tr_=NPts1Tr;
  }
 inline void SetFloatParams(r_4 Ouverture, r_4 OmegaTeta, r_4 OmegaPhi, 
			    r_4 OmegaRad, r_4 FrequenceEch, r_4 TempsFinal, 
			    r_4 TempsInitial, r_4 PhiZero, r_8* Rota)
   {
     Ouverture_    = Ouverture;
     OmegaTeta_    = OmegaTeta;
     OmegaPhi_     = OmegaPhi;
     OmegaRad_     = OmegaRad;
     FrequenceEch_ = FrequenceEch;
     TempsFinal_   = TempsFinal;
     TempsInitial_ = TempsInitial;
     PhiZero_      = PhiZero;
     for (int k=0; k<9;k++) Rota_[k]=Rota[k];
   }

 inline void GetFloatParams(r_4& Ouverture, r_4& OmegaTeta, r_4& OmegaPhi, 
			    r_4& OmegaRad, r_4& FrequenceEch, r_4& TempsFinal, 
			    r_4& TempsInitial, r_4& PhiZero, r_8* Rota) const
   {
     Ouverture    = Ouverture_;
     OmegaTeta    = OmegaTeta_;
     OmegaPhi     = OmegaPhi_;
     OmegaRad     = OmegaRad_;
     FrequenceEch = FrequenceEch_;
     TempsFinal   = TempsFinal_;
     TempsInitial = TempsInitial_;
     PhiZero      = PhiZero_;
     for (int k=0; k<9;k++) Rota[k]=Rota_[k];
   }


 int_4 NmaxPts_;
 int_4 NmaxTrs_;
 int_4 NPts1Tr_;
 r_4   Ouverture_;
 r_4   OmegaTeta_;     /* direction de l'axe de rotation du satellite */
 r_4   OmegaPhi_;      /* (radians)                                   */
 r_4   OmegaRad_;      /* vitesse de rotation du satellite (radians/s) */
 r_4   FrequenceEch_;  /* frequence d'echantillonnage (Hz)*/
 r_4   TempsFinal_;
 r_4   TempsInitial_;
 r_4   PhiZero_;           /* Offset antenne (radians)  */
 NDataBlock<r_8>  sPix_;   /* valeurs contenues dans chaque pixel */ 
 //r_8*  sPix_;            /* valeurs contenues dans chaque pixel */ 
 r_8   Rota_[9];       /* matrice de passage : [Xf]=[Rota][Xs] */
                      /* Xs : coordonnees dans un systeme lie au satellite*/ 
                      /* Xf : coordonnees dans un repere "fixe"           */ 
 DVList* mInfo_;        // Infos (variables) attachees 
};

// ------------- Classe pour la gestion de persistance --
//!    Delegated objects for persitance management

class FIO_Scan : public PPersist  
{

public:

FIO_Scan(); 
FIO_Scan(string const & filename); 
FIO_Scan(const Scan& obj);
FIO_Scan(Scan* obj);
virtual ~FIO_Scan();
virtual AnyDataObj* DataObj();
inline operator Scan() {return(*dobj); }

protected :

virtual void ReadSelf(PInPersist&);           
virtual void WriteSelf(POutPersist&) const;  
Scan* dobj;
bool ownobj;
};

} // namespace SOPHYA

#endif /* SCAN_H_SEEN */
