# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "<stdin>"
!HANDLE FFTS
module fft_mod
  use flags_mod
  use S_mod
  implicit none
  integer*8,pointer,private,save :: splanF(:,:),splanI(:,:)
  integer*8,pointer,private,save :: rplanF(:,:),rplanI(:,:)
  complex,allocatable,private::tmpr(:,:,:),tmps(:,:,:)
  real, private,save :: in12
  integer,private,save::dims(2)
contains

!----------------------------------------------------------------
  subroutine fft_init_r(wfld)
    complex,allocatable :: wfld(:,:,:)
    integer :: i,ith
    real :: a




    dims=(/down%amx%n,down%amy%n/)
    in12=sqrt(1./real(product(dims)))
    allocate(rplanF(size(wfld,3),run%o_nth))
    allocate(rplanI(size(wfld,3),run%o_nth))
    allocate(tmpr(dims(1),dims(2),run%o_nth))

    do ith=1,run%o_nth
       do i=1,size(wfld,3)!!output writes over input
          call sfftw_plan_dft_2d(rplanF(i,ith),dims(1),dims(2),&
          wfld(1,1,i),tmpr(1,1,ith),FFTW_FORWARD,FFTW_PATIENT)
! wfld(1,1,i),wfld(1,1,i),FFTW_FORWARD,FFTW_PATIENT)
          call sfftw_plan_dft_2d(rplanI(i,ith),dims(1),dims(2),&
          wfld(1,1,i),tmpr(1,1,ith),FFTW_BACKWARD,FFTW_PATIENT)
! wfld(1,1,i),wfld(1,1,i),FFTW_BACKWARD,FFTW_PATIENT)
       end do
    end do

    call sfftw_cleanup()
    a=8*(size(tmpr)+2*size(rplanF))
    down%mem=down%mem+a






  end subroutine fft_init_r
!----------------------------------------------------------------
  subroutine fft_init_s(wfld)
    complex,allocatable :: wfld(:,:,:)
    integer :: i,ith
    real :: a




    dims=(/down%amx%n,down%amy%n/)
    in12=sqrt(1./real(product(dims)))
    allocate(splanF(size(wfld,3),run%o_nth))
    allocate(splanI(size(wfld,3),run%o_nth))
    allocate(tmps(dims(1),dims(2),run%o_nth))
    do ith=1,run%o_nth
       do i=1,size(wfld,3)!!output writes over input
          call sfftw_plan_dft_2d(splanF(i,ith),dims(1),dims(2),&
          wfld(1,1,i),tmps(1,1,ith),FFTW_FORWARD,FFTW_PATIENT)
! wfld(1,1,i),wfld(1,1,i),ffTW_FORWARD,fftW_PATIENT)
          call sfftw_plan_dft_2d(splanI(i,ith),dims(1),dims(2),&
          wfld(1,1,i),tmps(1,1,ith),FFTW_BACKWARD,FFTW_PATIENT)
! wfld(1,1,i),wfld(1,1,i),ffTW_BACKWARD,fftW_PATIENT)
       end do
    end do

    call sfftw_cleanup()
    a=8*(size(tmps)+2*size(splanF))
    down%mem=down%mem+a






  end subroutine fft_init_s
  !----------------------------------------------------------------
  !! forward FFT
  subroutine fft(iws,ith,data)
    integer, intent(in) :: iws,ith
    integer :: i,j
    complex, dimension(:,:,:) ,allocatable:: data





    if(slo%source) then
       call sfftw_execute(splanF(iws,ith))
       do i=1,down%amy%n
          do j=1,down%amx%n
             data(j,i,iws)=tmps(j,i,ith)*in12
          end do
       end do
    else
       call sfftw_execute(rplanF(iws,ith))
       do i=1,down%amy%n
          do j=1,down%amx%n
             data(j,i,iws)=tmpr(j,i,ith)*in12
          end do
       end do
    end if




  end subroutine fft
!----------------------------------------------------------------
  !! inverse FFT
  subroutine ift(iws,ith,data)
    integer, intent(in) :: iws,ith
    integer :: i,j
    complex, dimension(:,:,:),allocatable :: data




    if(slo%source) then
       call sfftw_execute(splanI(iws,ith))
       do i=1,down%amy%n
          do j=1,down%amx%n
             data(j,i,iws)=tmps(j,i,ith)*in12
          end do
       end do
    else
       call sfftw_execute(rplanI(iws,ith))
       do i=1,down%amy%n
          do j=1,down%amx%n
             data(j,i,iws)=tmpr(j,i,ith)*in12
          end do
       end do
    end if



  end subroutine ift
!----------------------------------------------------------------
end module fft_mod
