#ifndef  FFTServ_H_SEEN
#define  FFTServ_H_SEEN

#include <complex>
#include "tvector.h"

class FFTServer{
 public:
  FFTServer();
  virtual ~FFTServer();
  virtual void fftf(int l, float* inout);
  virtual void fftb(int l, float* inout);
  virtual void fftf(int l, double* inout);
  virtual void fftb(int l, double* inout);
  virtual void fftf(int l, complex<float>* inout);
  virtual void fftb(int l, complex<float>* inout);
  virtual void fftf(int l, complex<double>* inout);
  virtual void fftb(int l, complex<double>* inout);
  virtual void fftf(Vector& in, Vector& out);
  virtual void fftb(Vector& in, Vector& out);

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

  int sz_rfft;
  float* ws_rfft;

  int sz_cfft;
  float* ws_cfft;

  int sz_dfft;
  double* ws_dfft;

  int sz_cdfft;
  double* ws_cdfft;
};
#endif

/*! \class FFTServer
 \brief An FFT server

A class that calculates Fourier transforms forwards and backwards.

The class calls the c library ``fftpack'', which is accessible and documented
at http://www.netlib.org/fftpack/.  However, the class functions do not
necessarily correspond with the equivalent fftpack function.  For example,
fftpack "forward" transformations are in fact inverse fourier transformations.
Otherwise, the output is in the fftpack format.

Complex input must be entered using the <complex> template.  Otherwise,
all input is assumed to be real.

Due to the way that fftpack manages
its work arrays, an object can run faster if the length of the input arrays
does not change.  For example, if you need to do a series of FFT's
of differing length, it may be more efficient to create an fftserver object
for each length.
*/

/*! \fn virtual void FFTServer::fftf(int l, float* inout)
  \param l length of array
  \param inout input array /output forward FFT (original array destroyed)
*/
/*! \fn virtual void FFTServer::fftb(int l, float* inout)
  \param l length of array
  \param inout input array /output backward FFT (original array destroyed)
*/
/*! \fn virtual void FFTServer::fftf(int l, double* inout)
  \param l length of array
  \param inout input array /output forward FFT (original array destroyed)
  \param inout input/output array (original array destroyed)
*/
/*! \fn virtual void FFTServer::fftb(int l, double* inout)
  \param l length of array
  \param inout input array /output backward FFT(original array destroyed)
*/
/*!\fn  virtual void FFTServer::fftf(int l, complex<float>* inout)
  \param l length of array
  \param inout input array /output forward FFT (original array destroyed)
*/
/*! \fn virtual void FFTServer::fftb(int l, complex<float>* inout)
  \param l length of array
  \param inout input array /output backward FFT (original array destroyed)
*/
/*! \fn virtual void FFTServer::fftf(int l, complex<double>* inout)
  \param l length of array
  \param inout input array /output forward FFT (original array destroyed)
*/
/*! \fn virtual void FFTServer::fftb(int l, complex<double>* inout)
  \param l length of array
  \param inout input array /output backward FFT(original array destroyed)
*/
/*!\fn  virtual void FFTServer::fftf(Vector& in, Vector& out)
  \param in input array
  \param out forward FFT
*/
/*! \fn virtual void FFTServer::fftb(Vector& in, Vector& out)
  \param in input array
  \param out backward FFT
*/
