!-------------------------------------- LICENCE BEGIN ------------------------------------
!Environment Canada - Atmospheric Science and Technology License/Disclaimer,
!                     version 3; Last Modified: May 7, 2008.
!This is free but copyrighted software; you can use/redistribute/modify it under the terms
!of the Environment Canada - Atmospheric Science and Technology License/Disclaimer
!version 3 or (at your option) any later version that should be found at:
!http://collaboration.cmc.ec.gc.ca/science/rpn.comm/license.html
!
!This software 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 above mentioned License/Disclaimer for more details.
!You should have received a copy of the License/Disclaimer along with this software;
!if not, you can write to: EC-RPN COMM Group, 2121 TransCanada, suite 500, Dorval (Quebec),
!CANADA, H9P 1J3; or send e-mail to service.rpn@ec.gc.ca
!-------------------------------------- LICENCE END --------------------------------------
!

      subroutine trans1d(ar,r1,r2,r3,maxsize,N,NLOT,ICAS,IAXE,IWAY) 2,24
!
! Author: Jean Cote -ARMN/EC - Date of creation unknown.
!
!  Revision 3.1  2003/10/24 21:05:48  dugas
!     Implementer du code compatible RS6000
!  Revision 3.0  2000/07/24 20:39:14  armnrbd
!  Revision  Luc Fillion -ARMA/EC - 17 Jun 2010 - Include author and revisions. Include taglam4d.cdk.

      IMPLICIT none
#include "taglam4d.cdk"

C     * THIS ROUTINE DOES THE SPECTRAL TRANSFORMS (FORWARD AND INVERSE)
C     * IT WORKS ON MULTIPLE ROW OR COLUMN AT A TIME.

C     * IT CAN DO FIVE KINDS OF TRANSFORM:

C                 1 => SIN ONLY.
C                 2 => COS ONLY.
C                 3 => SIN SHIFTED ONLY.
C                 4 => COS SHIFTED ONLY.
C                 5 => REGULAR SIN & COS.
C
      integer MAXSIZE,N,NLOT,ICAS,IAXE,IWAY
      real*8 ar(MAXSIZE), r1(MAXSIZE),r2(MAXSIZE),r3(MAXSIZE)

      integer NX,NY, nn, lot, nis, lots, nic, lotc

      real*8 cnorm, fac

C<<   JUST FOR DEBUGGING:
      real*8 scors2, scorc2, scors3, scorc3, scors4, scorc4
      real*8 scorqs2, scorqc2, scorqs3, scorqc3, scorqs4, scorqc4
      real*8 scorr2, scorr3, scorr4
C>>

      real*8 del, angle

      real*8 zero, half, one, two
      parameter( zero = 0.0 )
      parameter( half = 0.5 )
      parameter( one  = 1.0 )
      parameter( two  = 2.0 )

      LOGICAL FAST_FT
      logical lprint, lsin, lcos, lqsin, lqcos, lrft
      integer i, j, k, inc, jump, incs, jumps, incc, jumpc
      integer incr, jumpr, nfact, lotr
      integer ndx, nds, ndc, ndr

      ndx(i,j) =  1 + ( j - 1 ) * jump + i * inc
      ndr(i,j) =  1 + ( j - 1 ) * jumpr + i * incr
      nds(i,j) =  1 + ( j - 1 ) * jumps + ( i - 1 ) * incs
      ndc(i,j) =  1 + j * jumpc + i * incc

      lprint  = .false.

      lsin    = icas .eq. 1
      lcos    = icas .eq. 2
      lqsin   = icas .eq. 3
      lqcos   = icas .eq. 4
      lrft    = icas .eq. 5

      if (lprint) then 
      print *,'*********************'
      if ( lsin  ) print *,'*   sft8,  sfft8    *'
      if ( lcos  ) print *,'*   cft8,  cfft8    *'
      if ( lqsin ) print *,'*  qsft8, qsfft8    *'
      if ( lqcos ) print *,'*  qcft8, qcfft8    *'
      if ( lrft  ) print *,'*   rft8,  ffft8    *'
      print *,'*********************'
      endif

C<<   JUST FOR DEBUGGING:

      scors2  = zero
      scorc2  = zero
      scors3  = zero
      scorc3  = zero
      scors4  = zero
      scorc4  = zero
      scorqs2 = zero
      scorqc2 = zero
      scorqs3 = zero
      scorqc3 = zero
      scorqs4 = zero
      scorqc4 = zero
      scorr2  = zero
      scorr3  = zero
      scorr4  = zero
