module orbrzv

  use iso_c_binding, only: c_double_complex
  use ezspline_obj
  use rfxqlo_types

  implicit none
  save
  !! already moved to nbspec.dat
  !!integer :: orbrzv_option    = 0
  !!integer :: orbrzv_nr = 160, orbrzv_nz = 160
  !!real(fp) :: orbrzv_zzerr_con = 1.0e-4_fp
  !!real(fp) :: orbrzv_toric_frnm = 4.0_fp

  !! potential candidates to be moved to nbspec.dat
  !!integer :: orbrzv_rf_option = 0
  !!real(fp), allocatable, dimension(:) :: orbrzv_prftot
  !!real(fp), allocatable, dimension(:,:) :: orbrzv_prf
  !!real(fp), allocatable, dimension(:) :: orbrzv_toric_prftot
  !!real(fp), allocatable, dimension(:,:) :: orbrzv_toric_prf

  ! global option : later moved to nbspec.dat

  ! rz-domain information
  real(fp) :: orbrzv_rmin, orbrzv_rmax, orbrzv_dr
  real(fp) :: orbrzv_zmin, orbrzv_zmax, orbrzv_dz

  ! rectangle bounding plasma boundary
  real(fp) :: orbrzv_prmin, orbrzv_prmax, orbrzv_pzmin, orbrzv_pzmax

  ! spline object for psi, g, phi interpolation 
  type(ezspline2) :: orbrzv_psi_spo, orbrzv_g_spo, orbrzv_phi_spo

  ! some global equilibrium information
  real(fp) :: orbrzv_psix, orbrzv_rc, orbrzv_zc, orbrzv_bc

  ! bphi sign
  real(fp) :: orbrzv_bpsign

!mg 11/16 cleanup  ! rhot(rhop) interpolation
!mg 11/16 cleanup  type(ezspline1) :: orbrzv_rhot_spo

  ! interpolated psi's, g's, phi's at current guiding center position
  real(fp) :: orbrzv_psiv(1:6), orbrzv_gv(1:3), orbrzv_phiv(1:3), &
            & orbrzv_b, orbrzv_dbdr
  ! position & derivatives  
  !mg orbrzv_zz(1) = r, orbrzv_zz(2) = z, orbrzv_zz(3) = bivpar, orbrzv_zz(4) = bimu
  real(fp) :: orbrzv_zz(1:4), orbrzv_dzzdt(1:3), &
            & orbrzv_rho, orbrzv_th, orbrzv_ms, orbrzv_qs
  integer :: orbrzv_pflag ! 0, 1, -1 : in, out, lost

  ! store the above values at the start of step
  real(fp) :: orbrzv_psiv0(1:6), orbrzv_gv0(1:3), orbrzv_phiv0(1:3), &
            & orbrzv_b0, orbrzv_zz0(1:4), orbrzv_dzzdt0(1:3) 

  ! scaling factor minimum
  real(fp) :: orbrzv_zzscal_min(1:3) = (/ 1.0e-1_fp, 1.0e-1_fp, 1.0e4_fp /)

  ! error control factor & estimated error
  integer :: orbrzv_iter_max = 200
  real(fp) :: orbrzv_zzerr(0:5)

  ! particle energy & toroidal canonical angular momentum
  real(fp) :: orbrzv_teng, orbrzv_tcmt, orbrzv_teng0, orbrzv_tcmt0

  ! time step and related parameters
  real(fp) :: orbrzv_dt_min = 1.0e-10_fp, orbrzv_dt_max = 1.0e-5_fp, &
            & orbrzv_dt, orbrzv_tdt, orbrzv_time0, &
            & orbrzv_dbg_dt = 5.0e-8_fp

  ! file unit for debugging purpose
  integer :: orbrzv_out, orbrzv_out1, orbrzv_nloop

  !---------------------------------------------------------------------
