program main
  use wei_global_defi_mod
  use wei_global_calc_mod
  use wei_io_mod
  use wei_vel_mod
  use wei_ssf_mod
  use wei_int_mod
  use wei_cig_mod
  use wei_type_mod
  use wei_report_mod
  implicit none

  integer    :: ish, iwb, izb, iws, izs, stat
  integer    :: nws_bak, nzs_bak, percent
  integer    :: indx_dept
  real       :: ws
  type(axis) :: aws
  type(axis) :: azs
  complex, dimension(:,:)    , pointer :: wfld_slice_d
  complex, dimension(:,:)    , pointer :: wfld_slice_u
  real   , dimension(:,:,:,:), pointer :: modl_slice
  real   , dimension(:,:)    , pointer :: vmod_slice
  real   , dimension(:)      , pointer :: vref_slice

  complex, dimension(:,:,:)  , pointer :: wfld_tmp

  !!.. input history

  call wei_param_init()
  call wei_data_history(adj)
  call wei_imag_history(adj)
  call wei_io_file_init(adj)

  call wei_radians_calc()
  !call wei_block_calc()

  if (dgrid%hdr_rec) call wei_io_head_init("hrec")
  if (dgrid%hdr_sou) call wei_io_head_init("hsou")


  !!.. shot-profile migration
  if (adj) then
     do ish=1, dgrid%nsh
        if (dgrid%hdr_rec) call wei_io_head_oper("hrec")
        if (dgrid%hdr_sou) call wei_io_head_oper("hsou")
        call wei_counter_init()
        call wei_global_calc(ish)
        call wei_grids_report(ish, dgrid%nsh)
        if(igrid%ax%n>1.and.ogrid%ax%n == 0) cycle
        if(igrid%ay%n>1.and.ogrid%ay%n == 0) cycle 
        call wei_wfld_alloc(1)
        call wei_modl_alloc(1)
        call wei_memory_report()
        stat = wei_vel_init(lloyd, nref)
        stat = wei_ssf_init(kx2, ky2, igrid%az%d, maxang)
        stat = wei_cig_init(decon, eps, ogrid, pgrid)
        do iws=1, dgrid%aw%n
           ws = dgrid%aw%o + (iws-1)*dgrid%aw%d
           call wei_io_crec("reed", iws, 1, ish)
           call wei_io_csou(iws, 1)
           call wei_wfld_d_init(1)
           call wei_wfld_u_init(adj, .false., 1)
           wfld_slice_d => wfld_d(:,:,1)
           wfld_slice_u => wfld_u(:,:,1)
           do izs=1, igrid%az%n
              call wei_io_velo(izs, 1)
              call wei_io_imag("reed", izs, 1)
              modl_slice => model(:,:,:,:,1)
              vmod_slice => vmod(:,:,1)
              vref_slice => vref(:,1)
              stat = wei_vel_oper(vmod_slice, vref_slice)
              stat = wei_ssf_oper(.true., +1, ws, vref_slice(1), vmod_slice, wfld_slice_d)
              stat = wei_ssf_oper(.true., -1, ws, vref_slice(1), vmod_slice, wfld_slice_u)
              stat = wei_cig_oper(adj, .true., wfld_slice_d, wfld_slice_u, modl_slice)
              call wei_io_imag("rite", izs, 1)
           end do
           if(mod(iws, dgrid%aw%n/5) == 0) then
              write(0,*)"Finished:", int(real(iws)/real(dgrid%aw%n)*100), "%"
           end if 
        end do
        stat = wei_vel_clos()
        stat = wei_ssf_clos()
        stat = wei_cig_clos()
        call wei_modl_dealloc()
        call wei_wfld_dealloc()
     end do

  !!.. shot-profile demigration
  else
     do ish=1, dgrid%nsh
        call wei_global_calc(ish)
        call wei_grids_report(ish, dgrid%nsh)
        call wei_wfsd_history()
        call wei_wfld_alloc(1)
        call wei_modl_alloc(1)
  
        stat = wei_vel_init(lloyd, nref)
        stat = wei_ssf_init(kx2, ky2, igrid%az%d, maxang)
        stat = wei_cig_init(decon, eps, ogrid, pgrid)

        wfld_slice_u => wfld_u(:,:,1)
        do iws=1, dgrid%aw%n
           ws = dgrid%aw%o + (iws-1)*dgrid%aw%d
           call wei_io_csou(iws,1)
           call wei_wfld_d_init(1)
           wfld_slice_d => wfld_d(:,:,1)
           wfld_slice_u = 0.
           !crec         = 0.
           do izs=1, igrid%az%n
              call wei_io_velo(izs, 1)
              vmod_slice => vmod(:,:,1)
              vref_slice => vref(:,1)
              stat = wei_vel_oper(vmod_slice, vref_slice)
              stat = wei_ssf_oper(adj, +1, ws, vref_slice(1), vmod_slice, wfld_slice_d)
              call wei_io_wfsd("rite", wfld_slice_d, izs)
           end do

           do izs=igrid%az%n, 1, -1
              call wei_io_velo(izs, 1)
              call wei_io_imag("reed", izs, 1)
              call wei_io_wfsd("reed", wfld_slice_d, izs)
              vmod_slice => vmod(:,:,1)
              vref_slice => vref(:,1)
              modl_slice => model(:,:,:,:,1)
              stat = wei_cig_oper(adj, .true., wfld_slice_d, wfld_slice_u, modl_slice)
              stat = wei_vel_oper(vmod_slice, vref_slice)
              stat = wei_ssf_oper(adj, +1, ws, vref_slice(1), vmod_slice, wfld_slice_u)
           end do

           !call wei_io_crec("reed", iws, 1, ish)
           call wei_wfld_u_init(adj, .true., 1)
           call wei_io_crec("rite", iws, 1, ish)
           if(mod(iws, dgrid%aw%n/5) == 0) then
              write(0,*)"Finished:", int(real(iws)/real(dgrid%aw%n)*100), "%"
           end if
        end do
        !call wei_wfld_u_init(adj, .true., dgrid%aw%n)
        !call wei_io_crec("rite", 1, dgrid%aw%n, ish) 
        stat = wei_vel_clos()
        stat = wei_ssf_clos()
        stat = wei_cig_clos()
        call wei_modl_dealloc()
        call wei_wfld_dealloc()
     end do
  end if

end program