C>>

C     * SELECT THE FAST OR THE SLOW FOURIER TRANSFORM 
C     * BASED ON FACTORIZATION.
      
      NFACT=N
      CALL NGFFT( NFACT )

      If(NFACT.EQ.N) THEN 
         FAST_FT=.TRUE.

         if ( lsin  ) call setscqr( n-1, 'SIN'  )
         if ( lcos  ) call setscqr( n+1, 'COS'  )
         if ( lqsin ) call setscqr( n  , 'QSIN' )
         if ( lqcos ) call setscqr( n  , 'QCOS' )
         if ( lrft  ) call setscqr( n  , 'REAL' )

      ELSE
         FAST_FT=.FALSE.
      ENDIF


      cnorm = sqrt( two/n )
      del   = acos( - one )/n

      nis  = n - 1
      nic  = n + 1

         if     ( IAXE .eq. 0 ) then

C     * On veut par exemple:

C     appel de trans1d    liste d'arguments  appel pour
c     dans main           de trans1d         routine fft
C     =================   =================  ===========
C
C     NX=NID    -->        N      -->          n=jump=N=NID
C     NY=NJD    -->        NLOT   -->        lot=NLOT=NJD 
C                                            inc=1

C>>
            lot  = NLOT
            lots = lot   ! a verifier !!
            lotc = lot   ! a verifier !!
C>>
            inc   = 1
            jump  = n
            incr  = 1
            jumpr = n + 2
            incs  = 1
            jumps = n-1
            incc  = 1
            jumpc = n+1
         else

C     appel de trans1d    liste d'arguments  appel pour
c     dans main           de trans1d         routine fft
C     =================   =================  ===========
C
C     NX=NJD    -->        N      -->           n=NJD
C     NY=NID    -->        NLOT   -->         lot=inc=NLOT=NID 
C                                            jump=1
C>>
            lot  = NLOT
            lotr = NLOT + 2    
            lots = NLOT - 1    ! a verifier !!
            lotc = NLOT + 1 ! a verifier !!
C>>
            inc   = NLOT  ! il sont tous a verifer!!
            jump  = 1
            incr  = lotr 
            jumpr = 1
            incs  = lots
            jumps = 1
            incc  = lotc
            jumpc = 1
         endif
C------------------------------------------------------------------
C
C    case of sft8, sfft8
C
C------------------------------------------------------------------
         if ( lsin ) then

            do j=1,lots     ! a verifier
               do i=1,nis
C===          ar(nds(i,j)) = cnorm * sin( i * angle )
                  r3(nds(i,j)) = ar(nds(i,j))
               enddo 
            enddo            ! a verifier

         call sft8 ( r1, ar, incs, jumps, lots, n )
         call sfft8(     r3, incs, jumps, lots    )

         do j=1,lots
            do i=1,nis
               scors2 = max( scors2, abs(r1(nds(i,j))-r3(nds(i,j))) )
            enddo
         enddo
         print *,'scors2 = ',scors2

         if ( lprint ) then
            print *,'r1, r3'
            do j=1,lots
               print *,'j = ',j,(r1(nds(i,j)),i=1,nis)
               print *,'j = ',j,(r3(nds(i,j)),i=1,nis)
            enddo
         endif

         call sft8 ( r2, r1, incs, jumps, lots, n )
         call sfft8(     r3, incs, jumps, lots    )

         do j=1,lots
            do i=1,nis
               scors3 = max( scors3, abs(ar(nds(i,j))-r2(nds(i,j))) )
               scors4 = max( scors4, abs(ar(nds(i,j))-r3(nds(i,j))) )
            enddo
         enddo
         print *,'scors3, scors4 = ',scors3,scors4

         if ( lprint ) then
            print *,'r2, r3'
            do j=1,lots
               print *,'j = ',j,(r2(nds(i,j)),i=1,nis)
               print *,'j = ',j,(r3(nds(i,j)),i=1,nis)
            enddo
         endif

         endif
C------------------------------------------------------------------
C
C    case of cft8, cfft8
C
C------------------------------------------------------------------
         if ( lcos ) then

         do j=0,n
c==          angle = j * del
c==                                         fac = one
c==            if ( j .eq. 0 .or. j.eq. n ) fac = half

            do i=0,n
