module opt_prop

  use dc_types

  use opt_prop_lbl

  implicit none

  private

  public :: OptPropInit
  public :: OptPropFinalize
  public :: OptPropGetNWN
  public :: OptPropGetNPress
  public :: OptPropGetNMol
  public :: OptPropGetDelWN
  public :: OptPropGetWN
  public :: OptPropGetAbsCoefProf
  public :: OptPropGetPFInted
  public :: OptPropGetPFIntedRatio


  integer, save               :: IDMethod
  integer, parameter          :: IDMethodLBL = 1


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

  logical, save :: FlagInited = .false.

contains

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

  subroutine OptPropInit( &
    & Type, &
    & OptPropNcFN &
    & )

    character(*), intent(in) :: Type
    character(*), intent(in) :: OptPropNcFN

    if ( FlagInited ) return


    select case ( Type )
    case ( 'LBL' )
      IDMethod = IDMethodLBL
    case default
      write( 6, * ) trim( ModuleName )
      write( 6, * ) 'Unexpected type: ', trim( Type )
      stop
    end select


    select case ( IDMethod )
    case ( IDMethodLBL )
      call OptPropLBLInit( &
        & OptPropNcFN &
        & )
    end select


    FlagInited = .true.

  end subroutine OptPropInit

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

  subroutine OptPropFinalize


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


    select case ( IDMethod )
    case ( IDMethodLBL )
      call OptPropLBLFinalize
    end select


    FlagInited = .false.

  end subroutine OptPropFinalize

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

  function OptPropGetNWN() result( NWN )


    integer :: NWN

    ! local variables
    !


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


    select case ( IDMethod )
    case ( IDMethodLBL )
      NWN = OptPropLBLGetNWN()
    end select


  end function OptPropGetNWN

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

  function OptPropGetNPress() result( NPress )


    integer :: NPress

    ! local variables
    !


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


    select case ( IDMethod )
    case ( IDMethodLBL )
      NPress = OptPropLBLGetNPress()
    end select


  end function OptPropGetNPress

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

  function OptPropGetNMol() result( NMol )


    integer :: NMol

    ! local variables
    !


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


    select case ( IDMethod )
    case ( IDMethodLBL )
      NMol = OptPropLBLGetNMol()
    end select


  end function OptPropGetNMol

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

  function OptPropGetDelWN() result( DelWaveNum )


    real(DP) :: DelWaveNum

    ! local variables
    !


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


    select case ( IDMethod )
    case ( IDMethodLBL )
      DelWaveNum = OptPropLBLGetDelWN()
    end select


  end function OptPropGetDelWN

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

  function OptPropGetWN( iWaveNum ) result( WaveNum )


    integer, intent(in) :: iWaveNum

    real(DP) :: WaveNum

    ! local variables
    !


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


    select case ( IDMethod )
    case ( IDMethodLBL )
      WaveNum = OptPropLBLGetWN( iWaveNum )
    end select


  end function OptPropGetWN

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

  subroutine OptPropGetAbsCoefProf( &
    & iWaveNum, NPress, NMol, &
    & zm_AbsCoef &
    & )


    integer     , intent(in ) :: iWaveNum
    integer     , intent(in ) :: NPress
    integer     , intent(in ) :: NMol
    real(DP)    , intent(out) :: zm_AbsCoef(1:NPress,1:NMol)


    ! local variables
    !


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


    select case ( IDMethod )
    case ( IDMethodLBL )
      call OptPropLBLGetAbsCoefProf( &
        & iWaveNum, NPress, NMol, &
        & zm_AbsCoef &
        & )
    end select

  end subroutine OptPropGetAbsCoefProf

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

  subroutine OptPropGetPFInted( &
    & iWaveNum, &
    & kmax, &
    & r_Temp, SurfTemp, &
    & r_PFInted, SurfPFInted, SurfDPFDTInted &
    & )

    integer , intent(in ) :: iWaveNum
    integer , intent(in ) :: kmax
    real(DP), intent(in ) :: r_Temp(0:kmax)
    real(DP), intent(in ) :: SurfTemp
    real(DP), intent(out) :: r_PFInted  (0:kmax)
    real(DP), intent(out) :: SurfPFInted
    real(DP), intent(out) :: SurfDPFDTInted


    ! local variables
    !


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


    select case ( IDMethod )
    case ( IDMethodLBL )
      call OptPropLBLGetPFInted( &
        & iWaveNum, &
        & kmax, &
        & r_Temp, SurfTemp, &
        & r_PFInted, SurfPFInted, SurfDPFDTInted &
        & )
    end select


  end subroutine OptPropGetPFInted

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

  subroutine OptPropGetPFIntedRatio( &
    & iWaveNum, NPress, &
    & z_PFRatio, SurfPFRatio &
    & )

    integer     , intent(in ) :: iWaveNum
    integer     , intent(in ) :: NPress
    real(DP)    , intent(out) :: z_PFRatio(1:NPress)
    real(DP)    , intent(out) :: SurfPFRatio


    ! local variables
    !


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


    select case ( IDMethod )
    case ( IDMethodLBL )
      call OptPropLBLGetPFIntedRatio( &
        & iWaveNum, NPress, &
        & z_PFRatio, SurfPFRatio &
        & )
    end select


  end subroutine OptPropGetPFIntedRatio

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

end module opt_prop

