#ifndef GSL_FFT_COMPLEX
#define GSL_FFT_COMPLEX

#include "gsl/gsl_vector_complex.h"
#include "gsl/gsl_fft_complex.h"
#include "gsl/gsl_fft_halfcomplex.h"

#include "Header.hh"

#include "AdvVectorComplexTool.hh"

/** warpper for Fast Fourier Transform in GNU Scientific Library.
 *  evaluates the forward, inverse and backward transform
 *
 *  @author  TANIMORI Souichirou, AdvanceSoft Corp.
 *  @version 0.0
 *  @since   0.0
 */
class AdvGslFFTComplex {
    private:
        static const string className;

    protected:
        UInt4 dataLength;
        gsl_fft_complex_wavetable *waveTable;
        gsl_fft_complex_workspace *workSpace;

    protected:
        Bool isRadix2(UInt4 i) const {  return (i & (i-1)) == 0; };
        //Bool isRadix2(Int4  i) const {  return (i & (i-1)) == 0; };

    protected:
        void allocateWorkSpace(UInt4 i);
        void freeWorkSpace();

    public:
        /** constructor */
        //AdvGslFFTComplex();
        /** constructor
         *  @papram[in] n the length of data to be transformed
         */
        AdvGslFFTComplex(UInt4 n);

        /** destructor */
        ~AdvGslFFTComplex();

        void setDataLength(UInt4 n);

        UInt4 getDataLength() { return this->dataLength; };

        /** forward DFT.
         *  @param[inout] v  values to be transformed
         *                   v is overwritten by results.
         */
        Int4 forward(gsl_vector_complex* v);

        /** backward DFT.
         *  @param[inout] v  values to be transformed
         *                   v is overwritten by results.
         */
        Int4 backward(gsl_vector_complex* v);

        /** inverse DFT.
         *  @param[inout] v  values to be transformed
         *                   v is overwritten by results.
         */
        Int4 inverse(gsl_vector_complex* v);

        /** DFT.
         *  @param[inout] v  values to be transformed
         *                   v is overwritten by results.
         *  @param[in]    sign  gsl_fft_forward (-1) or gsl_fft_backward (+1)
         */
        Int4 transform(gsl_vector_complex* v, gsl_fft_direction sign);

};

#endif // GSL_FFT_COMPLEX
