//   Class for representing spherical harmonic coefficients
//              G. Le Meur      2000
// DAPNIA/SPP (Saclay) / CEA    LAL - IN2P3/CNRS  (Orsay)

#ifndef ALM_SEEN
#define ALM_SEEN

#include "srandgen.h"
#include "nbmath.h"
#include "triangmtx.h"
#include "tvector.h"

namespace SOPHYA {  

/*! class for the coefficients \f$a_{lm}\f$ of the development of a function defined on a sphere, in spherical harmonics */
template <class T>
class Alm : public TriangularMatrix<complex<T> >
  {
    public :
 
Alm() : TriangularMatrix<complex<T> >()  {;};
    /* instanciate the class from the maximum value of the index \f$l\f$ in the sequence of the \f$a_{lm}\f$'s */
Alm(sa_size_t nlmax) : TriangularMatrix<complex<T> >(nlmax+1) {;}
Alm(const Alm<T>& a,  bool share=false)  : TriangularMatrix<complex<T> >(a, share)  {;}

Alm(const TVector<T>& clin, const r_8 fwhm) ;
/*! resize with a new lmax */
inline void ReSizeToLmax(sa_size_t nlmax) {this->ReSizeRow(nlmax+1);}
inline sa_size_t Lmax() const {return this->rowNumber()-1;}
TVector<T> powerSpectrum() const;

inline  Alm<T>& SetComplexT(complex<T> a)
   {
     this->SetT(a);
     return *this;
   }
 inline Alm<T>& operator = (complex<T> a)
 {
   return SetComplexT(a);
 } 

};
/*! class for a vector with an index running from \f$-m_{max}\f$ to \f$+m_{max}\f$ (then the size of the vector will be actually \f$2m_{max}+1)\f$ */
template <class T>
class Bm
  {
    public :
Bm(): nmmax_(0) {;};
    /* instanciate from the maximum absolute value of the index */
Bm(sa_size_t mmax) : nmmax_(mmax)   { bm_.ReSize( (2*mmax+1) );}
 Bm(const Bm<T>& b,  bool share=false) : nmmax_(b.nmmax_), bm_(b.bm_, share) {;}
 /*! resize with a new value of mmax */
inline void ReSizeToMmax(sa_size_t mmax) 
  {
    nmmax_= mmax;
    bm_.ReSize(2* nmmax_+1);
  }
//inline sa_size_t Size() const {return 2*nmmax_+1;};
inline T& operator()(sa_size_t m) {return bm_( adr_i(m));};
inline T const& operator()(sa_size_t m) const {return *(bm_.Begin()+ adr_i(m));};
/*! return the current value of the maximum absolute value of the index */
inline sa_size_t Mmax() const 
   {
     return nmmax_;
   }
inline Bm<T>& operator = (const Bm<T>& b)
 {
   if (this != &b)
     {
       nmmax_= b.nmmax_;
       bm_=  b.bm_;
     }
   return *this;
 }

  private:
/*! return the address in the array representing the vector */
inline sa_size_t adr_i(sa_size_t i) const 
{
  return (i+nmmax_);
}



 sa_size_t nmmax_;
 NDataBlock<T> bm_;

  };

} // namespace SOPHYA

#endif