!mg 11/16 cleanup  ! bounce time
!mg 11/16 cleanup  real(fp) :: orbrzv_tb_r1, orbrzv_tb_r2, orbrzv_tb_dr, &
!mg 11/16 cleanup            & orbrzv_tb_lnv1, orbrzv_tb_lnv2, orbrzv_tb_dlnv, &
!mg 11/16 cleanup            & orbrzv_tb_xi1, orbrzv_tb_xi2, orbrzv_tb_dxi
!mg 11/16 cleanup  integer :: orbrzv_tb_nr, orbrzv_tb_nlnv, orbrzv_tb_nxi
!mg 11/16 cleanup  real(fp), allocatable, dimension(:,:,:) :: orbrzv_tb
!mg 11/16 cleanup  type(ezspline2), allocatable, dimension(:) :: orbrzv_tb_spo

  !---------------------------------------------------------------------
  ! rf part
  ! maximum harmonic number ever considered...
  integer :: orbrzv_llmax
  logical :: il_rz_updated !this flag will be set true in orbit.for if r,z changed

  type mcrf_wavefield_type

    ! =========================================================
    ! data members for wave field discription
    real(fp) :: freq, power ! frequency and power
    real(fp) :: nphi, kl    ! nphi and its conversion to r8
    integer :: ksym         ! nphi symmety factor
    ! spline object holding wavefield information
    type(ezspline2) :: kp_spo, ep_spo, rp_spo, ip_spo
    ! profiles
    type(rfxqlo_outpro) :: pro

    ! =========================================================
    ! data members to hold particle info for rf-resonance
    ! all with dimension (1:max-harmonics, 1:ksym)
    ! resonance condition
!mg    real(fp), dimension(orbrzv_llmax,2) :: lam0, lam
    real(fp), dimension(:,:),allocatable :: lam0, lam
    ! resonance direction
!mg    integer, dimension(orbrzv_llmax,2) :: dsgn
    integer, dimension(:,:),allocatable :: dsgn
    ! last time of crossing this resonance and elasped time
!mg    real(fp), dimension(orbrzv_llmax,2) :: time, dt, nstep, time0, dt0
    real(fp), dimension(:,:),allocatable :: time, dt, nstep, time0, dt0
    ! time adjusting factor for close location of resonance
!mg    real(fp), dimension(orbrzv_llmax,2) :: ztf
    real(fp), dimension(:,:),allocatable :: ztf

    ! =========================================================
    ! interpolated kp2, ep, cpol, zzm
!mg    real(fp), dimension(orbrzv_llmax,2,1:4) :: zzm
    real(fp), dimension(:,:,:),allocatable :: zzm
!mg    real(fp), dimension(orbrzv_llmax,2) :: kp2, ep
    real(fp), dimension(:,:),allocatable :: kp2, ep
