# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "<stdin>"
module OW_encoding

use sep
use OW_type
use OW_parms_areal
use OW_fftw_areal
use OW_rndseed1
use OW_mseq
use OW_gcd
use OW_exec_time

implicit none

real,private :: start,finish
integer,private :: i,ixs,iw,iz,iq,nq
integer,private :: igap,jgap,indq(1),ihorz,gap,irand
integer,allocatable,private :: q(:),prefer(:,:,:)
real,allocatable,private :: rand1(:),hold(:,:),gol(:,:,:,:),correl(:,:)
complex,allocatable,private :: tfld(:),fun1(:)

contains

!==================================================
subroutine owgoldpw (randz,nhorz)
real :: randz(:,:,:,:)
integer :: nhorz,nodes
integer, external :: omp_get_thread_num,omp_get_num_threads

if (node.eq.9999) then
  !$OMP PARALLEL
  nodes = omp_get_num_threads()
  !$OMP END PARALLEL
else
  nodes=node
end if
write(0,*) "****************"
write(0,*) "* NUM.THREADS = ",nodes
write(0,*) "****************"

   allocate(hold(48,2*sou%w%n-subf))
   allocate(rand1(2*sou%w%n-subf))
   allocate(q(2*sou%w%n-subf));q=0
   call owexec_time(start)
   call owgcd(9,nq,q,indq)
   call owexec_time(finish)

   write(0,*) "gcd ",(finish-start)/60,"(min)"

   call owexec_time(start)
   do i=1,48
      rand1=0
      call owmseq(2,9,rand1,2*sou%w%n,i-int((i-1)/48)*48)
      hold(i,:)=rand1
   end do
   rand1=0
   hold=hold*2-1
   call owexec_time(finish)

   write(0,*) "mseq ",(finish-start)/60,"(min)"

   allocate(prefer(48,indq(1),2*sou%w%n-subf))

   call owexec_time(start)
   do iq=1,indq(1)
      do i=1,48
         prefer(i,iq,1)=hold(i,1)
         rand1=hold(i,:)
         do iz=2,2*sou%w%n-subf
            rand1=cshift(rand1,q(iq))
            prefer(i,iq,iz)=rand1(1)
         end do
      end do
   end do
   call owexec_time(finish)

   write(0,*) "prefer ",(finish-start)/60,"(min)"

   if (exist_file("prefpair")) then
      write(0,*) "COMPUTING THE CROSSCORRELATIONS OF THE PREFERRED PAIRS"
      if (allocated(tfld)) deallocate(tfld);allocate(tfld(2*sou%w%n-subf))
      call owfftw(tfld)
      allocate(fun1(2*sou%w%n-subf))
      allocate(correl(2*sou%w%n-subf,2*sou%w%n-subf))
      tfld=cmplx(hold(1,:),0.)
      call sfftw_execute(planF)
      fun1=conjg(tfld/sqrt(1.*(2*sou%w%n-subf)))
      do ixs=1,indq(1)
         tfld=cmplx(prefer(1,ixs,:),0.)
         call sfftw_execute(planF)
         tfld=tfld/sqrt(1.*(2*sou%w%n-subf))*fun1
         call sfftw_execute(planI)
         correl(ixs,:)=tfld
         correl(ixs,:)=cshift(correl(ixs,:),int((2*sou%w%n-subf)/2))
      end do
      call to_history("n1",20,"prefpair"); call to_history("d1",1.,"prefpair");
      call to_history("o1",1.,"prefpair")
      call to_history("n2",2*sou%w%n-subf,"prefpair") ; call to_history("d2",1.,"prefpair") ;
      call to_history("o2",-float(sou%w%n),"prefpair")
      call to_history("n3",1,"prefpair"); call to_history("d3",1.,"prefpair");
      call to_history("o3",1.,"prefpair")
      call to_history("n4",1,"prefpair"); call to_history("d4",1.,"prefpair");
      call to_history("o4",0.,"prefpair")
      call to_history("n5",1,"prefpair"); call to_history("d5",1.,"prefpair");
      call to_history("o5",0.,"prefpair")
      call to_history("esize",4,"prefpair")
      call srite("prefpair",correl,4*(2*sou%w%n-subf)*20)
      call owfftwdestroy()
      deallocate(tfld,fun1,correl)
   end if

   deallocate(rand1)
   allocate(gol(48,indq(1),2*sou%w%n-subf,2*sou%w%n-subf));gol=0;

!
! ii can not be greater than 48
!
   call owexec_time(start)
