module rad_rte_two_stream_app_1d_wrapper

  use vtype_module
!!$  use rad_rte_two_stream_app_v2, only : &
!!$    & IDScatApproxEddington, &
!!$    & IDScatApproxHemiMean
  use rad_rte_two_stream_app_v3, only : &
    & IDScatApproxEddington, &
    & IDScatApproxHemiMean

  implicit none

  private

  public :: RadRTETwoStreamApp1DWrapper
  public :: RadRTETwoStreamApp1DLWWrapper
  public :: RadRTETwoStreamApp1DSWWrapper
  public :: RadRTETwoStreamApp1DWrapperInit

  public :: IDScatApproxEddington
  public :: IDScatApproxHemiMean


  integer, parameter :: imax = 1
  integer, parameter :: jmax = 1



  character(128), save :: ModuleName = 'rad_rte_two_stream_app_1d_wrapper'

  logical, save :: FlagInited = .false.

contains

  !----------------------------------------------------------------------------

  subroutine RadRTETwoStreamApp1DWrapper(      &
    & IDScatApprox, FlagSrcFuncTech,           & ! (in)
    & kmax,                                    & ! (in)
    & z_SSA, z_AF,                             & ! (in)
    & r_OptDep,                                & ! (in)
    & SurfAlbedo,                              & ! (in)
    & r_RadUwFlux, r_RadDwFlux,                & ! (out)
    & SolarFluxTOA, InAngle,                   & ! (in)
    & r_PFInted, SurfPFInted, SurfDPFDTInted,  & ! (in)
    & ra_DelRadUwFlux, ra_DelRadDwFlux         & ! (out)
    & )

!!$    use rad_rte_two_stream_app_v2, only : RadRTETwoStreamAppWrapper
    use rad_rte_two_stream_app_v3, only : RadRTETwoStreamAppWrapper

    integer , intent(in ) :: IDScatApprox
    logical , intent(in ) :: FlagSrcFuncTech
    integer , intent(in ) :: kmax
    real(DP), intent(in ) :: z_SSA          (1:kmax)
    real(DP), intent(in ) :: z_AF           (1:kmax)
    real(DP), intent(in ) :: r_OptDep       (0:kmax)
    real(DP), intent(in ) :: SurfAlbedo
    real(DP), intent(out) :: r_RadUwFlux    (0:kmax)
    real(DP), intent(out) :: r_RadDwFlux    (0:kmax)

    real(DP), intent(in ) :: SolarFluxTOA
    real(DP), intent(in ) :: InAngle
    real(DP), intent(in ) :: r_PFInted      (0:kmax)
    real(DP), intent(in ) :: SurfPFInted
    real(DP), intent(in ) :: SurfDPFDTInted
    real(DP), intent(out) :: ra_DelRadUwFlux(0:kmax,-1:1)
    real(DP), intent(out) :: ra_DelRadDwFlux(0:kmax,-1:1)


    ! Local variables
    !
    logical, parameter :: FlagTOAFlux = .true.
    logical, parameter :: FlagEmis    = .true.

    real(DP) :: xyz_SSA       ( 0:imax-1, 1:jmax, 1:kmax )
    real(DP) :: xyz_AF        ( 0:imax-1, 1:jmax, 1:kmax )
    real(DP) :: xyr_OptDep    ( 0:imax-1, 1:jmax, 0:kmax)
    real(DP) :: xy_SurfAlbedo ( 0:imax-1, 1:jmax )
    real(DP) :: xyr_RadUwFlux(0:imax-1, 1:jmax, 0:kmax)
    real(DP) :: xyr_RadDwFlux(0:imax-1, 1:jmax, 0:kmax)

    real(DP) :: xy_InAngle       (0:imax-1, 1:jmax)
    real(DP) :: xyr_PFInted      (0:imax-1, 1:jmax, 0:kmax)
    real(DP) :: xy_SurfPFInted   (0:imax-1, 1:jmax)
    real(DP) :: xy_SurfDPFDTInted(0:imax-1, 1:jmax)
    real(DP) :: xyra_DelRadUwFlux(0:imax-1, 1:jmax, 0:kmax, -1:1)
    real(DP) :: xyra_DelRadDwFlux(0:imax-1, 1:jmax, 0:kmax, -1:1)

    integer :: k
    integer :: l


    if ( .not. FlagInited ) then
      write( 6, * ) trim( ModuleName ), " is not initialized."
      stop
    end if


    do k = 1, kmax
      xyz_SSA(:,:,k) = z_SSA(k)
      xyz_AF (:,:,k) = z_AF (k)
    end do
    do k = 0, kmax
      xyr_OptDep(:,:,k) = r_OptDep(k)
    end do
    xy_SurfAlbedo = SurfAlbedo

    xy_InAngle = InAngle
    do k = 0, kmax
      xyr_PFInted(:,:,k) = r_PFInted(k)
    end do
    xy_SurfPFInted    = SurfPFInted
    xy_SurfDPFDTInted = SurfDPFDTInted



    call RadRTETwoStreamAppWrapper(                &
      & IDScatApprox, FlagTOAFlux, FlagEmis, FlagSrcFuncTech,  & ! (in)
      & imax, jmax, kmax,                                & ! (in)
      & xyz_SSA, xyz_AF,                                 & ! (in)
      & xyr_OptDep,                                      & ! (in)
      & xy_SurfAlbedo,                                   & ! (in)
      & xyr_RadUwFlux, xyr_RadDwFlux,                    & ! (out)
      & SolarFluxTOA, xy_InAngle,                        & ! (in) optional
      & xyr_PFInted, xy_SurfPFInted, xy_SurfDPFDTInted,  & ! (in) optional
      & xyra_DelRadUwFlux, xyra_DelRadDwFlux             & ! (out) optional
      & )


    do k = 0, kmax
      r_RadUwFlux(k) = xyr_RadUwFlux(0,1,k)
      r_RadDwFlux(k) = xyr_RadDwFlux(0,1,k)
    end do
    do l = -1, 1
      do k = 0, kmax
        ra_DelRadUwFlux(k,l) = xyra_DelRadUwFlux(0,1,k,l)
        ra_DelRadDwFlux(k,l) = xyra_DelRadDwFlux(0,1,k,l)
      end do
    end do


  end subroutine RadRTETwoStreamApp1DWrapper

  !----------------------------------------------------------------------------

  subroutine RadRTETwoStreamApp1DLWWrapper(    &
    & kmax,                                    & ! (in)
    & z_SSA, z_AF,                             & ! (in)
    & r_OptDep,                                & ! (in)
    & SurfAlbedo,                              & ! (in)
    & r_PFInted, SurfPFInted, SurfDPFDTInted,  & ! (in)
    & r_RadUwFlux, r_RadDwFlux,                & ! (out)
    & ra_DelRadUwFlux, ra_DelRadDwFlux         & ! (out)
    & )

    ! USE statements
    !
