#ifndef  FFTWServer_H_SEEN
#define  FFTWServer_H_SEEN

#include "machdefs.h"
#include "sspvflags.h"
#include "fftservintf.h"


// Classe implementant l'interface FFTServerInterface en 
// utilisant FFTW 

namespace SOPHYA {

#ifdef FFTW_V2_EXTSOP
class FFTWServerPlan;
#endif

class FFTWServer : public FFTServerInterface {
 public:
  FFTWServer(bool preserve_input=true);
  virtual ~FFTWServer();

  
  virtual FFTServerInterface * Clone();

  // Transforme unidimensionnelle , N-dimensionnel  (double precision - r_8)
  virtual void FFTForward(TArray< complex<r_8> > & in, TArray< complex<r_8> > & out);
  virtual void FFTBackward(TArray< complex<r_8> > & in, TArray< complex<r_8> > & out);
  virtual void FFTForward(TArray< r_8 > & in, TArray< complex<r_8> > & out);
  virtual void FFTBackward(TArray< complex<r_8> > & in, TArray< r_8 > & out,
			   bool usoutsz=false);

// Methodes statiques pour reordonner les donnees en 1-D (double precision - r_8)
  static void ReShapetoReal(TArray< complex<r_8> > const & in, TArray< r_8 > & out, bool usz);
  static void ReShapetoCompl(TArray< r_8 > const & in, TArray< complex<r_8> > & out);

#ifdef ALSO_FFTW_FLOAT_EXTSOP 
 /* ---------------------------------------------------------------------------
   Declare and compile single precision (float) version of FFTWServr methods 
   Needs the libfftw3f.a , in addition to libfftw3.a   
   --------------------------------------------------------------------------- */

  // Transforme unidimensionnelle , N-dimensionnel  (single precision - r_4)
  virtual void FFTForward(TArray< complex<r_4> > & in, TArray< complex<r_4> > & out);
  virtual void FFTBackward(TArray< complex<r_4> > & in, TArray< complex<r_4> > & out);
  virtual void FFTForward(TArray< r_4 > & in, TArray< complex<r_4> > & out);
  virtual void FFTBackward(TArray< complex<r_4> > & in, TArray< r_4 > & out,
			   bool usoutsz=false);

// Methodes statiques pour reordonner les donnees en 1-D (single precision - r_4)
  static void ReShapetoReal(TArray< complex<r_4> > const & in, TArray< r_4 > & out, bool usz);
  static void ReShapetoCompl(TArray< r_4 > const & in, TArray< complex<r_4> > & out);
  
#endif

 protected:

#ifndef FFTW_V2_EXTSOP    
/*  For FFTW >= V3  */
 FFTArrayChecker<r_8> ckR8;
 FFTArrayChecker<r_4> ckR4;
 bool _preserve_input; // if true, input arrays not overwritten

#else
/*  For FFTW  V2  */
 FFTWServerPlan * _p1df;
 FFTWServerPlan * _p1db;
 FFTWServerPlan * _pndf;
 FFTWServerPlan * _pndb;

 FFTWServerPlan * _p1drf;
 FFTWServerPlan * _p1drb;
 FFTWServerPlan * _pndrf;
 FFTWServerPlan * _pndrb;

 FFTArrayChecker<r_8> ckR8;
 bool _preserve_input; // if true, input arrays not overwritten

#endif
};

} // Fin du namespace

#endif
