!!----------------------------------------------------
!!.. Author: Yaxun Tang, tang@sep.stanford.edu
!!----------------------------------------------------
module base_struct_mod
  implicit none

  !!.. axis
  type axis
    integer :: n
    real    :: d
    real    :: o
  end type

  !!.. data grid
  !!.. IMPORTANT: 1. for conventional shot-profile migration, the input source function should
  !!..               be a single trace
  !!..            2. for composite source migration, the input source wavefield should be the 
  !!..               composite source wavefield corresponding to the current composite shot gather
  !!..            3. if it is composite source migration, the input source and receiver wavefields
  !!..               should share exactly the same grid 
  type dat_grid                                       
    type(axis)                           :: aw, at
    type(axis)                           :: asx, asy, asz                        !!.. entire source grid, used only when conventional shot-profile migration is used
    type(axis)                           :: agx, agy, agz                        !!.. the shot gather for current shot location
    type(axis)                           :: acs                                  !!.. composite sources
    integer                              :: ntrg                                 !!.. number of traces for one shot
    integer                              :: nshg                                 !!.. number of total shots
    integer                              :: ntrs                                 !!.. number of traces for a composite souce
    integer                              :: nshs                                 !!.. number of composite sources  
    real                                 :: sx, sy, sz                           !!.. source location for current shot
    real                                 :: gxmin_save, gymin_save
    real   , dimension(:,:), allocatable :: hsou
    logical                              :: hdrsou
    logical                              :: hdrrec
    logical                              :: radian
    logical                              :: offset
    logical                              :: comsou
  end type 

  !!.. propagation grid
  type pro_grid
    type(axis)                           :: ax, ay, az                           !!.. the propagation grid
    real                                 :: sx, sy, sz                           !!.. source location for one shot
    real                                 :: avx, avy, avz                        !!.. velocity model that are needed for wave propagation
    real                                 :: gxmin, gymin, gzmin
    real                                 :: gxmax, gymax, gzmax

    integer                              :: index_datpro_sx
    integer                              :: index_datpro_sy
    integer                              :: index_datpro_sz
    integer                              :: index_recpro_xmin, index_recpro_xmax !!.. indexes of receiver on the propagation grid
    integer                              :: index_recpro_ymin, index_recpro_ymax !!.. for mapping from receiver grid to propagation grid
    integer                              :: index_recpro_zmin, index_recpro_zmax

    integer                              :: nxpad_beg, nxpad_end
    integer                              :: nypad_beg, nypad_end
    integer                              :: nzpad_beg, nzpad_end

    integer                              :: nzstep                               !!.. total extrapolation depth step for one-way wave equation
    integer                              :: ntstep                               !!.. total extrapolation time step for two-way wave equation

    integer                              :: ntpx, ntpy
    integer                              :: nvrf
    integer                              :: pdip
    real                                 :: trick
    character(len=5)                     :: oper
  end type

  !!.. entire velocity grid
  type vel_grid
    type(axis) :: ax, ay, az

    integer    :: index_provel_xmin, index_provel_xmax !!.. indexes of propagation grid on the total velocity grid
    integer    :: index_provel_ymin, index_provel_ymax !!.. for reading velocity model for this shot
    integer    :: index_provel_zmin, index_provel_zmax
  end type

  !!.. entire image grid
  type img_grid
    type(axis) :: ax, ay, az
    type(axis) :: ahx, ahy, ahz, aht
    real       :: image_xmin, image_xmax, image_dx
    real       :: image_ymin, image_ymax, image_dy
    real       :: image_zmin, image_zmax, image_dz
    logical    :: wntimg
  end type

  !!.. output image grid for one shot
  type out_grid
    type(axis) :: ax, ay, az
    type(axis) :: ahx, ahy, ahz, aht

    integer    :: index_outimg_xmin, index_outimg_xmax
    integer    :: index_outimg_ymin, index_outimg_ymax
    integer    :: index_outimg_zmin, index_outimg_zmax

    integer    :: index_outpro_xmin, index_outpro_xmax
    integer    :: index_outpro_ymin, index_outpro_ymax
    integer    :: index_outpro_zmin, index_outpro_zmax
  
  end type

  !!.. Hessian
  type hes_grid
    type(axis) :: ax_modl, ay_modl, az_modl
    type(axis) :: ax_offd, ay_offd, az_offd
    type(axis) :: adip_agl, adip_azm
    type(axis) :: asca_agl, asca_azm
    integer    :: nx_offd_pad_beg, nx_offd_pad_end
    integer    :: ny_offd_pad_beg, ny_offd_pad_end
    integer    :: nz_offd_pad_beg, nz_offd_pad_end
    integer    :: hestyp
    logical    :: wnthes
  end type

  !!.. Green's function
  type gre_grid
    type(axis) :: ax_modl, ay_modl, az_modl
    type(axis) :: ax_surf, ay_surf, aw
    real       :: surf_xmin, surf_xmax            ! xmin for the surface location
    real       :: surf_ymin, surf_ymax            ! ymin for the surface location
    real       :: modl_xmin, modl_xmax
    real       :: modl_ymin, modl_ymax
    real       :: modl_zmin, modl_zmax
    integer    :: index_surpro_xmin, index_surpro_xmax  ! first x index of the surface grid on the propagation grid
    integer    :: index_surpro_ymin, index_surpro_ymax
    integer    :: index_surpro_sx, index_surpro_sy, index_surpro_sz   
    integer    :: index_modpro_mx, index_modpro_my, index_modpro_mz 
    integer    :: index_modpro_xmin, index_modpro_xmax
    integer    :: index_modpro_ymin, index_modpro_ymax
    integer    :: index_modpro_zmin, index_modpro_zmax
    logical    :: radian
    logical    :: spikes 
  end type

  !!.. blocks
  type block
    integer                            :: ns
    integer                            :: nb
    integer                            :: nb_res
    real                               :: ds
    real   , allocatable, dimension(:) :: os
    integer, allocatable, dimension(:) :: blen
    integer, allocatable, dimension(:) :: indx
    logical                            :: bres
  end type

end module