!!$    use rad_rte_two_stream_app_v2, only : RadRTETwoStreamAppLW
    use rad_rte_two_stream_app_v3, only : RadRTETwoStreamAppLW


    integer , intent(in ) :: kmax
    real(DP), intent(in ) :: z_SSA          (1:kmax)
    real(DP), intent(in ) :: z_AF           (1:kmax)
    real(DP), intent(in ) :: r_OptDep       (0:kmax)
    real(DP), intent(in ) :: SurfAlbedo
    real(DP), intent(in ) :: r_PFInted      (0:kmax)
    real(DP), intent(in ) :: SurfPFInted
    real(DP), intent(in ) :: SurfDPFDTInted
    real(DP), intent(out) :: r_RadUwFlux    (0:kmax)
    real(DP), intent(out) :: r_RadDwFlux    (0:kmax)
    real(DP), intent(out) :: ra_DelRadUwFlux(0:kmax, -1:1)
    real(DP), intent(out) :: ra_DelRadDwFlux(0:kmax, -1:1)


    ! Local variables
    !
    real(DP) :: xyz_SSA          (0:imax-1, 1:jmax, 1:kmax)
    real(DP) :: xyz_AF           (0:imax-1, 1:jmax, 1:kmax)
    real(DP) :: xyr_OptDep       (0:imax-1, 1:jmax, 0:kmax)
    real(DP) :: xy_SurfAlbedo    (0:imax-1, 1:jmax)
    real(DP) :: xyr_PFInted      (0:imax-1, 1:jmax, 0:kmax)
    real(DP) :: xy_SurfPFInted   (0:imax-1, 1:jmax)
    real(DP) :: xy_SurfDPFDTInted(0:imax-1, 1:jmax)
    real(DP) :: xyr_RadUwFlux    (0:imax-1, 1:jmax, 0:kmax)
    real(DP) :: xyr_RadDwFlux    (0:imax-1, 1:jmax, 0:kmax)
    real(DP) :: xyra_DelRadUwFlux(0:imax-1, 1:jmax, 0:kmax, -1:1)
    real(DP) :: xyra_DelRadDwFlux(0:imax-1, 1:jmax, 0:kmax, -1:1)

    integer :: k


    if ( .not. FlagInited ) then
      write( 6, * ) trim( ModuleName ), " is not initialized."
      stop
    end if


    do k = 1, kmax
      xyz_SSA    (:,:,k) = z_SSA    (k)
      xyz_AF     (:,:,k) = z_AF     (k)
    end do
    do k = 0, kmax
      xyr_OptDep (:,:,k) = r_OptDep (k)
      xyr_PFInted(:,:,k) = r_PFInted(k)
    end do
    xy_SurfAlbedo     = SurfAlbedo
    xy_SurfPFInted    = SurfPFInted
    xy_SurfDPFDTInted = SurfDPFDTInted

    call RadRTETwoStreamAppLW(                     &
      & imax, jmax, kmax,                                & ! (in)
      & xyz_SSA, xyz_AF,                                 & ! (in)
      & xyr_OptDep,                                      & ! (in)
      & xy_SurfAlbedo,                                   & ! (in)
      & xyr_PFInted, xy_SurfPFInted, xy_SurfDPFDTInted,  & ! (in)
      & xyr_RadUwFlux, xyr_RadDwFlux,                    & ! (out)
      & xyra_DelRadUwFlux, xyra_DelRadDwFlux             & ! (out)
      & )

    r_RadUwFlux     = xyr_RadUwFlux    (0,1,:)
    r_RadDwFlux     = xyr_RadDwFlux    (0,1,:)
    ra_DelRadUwFlux = xyra_DelRadUwFlux(0,1,:,:)
    ra_DelRadDwFlux = xyra_DelRadDwFlux(0,1,:,:)


  end subroutine RadRTETwoStreamApp1DLWWrapper

  !------------------------------------------------------------------------------------

  subroutine RadRTETwoStreamApp1DSWWrapper(      &
    & kmax,                         & ! (in)
    & z_SSA, z_AF,                  & ! (in)
    & r_OptDep,                     & ! (in)
    & SurfAlbedo,                   & ! (in)
    & SolarFluxTOA, InAngle,        & ! (in)
    & r_RadUwFlux, r_RadDwFlux      & ! (out)
    & )

    ! USE statements
    !