!mg    complex*16, dimension(orbrzv_llmax,2) :: cpol
    complex(c_double_complex), dimension(:,:),allocatable :: cpol

  end type mcrf_wavefield_type

  ! geometric information for resonance time evaluation
  type(ezspline2) :: orbrzv_bdb_spo, orbrzv_b_spo, orbrzv_lrfi_spo
  real(fp) :: orbrzv_bdb_min

  ! bessel function table
  ! maximum kp2
  real(fp) :: orbrzv_kp2_max, orbrzv_bb_max
  type(ezspline1), allocatable, dimension(:) :: orbrzv_jtb_spo

  ! number of antenna and maximum nphi value over all antenna
  integer :: orbrzv_rf_nant, orbrzv_rf_max_nphi
  ! arrary of the number of nphi for each antenna
  integer, allocatable, dimension(:) :: orbrzv_rf_nnphi
  ! wavefield dimensions
  integer :: orbrzv_rf_nx, orbrzv_rf_nth, orbrzv_rf_nsp
  real(fp) :: orbrzv_rf_dx, orbrzv_rf_dth

  ! rf-information for each antenna
  type(mcrf_wavefield_type), allocatable, dimension(:,:) :: orbrzv_rfw

  ! temp storage for kp, ep, pol
  !real(fp), allocatable, dimension(:,:) :: orbrzv_zkp, orbrzv_zep
  !complex*16, allocatable, dimension(:,:) :: orbrzv_zpol

  ! total rf-kick and bad resonance crossing
  integer :: orbrzv_rf_nkick, orbrzv_rf_nbadc

  ! kjm-rfdbg --------------
  !integer :: orbrzv_its, orbrzv_norbit
  ! kjm-rfdbg --------------

  ! max & min of gyro-frequency of fast ion
  real(fp) :: orbrzv_omgc_max, orbrzv_omgc_min
  ! scan range of harmonic during simulation 1 <= lmin <= lmax <= llmax
  integer, allocatable, dimension(:) :: orbrzv_lmin, orbrzv_lmax
  ! resonance time cutoff
  real(fp), allocatable, dimension(:) :: orbrzv_trmax

  ! temp storage for bessel function
  real(fp), allocatable, dimension(:) :: orbrzv_zbesl

  ! total prficha in this time step 
  ! this value is used to determine whether to calculate mcrf
  ! in this time step
  logical :: mcrf_on

  ! toric field ampulitude renormalizer --> nbspec.dat orbrzv_frnm

  ! additional time step control near rf-resonance
  logical :: nlmcrfgcon
  real(fp), parameter :: orbrzv_rf_dist = 3.0_fp ! should be greater than 1.0
  real(fp) :: orbrzv_zzerr_con0, orbrzv_rferr_con = 1.0e-4_fp
  real(fp) :: orbrzv_ztf_min, orbrzv_zrfd_min, &
            & orbrzv_rfdv(-1:2), & ! rf-induced variations per half bounce
            & orbrzv_bnw, orbrzv_rhopm, &   ! orbit width
            & orbrzv_rmid0, orbrzv_trpas, & ! mid-plane crossing point & trpas
            & orbrzv_bnw_lrf ! orbit width / rf-length scale
  ! # of 'real' mid-plane crossing
  integer :: orbrzv_nmidc

  ! debugging information for resonance monitor
  real(fp), allocatable, dimension(:,:) :: rfdbg_pdiag

  integer :: orbrzv_where

  ! my_rfdist_diag
!mg 11/16 cleanup  integer :: orbrzv_my_nr, orbrzv_my_ne, orbrzv_my_nx
!mg 11/16 cleanup  real(fp), allocatable, dimension(:,:,:) :: orbrzv_my_rfdist
!mg 11/16 cleanup  real(fp), allocatable, dimension(:,:,:) :: orbrzv_my_rfdist_tmp

  ! diagnostic variables
  ! density profile of particles interacting with rf
  real(fp), allocatable, dimension(:,:,:) :: orbrzv_nrf
  ! toric power profiles for comparison and renormalization of rf-field
  integer :: orbrzv_fbm_nvl = 20, orbrzv_fbm_nvp = 20
  integer :: orbrzv_fbm_cnt
  real(fp), allocatable, dimension(:) :: orbrzv_fbm_dvl, orbrzv_fbm_dvp
  real(fp), allocatable, dimension(:,:,:,:) :: orbrzv_fbm, orbrzv_fbm_tmp

  ! temporary buffer to communicate with toric
  integer :: mcrf_nsize(1:3)
  integer, allocatable, dimension(:) :: mcrf_iarry1
  real(fp), allocatable, dimension(:) :: mcrf_rarry1
  real(fp), allocatable, dimension(:) :: mcrf_kbuf, mcrf_ebuf
  complex(c_double_complex), allocatable, dimension(:) :: mcrf_pbuf
  type(rfxqlo_outpro), allocatable, dimension(:,:) :: mcrf_prof
  integer :: mcrf_nbuf(1:3)
  integer, allocatable, dimension(:) :: mcrf_ibuf
  real(fp), allocatable, dimension(:) :: mcrf_rbuf
  !---------------------------------------------------------------------

  ! comment list
  ! kjm-rfdbg : master comment related to rf-debugging
  ! kjm-rfdbg-nogoose : for no goosing
  ! kjm-rfdbg-goose : for additional goosing for rf

end module orbrzv
