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

#ifndef  FFTServerIntf_H_SEEN
#define  FFTServerIntf_H_SEEN

#include "machdefs.h"
#include "pexceptions.h"
#include <complex>
#include "tmatrix.h"
#include "tvector.h"

// Classe definissant l'interface pour les transformees de Fourier 
// L'implementation par defaut est vide et lance une exception 

namespace SOPHYA {

class FFTServerInterface {
 public:

// Methodes de la classe 
  FFTServerInterface(string info);
  virtual ~FFTServerInterface();

  
  virtual FFTServerInterface * Clone() = 0;

  //! Set/clear the flag for normalizing Fourier transforms.
  inline void setNormalize(bool fg=true) { _fgnorm = fg; }
  //! Returns the status of normalization flag for the server
  inline bool getNormalize() const { return(_fgnorm); } 
  //! Returns the information string associated with the server
  inline string getInfo() const { return _info; }

  //---------------------------------------------------
  // Transforme N-dim sur des doubles
  virtual void FFTForward(TArray<r_4> & in, TArray< complex<r_4> > & out);
  virtual void FFTForward(TArray<r_8> & in, TArray< complex<r_8> > & out); 
  virtual void FFTForward(TArray< complex<r_4> > & in, TArray< complex<r_4> > & out);
  virtual void FFTForward(TArray< complex<r_8> > & in, TArray< complex<r_8> > & out);

  virtual void FFTBackward(TArray< complex<r_4> > & in, TArray<r_4> & out,bool usoutsz=false);
  virtual void FFTBackward(TArray< complex<r_8> > & in, TArray<r_8> & out,bool usoutsz=false);
  virtual void FFTBackward(TArray< complex<r_4> > & in, TArray< complex<r_4> > & out);
  virtual void FFTBackward(TArray< complex<r_8> > & in, TArray< complex<r_8> > & out);

 protected:

  bool _fgnorm;
  string _info;
  
};


template <class T> 
class FFTArrayChecker {
public:
		FFTArrayChecker(string msg, bool checkpack=true, 
				bool onedonly=false);
  virtual	~FFTArrayChecker();
  static T	ZeroThreshold();
  
  inline void	SetMsg(string const & msg) { _msg = msg; }
  inline void	CheckPackedArray(bool ck=true) { _checkpack = ck; }
  inline void	Accept1DOnly(bool ac1d=false) { _onedonly = ac1d; }

  virtual int	CheckResize(TArray< complex<T> > const & in, TArray< complex<T> > & out);
  virtual int	CheckResize(TArray< T > const & in, TArray< complex<T> > & out);
  virtual int	CheckResize(TArray< complex<T> > const & in, TArray< T > & out, 
			    bool usoutsz=false);

protected:
  string _msg;
  bool _checkpack;
  bool _onedonly;

};

} // Fin du namespace

#endif