!!$    use rad_rte_two_stream_app_v2, only : RadRTETwoStreamAppSW
    use rad_rte_two_stream_app_v3, only : RadRTETwoStreamAppSW

    integer , intent(in ) :: kmax
    real(DP), intent(in ) :: z_SSA      ( 1:kmax )
    real(DP), intent(in ) :: z_AF       ( 1:kmax )
    real(DP), intent(in ) :: r_OptDep   ( 0:kmax )
    real(DP), intent(in ) :: SurfAlbedo
    real(DP), intent(in ) :: SolarFluxTOA
    real(DP), intent(in ) :: InAngle
    real(DP), intent(out) :: r_RadUwFlux( 0:kmax )
    real(DP), intent(out) :: r_RadDwFlux( 0:kmax )

    ! Local variables
    !
    real(DP) :: xyz_SSA      ( 0:imax-1, 1:jmax, 1:kmax )
    real(DP) :: xyz_AF       ( 0:imax-1, 1:jmax, 1:kmax )
    real(DP) :: xyr_OptDep   ( 0:imax-1, 1:jmax, 0:kmax )
    real(DP) :: xy_SurfAlbedo( 0:imax-1, 1:jmax )
    real(DP) :: xy_InAngle   ( 0:imax-1, 1:jmax )
    real(DP) :: xyr_RadUwFlux( 0:imax-1, 1:jmax, 0:kmax )
    real(DP) :: xyr_RadDwFlux( 0:imax-1, 1:jmax, 0:kmax )

    integer :: k


    ! 初期化確認
    ! Initialization check
    !
    if ( .not. FlagInited ) then
      write( 6, * ) "Error: ", trim( ModuleName ), &
        & 'This module has not been initialized.'
      stop
    end if


    do k = 1, kmax
      xyz_SSA(:,:,k)      = z_SSA(k)
      xyz_AF (:,:,k)      = z_AF (k)
    end do
    do k = 0, kmax
      xyr_OptDep(:,:,k)   = r_OptDep(k)
    end do
    xy_SurfAlbedo         = SurfAlbedo
    xy_InAngle            = InAngle

    call RadRTETwoStreamAppSW(      &
      & imax, jmax, kmax,                 & ! (in)
      & xyz_SSA, xyz_AF,                  & ! (in)
      & xyr_OptDep,                       & ! (in)
      & xy_SurfAlbedo,                    & ! (in)
      & SolarFluxTOA, xy_InAngle,         & ! (in)
      & xyr_RadUwFlux, xyr_RadDwFlux      & ! (out)
      & )

    do k = 0, kmax
      r_RadUwFlux(k) = xyr_RadUwFlux(0,1,k)
      r_RadDwFlux(k) = xyr_RadDwFlux(0,1,k)
    end do


  end subroutine RadRTETwoStreamApp1DSWWrapper

  !----------------------------------------------------------------------------

  subroutine RadRTETwoStreamApp1DWrapperInit

!!$    use rad_rte_two_stream_app_v2, only : RadRTETwoStreamAppInit
    use rad_rte_two_stream_app_v3, only : RadRTETwoStreamAppInit


    if ( FlagInited ) return


    call RadRTETwoStreamAppInit


    FlagInited = .true.

  end subroutine RadRTETwoStreamApp1DWrapperInit

  !----------------------------------------------------------------------------

end module rad_rte_two_stream_app_1d_wrapper

