!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!   Copyright (C) 2008-2019 by Simon Prunet, Christophe Pichon et al     !
!   prunet iap.fr                                                        !
!   Copyright (C) 2020 Boud Roukema -  fix single vs double precision    !
!                                                                        !
!   This program is free software; you can redistribute it and/or modify !
!   it under the terms of the GNU General Public License as published by !
!   the Free Software Foundation; either version 2 of the License, or    !
!   (at your option) any later version.                                  !
!                                                                        !
!   This program is distributed in the hope that it will be useful,      !
!   but WITHOUT ANY WARRANTY; without even the implied warranty of       !
!   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        !
!   GNU General Public License for more details.                         !
!                                                                        !
!   You should have received a copy of the GNU General Public License    !
!   along with this program; if not, write to the                        !
!   Free Software Foundation, Inc.,                                      !
!     59 Temple Place - Suite 330, Boston, MA  02111-1307, USA           !
!   or see https://www.gnu.org/licenses/licenses.html#GPL .              !
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

module transform

  use grafic_types
  IMPLICIT NONE
#ifdef ADD1US
#define  rfftw3d_f77_create_plan  rfftw3d_f77_create_plan_
#define  rfftwnd_f77_destroy_plan rfftwnd_f77_destroy_plan_
#define  rfftwnd_f77_one_real_to_complex rfftwnd_f77_one_real_to_complex_
#define  rfftw3d_f77_mpi_create_plan  rfftw3d_f77_mpi_create_plan_
#define  rfftwnd_f77_mpi_destroy_plan rfftwnd_f77_mpi_destroy_plan_
#define  rfftwnd_f77_mpi rfftwnd_f77_mpi_
#define  rfftwnd_f77_mpi_local_sizes rfftwnd_f77_mpi_local_sizes_
#endif

  interface fft_mpi
     module procedure fft_mpi_double
  end interface

contains

  subroutine fft_forward(l,m,n,input,output)

    integer :: l,m,n
    real*8, dimension(l,m,n), intent(in) :: input
    complex*16, dimension(l/2+1,m,n), intent(out) :: output
    integer*8 :: plan

    call rfftw3d_f77_create_plan(plan,l,m,n,FFTW_REAL_TO_COMPLEX, &
         & FFTW_ESTIMATE)
    call rfftwnd_f77_one_real_to_complex(plan,input,output)
    call rfftwnd_f77_destroy_plan(plan)

  end subroutine fft_forward

  ! This covers both forward and backward ffts,
  ! depending on plan

  subroutine fft_mpi_double(plan,input,total_local_size)

    use iso_C_binding

    ! Arguments
    type(c_ptr) :: plan
    integer :: total_local_size
    real(dp), dimension(total_local_size) :: input

    ! Local variables
    !integer :: ierr,myid,status
    !real*4 :: tstart, tstop
    real*8, allocatable, dimension(:) :: work

    !allocate(work(total_local_size),stat=status)
    !if (status /= 0) then
    !   print*,'Could not allocate work for proc #',myid
    !   stop
    !endif
    allocate(work(1))
!!$    call rfftwnd_f77_mpi(plan,1,input,work, &
!!$         & 0,FFTW_TRANSPOSED_ORDER)
    call rfftwnd_f77_mpi(plan,1,input,work, &
         & 0,FFTW_NORMAL_ORDER) !0 to ignore work, 1 to use it
    deallocate(work)

  end subroutine fft_mpi_double

end module transform