!$OMP parallel do private (ixs,&
                         ihorz,&
                             i) schedule(dynamic,1) num_threads(nodes)
   do ixs=1,2*sou%w%n-subf
      do ihorz=1,indq(1)
         do i=1,48
            gol(i,ihorz,:,ixs)=hold(i,:)*cshift(prefer(i,ihorz,:),ixs)
         end do
      end do
   end do
!$OMP END PARALLEL DO

   call owexec_time(finish)
   write(0,*) "gold ",(finish-start)/60,"(min)"

   if (exist_file("correlations")) then
      write(0,*) "COMPUTING THE CROSSCORRELATIONS OF GOLD CODES"
      if (allocated(tfld)) deallocate(tfld);allocate(tfld(2*sou%w%n-subf))
      call owfftw(tfld)
      allocate(fun1(2*sou%w%n-subf))
      allocate(correl(2*sou%w%n-subf,2*sou%w%n-subf))
      tfld=cmplx(gol(1,1,1,:),0.)
      call sfftw_execute(planF)
      fun1=conjg(tfld/sqrt(1.*(2*sou%w%n-subf)))
      do ixs=1,(2*sou%w%n-subf)
         tfld=cmplx(gol(1,1,ixs,:),0.)
         call sfftw_execute(planF)
         tfld=tfld/sqrt(1.*(2*sou%w%n-subf))*fun1
         call sfftw_execute(planI)
         correl(ixs,:)=tfld
         correl(ixs,:)=cshift(correl(ixs,:),int((2*sou%w%n-subf)/2))
      end do
      call to_history("n1",(2*sou%w%n-subf),"correlations"); call to_history("d1",1.,"correlations");
      call to_history("o1",1.,"correlations")
      call to_history("n2",2*sou%w%n-subf,"correlations") ; call to_history("d2",1.,"correlations") ;
      call to_history("o2",-float(sou%w%n),"correlations")
      call to_history("n3",1,"correlations"); call to_history("d3",1.,"correlations");
      call to_history("o3",1.,"correlations")
      call to_history("n4",1,"correlations"); call to_history("d4",1.,"correlations");
      call to_history("o4",0.,"correlations")
      call to_history("n5",1,"correlations"); call to_history("d5",1.,"correlations");
      call to_history("o5",0.,"correlations")
      call to_history("esize",4,"correlations")
      call srite("correlations",correl,4*(2*sou%w%n-subf)*(2*sou%w%n-subf))
      call owfftwdestroy()
      deallocate(tfld,fun1,correl)
   end if

   deallocate(hold)

   if (allocated(tfld)) deallocate(tfld);allocate(tfld(2*sou%w%n-subf))

   call owfftw(tfld)

   call owexec_time(start)
! if (encz) then
! gap=int((2*sou%w%n-subf)/(nhorz-1))
! else
      gap=int((2*sou%w%n-subf)/(sog%xm%n/ngap))
! end if

   if (encz) then
      do ihorz=1,nhorz
         do ixs=1,sog%xm%n
            jgap=int((ixs-1)/(ngap)+1)*gap
            if (jgap > 2*sou%w%n-subf) jgap=jgap/2
! jgap=int((ihorz-1)/(nhorz))*gap+1
            tfld=0
            tfld=cmplx(gol(1,ihorz,jgap,:),0)
            call sfftw_execute(planF)
            randz(:,ixs,ihorz,1)=atan(imag(tfld(1:sou%w%n))*real(tfld(1:sou%w%n))/ &
                      (real(tfld(1:sou%w%n))*real(tfld(1:sou%w%n))+tiny(1.)))
         end do
      end do
   else
       do ihorz=1,nhorz
         do ixs=1,sog%xm%n
            jgap=int((ixs-1)/(ngap)+1)*gap
            if (jgap > 2*sou%w%n-subf) jgap=jgap/2
            tfld=0
            tfld=cmplx(gol(1,ihorz,jgap,:),0)
            call sfftw_execute(planF)
            randz(:,ixs,ihorz,1)=atan(imag(tfld(1:sou%w%n))*real(tfld(1:sou%w%n))/ &
                      (real(tfld(1:sou%w%n))*real(tfld(1:sou%w%n))+tiny(1.)))
         end do
      end do
   end if
   randz=randz*2
   call owexec_time(finish)
   write(0,*) "encode ",(finish-start)/60,"(min)"

   call owfftwdestroy()

   deallocate(tfld,gol)

end subroutine
!========================================================

end module