c==            ar(ndc(i,j)) = fac * cnorm * cos( i * angle )
               r3(ndc(i,j)) = ar(ndc(i,j))
            enddo
         enddo

         call cft8 ( r1, ar, incc, jumpc, lotc, n )
         call cfft8(     r3, incc, jumpc, lotc    )

         do j=0,n
            do i=0,n
               scorc2 = max( scorc2, abs(r1(ndc(i,j))-r3(ndc(i,j))) )
            enddo
         enddo
         print *,'scorc2 = ',scorc2

         if ( lprint ) then
            print *,'r1, r3'
            do j=0,n
               print *,'j = ',j,(r1(ndc(i,j)),i=0,n)
               print *,'j = ',j,(r3(ndc(i,j)),i=0,n)
            enddo
         endif

         call cft8 ( r2, r1, incc, jumpc, lotc, n )
         call cfft8(     r3, incc, jumpc, lotc    )

         do j=0,n
            do i=0,n
               scorc3 = max( scorc3, abs(ar(ndc(i,j))-r2(ndc(i,j))) )
               scorc4 = max( scorc4, abs(ar(ndc(i,j))-r3(ndc(i,j))) )
            enddo
         enddo
         print *,'scorc3, scorc4 = ',scorc3,scorc4

         if ( lprint ) then
            print *,'r2, r3'
            do j=0,n
               print *,'j = ',j,(r2(ndc(i,j)),i=0,n)
               print *,'j = ',j,(r3(ndc(i,j)),i=0,n)
            enddo
         endif

         endif
C------------------------------------------------------------------
C
C    case of qsft8, qsfft8
C
C------------------------------------------------------------------
         if ( lqsin ) then


           if (IWAY.eq.-1) then
               if (FAST_FT) then
                  call qsfft8(ar, inc,jump,lot,-1)
               else
                  call qsft8 (r1,ar,inc,jump,lot,-1,n )
                  do k=1,n*lot
                     ar(k)=r1(k)
                  enddo
               endif

            else                ! Fourier -> gridpoint

               if (FAST_FT) then
                  call qsfft8(ar, inc,jump,lot,+1)
               else
                  call qsft8 (r1,ar,inc,jump,lot,+1,n )
                  do k=1,n*lot
                     ar(k)=r1(k)
                  enddo
               endif
            endif

         endif
C------------------------------------------------------------------
C
C    case of qcft8, qcfft8
C
C------------------------------------------------------------------
         if ( lqcos ) then


           if (IWAY.eq.-1) then
               if (FAST_FT) then
                  call qcfft8(ar, inc,jump,lot,-1)
               else
                  call qcft8 (r1,ar,inc,jump,lot,-1,n )
                  do k=1,n*lot
                     ar(k)=r1(k)
                  enddo
               endif

            else                ! Fourier -> gridpoint

               if (FAST_FT) then
                  call qcfft8(ar, inc,jump,lot,+1)
               else
                  call qcft8 (r1,ar,inc,jump,lot,+1,n )
                  do k=1,n*lot
                     ar(k)=r1(k)
                  enddo
               endif
            endif

         endif
C------------------------------------------------------------------
C
C case of rft8, ffft8
C
C------------------------------------------------------------------
         if ( lrft ) then

C==            do j=1,lot
C==               do i=0,n-1
C==                  r3(ndr(i,j)) = ar(ndr(i,j))
C==               enddo
C==            enddo
            
            if ( lprint ) then
               print *,' On imprime ar avant transforme'
               do j=1,lot
                  print *,'j = ',j,(ar(ndr(i,j)),i=0,2*(n/2)+1)
               enddo
            endif
         
            if (IWAY.eq.-1) then
               if (FAST_FT) then
C==                  print *,'USING FFT'
                  call ffft8(ar, incr,jumpr,lot,-1) ! gridpoint -> Fourier
               else
                  call rft8 ( r1,ar,incr,jumpr,lot,-1,n)
                  do k=1,(n+2)*lot
                     ar(k)=r1(k)
                  enddo
               endif
               
            else                ! Fourier -> gridpoint
               if (FAST_FT) then
!                  print *,'USING FFT'
                  call ffft8(ar, incr,jumpr,lot,+1) 
               else
                  call rft8 (r1,ar,incr,jumpr,lot,+1,n)
                  do k=1,(n+2)*lot
                     ar(k)=r1(k)
                  enddo
               endif
            endif
            
            if ( lprint ) then
               print *,' On imprime ar apres transforme'
               do j=1,lot
                  print *,'j = ',j,(ar(ndr(i,j)),i=0,2*(n/2)+1)
               enddo
            endif

         endif
         

C==         print *,'------------------------------------------------------
C==     %-------------'



      return 
      end