//   FFT (Fast Fourier Transform) Server based on FFTPack
//        R. Ansari     1999-2000
// DAPNIA/SPP (Saclay) / CEA    LAL - IN2P3/CNRS  (Orsay)

#ifndef  FFTPServer_H_SEEN
#define  FFTPServer_H_SEEN

#include "fftservintf.h"

// implementation de FFTServerInterface en utilisant FFTPack 

namespace SOPHYA {

//! An FFT server based on fftpack.
class FFTPackServer : public FFTServerInterface {
 public:
  FFTPackServer(bool preserve_input=true);
  virtual ~FFTPackServer();

  // Implementation de l'interface FFTServerInterface

  virtual FFTServerInterface * Clone();

  // Transforme unidimensionnel sur des double
  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);

  // Transforme unidimensionnel sur des float
  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
  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); 
  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); 

  //  Methodes propres a cette classe
  virtual void fftf(int_4 l, float* inout);
  virtual void fftb(int_4 l, float* inout);
  virtual void fftf(int_4 l, double* inout);
  virtual void fftb(int_4 l, double* inout);
  virtual void fftf(int_4 l, complex<float>* inout);
  virtual void fftb(int_4 l, complex<float>* inout);
  virtual void fftf(int_4 l, complex<double>* inout);
  virtual void fftb(int_4 l, complex<double>* inout);

 protected:
  virtual void checkint_rfft(int_4 l);
  virtual void checkint_dfft(int_4 l);
  virtual void checkint_cfft(int_4 l);
  virtual void checkint_cdfft(int_4 l);

  int sz_rfft;
  r_4* ws_rfft;

  int sz_cfft;
  r_4* ws_cfft;

  int sz_dfft;
  r_8* ws_dfft;

  int sz_cdfft;
  r_8* ws_cdfft;

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

};

} // Fin du namespace


#endif
