program main

  use vtype_module

  use fi_module
  use xsc_module

  implicit none

  character(extstr) :: CtlFN  = 'conv_xsc2nc.conf'

  integer                        :: NFile
  character(extstr), allocatable :: a_XSCFileName(:)
  character(extstr) :: OutputFileName
  character(extstr) :: Com
  character(extstr) :: Src
  character(extstr) :: Ref

  real(dp) :: WaveNumS
  real(dp) :: WaveNumE
  real(dp) :: ConvFactorWaveNum
  real(dp) :: ConvFactorCoef

  ! Local variables
  !

  integer , parameter   :: MaxNmlArySize = 256
  character(extstr)     :: XSCFileName(MaxNmlArySize)


  type( XSCParam ) :: XSCP

  integer            :: FileUnit
  integer            :: iostat

  integer            :: n


  namelist /file_nml/ &
    & WaveNumS, WaveNumE, &
    & ConvFactorWaveNum, ConvFactorCoef, &
    & XSCFileName, &
    & OutputFileName, &
    & Com, Src, Ref


  WaveNumS = -1.0d0
  WaveNumE =  1.0d100

  XSCFileName    = ""
  OutputFileName = "./out"

  Com = ""
  Src = ""
  Ref = ""

  ! Explanation

  call fi_open( CtlFN, "read", FileUnit )
  !
  rewind( FileUnit )
  read( FileUnit, nml = file_nml, iostat = iostat )
  if ( iostat > 0 ) then
    stop 'Namelist in file_nml is something wrong.'
  end if
  write( 6, nml = file_nml )
  !
  close( FileUnit )

  NFile = 0
  do n = 1, MaxNmlArySize
    if ( len_trim( XSCFileName(n) ) > 0 ) then
      NFile = NFile + 1
    end if
  end do

  allocate( a_XSCFileName(NFile) )
  a_XSCFileName = XSCFileName(1:NFile)

  write( 6, * ) 'Input  File: '
  do n = 1, NFile
    write( 6, * ) '  ', trim( a_XSCFileName(n) )
  end do
  write( 6, * ) 'Output File: ', trim( OutputFileName )

  call ReadASIIXSCFile( &
    & NFile, a_XSCFileName, &
    & WaveNumS, WaveNumE, &
    & ConvFactorWaveNum, ConvFactorCoef, &
    & XSCP &
    & )
  call XSCWriteFileNetcdf( OutputFileName, Src, Com, Ref, XSCP )
  call XSCParamFinalize( XSCP )

  deallocate( a_XSCFileName )


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

contains

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

  subroutine ReadASIIXSCFile( &
    & NFile, a_FileName, &
    & WaveNumLimS, WaveNumLimE, &
    & ConvFactorWaveNum, ConvFactorCoef, &
    & XSCP &
    & )

    use fi_module
    use xsc_module

    integer          , intent(in ) :: NFile
    character(extstr), intent(in ) :: a_FileName(NFile)
    real(dp)         , intent(in ) :: WaveNumLimS
    real(dp)         , intent(in ) :: WaveNumLimE
    real(dp)         , intent(in ) :: ConvFactorWaveNum
    real(dp)         , intent(in ) :: ConvFactorCoef
    type( XSCParam ) , intent(out) :: XSCP


    ! Local variables
    !
    integer :: NTemp

    character(20) :: ChemSym = "CO2"
    integer       :: NWaveNum
    real(dp)      :: Temp
    real(dp)      :: Press

    real(dp), allocatable :: w_WaveNum(:)
    real(dp), allocatable :: t_Temp   (:)
    real(dp), allocatable :: wt_Coef  (:,:)

    integer               :: iWaveNumS
    integer               :: iWaveNumE
    integer               :: NWaveNumBK
    real(dp), allocatable :: w_WaveNumBK(:)
    real(dp), allocatable :: wt_CoefBK  (:,:)

    integer :: IMol

    character(stdstr)  :: Mode
    integer            :: FileUnit
!!$    integer            :: iostat

    integer            :: NLoop

    integer            :: NLine
    integer            :: NHeader = 3
    integer            :: NFooter = 0
    integer            :: NLineSave

    integer            :: l
    integer            :: n
    integer            :: t


    ! check file
    do n = 1, NFile
      Mode = "read"
      NLine = fi_lc( a_FileName(n), NHeader, NFooter )
      if ( n == 1 ) then
        NLineSave = NLine
      else
        if ( NLineSave /= NLine ) then
          write( 6, * ) 'NLine is not the same for all files.'
          write( 6, * ) NLineSave, NLine
          stop
        end if
      end if
    end do


    ! At a line next to header, temperature is written.
    NLine = NLine - 1

    NTemp        = NFile
    NWaveNum     = NLine

    if ( NTemp <= 1 ) then
      write( 6, * ) 'ERROR: Number of temperature has to be greater than 1.'
      stop
    end if

    allocate( w_WaveNum( NWaveNum ) )
    allocate( t_Temp   ( NTemp    ) )
    allocate( wt_Coef  ( NWaveNum, NTemp ) )

    do n = 1, NFile
      Mode = "read"
      call fi_open( a_FileName(n), Mode, FileUnit )
      !
      do l = 1, NHeader
        read( FileUnit, * )
      end do
      read( FileUnit, * ) Temp
      !
      t_Temp(n) = Temp
      !
      NLoop = NWaveNum
      do l = 1, NLoop
        read( FileUnit, * ) w_WaveNum(l), wt_Coef(l,n)
      end do
      !
      close( FileUnit )
    end do

    do l = 1+1, NWaveNum
      if ( w_WaveNum(l-1) > w_WaveNum(l) ) then
        write( 6, * ) 'Order of wavenumber is inappropriate: ', l-1, w_WaveNum(l-1), w_WaveNum(l)
        stop
      end if
    end do


    ! unit of coefficient is changed from cm2 molecule-1 to m2 molecule-1
    w_WaveNum = 1.0d0 / w_WaveNum * ConvFactorWaveNum
    wt_Coef   = wt_Coef           * ConvFactorCoef

    allocate( w_WaveNumBK(NWaveNum)       )
    allocate( wt_CoefBK  (NWaveNum,NTemp) )
    w_WaveNumBK = w_WaveNum
    wt_CoefBK   = wt_Coef
    do l = 1, NWaveNum
      w_WaveNum(l) = w_WaveNumBK(NWaveNum-l+1)
      do t = 1, NTemp
        wt_Coef(l,t) = wt_CoefBK(NWaveNum-l+1,t)
      end do
    end do
    deallocate( w_WaveNumBK )
    deallocate( wt_CoefBK   )

    if ( ( NTemp         == 2             ) .and. &
      &  ( t_Temp(1)     == t_Temp(2)     ) .and. &
      &  ( a_FileName(1) == a_FileName(2) ) ) then
      write( 6, * ) 'NOTE: Temperature is modified: '
      write( 6, * ) '  Original values: ', t_Temp
      t_Temp(2) = t_Temp(2) + 1.0d0
      write( 6, * ) '  Modified valies: ', t_Temp
    else
      do t = 1+1, NTemp
        if ( t_Temp(t-1) >= t_Temp(t) ) then
          write( 6, * ) 'Order of file (temperature) is inappropriate.'
          write( 6, * ) t_Temp
          stop
        end if
      end do
    end if

    !
    ! Restrict wavenumber range
    !
    NWaveNumBK = NWaveNum
    allocate( w_WaveNumBK(NWaveNumBK)       )
    allocate( wt_CoefBK  (NWaveNumBK,NTemp) )
    w_WaveNumBK = w_WaveNum
    wt_CoefBK   = wt_Coef
    deallocate( w_WaveNum )
    deallocate( wt_Coef   )
    !
    NWaveNum = 0
    do l = 1, NWaveNumBK
      if ( WaveNumLimS <= w_WaveNumBK(l) ) exit
    end do
    iWaveNumS = l
    do l = NWaveNumBK, 1, -1
      if ( w_WaveNumBK(l) <= WaveNumLimE ) exit
    end do
    iWaveNumE = l
    !
    NWaveNum = iWaveNumE - iWaveNumS + 1
    allocate( w_WaveNum(NWaveNum)       )
    allocate( wt_Coef  (NWaveNum,NTemp) )
    do t = 1, NTemp
      do l = 1, NWaveNum
        w_WaveNum(l)   = w_WaveNumBK(l+iWaveNumS-1)
        wt_Coef  (l,t) = wt_CoefBK  (l+iWaveNumS-1,t)
      end do
    end do
    deallocate( w_WaveNumBK )
    deallocate( wt_CoefBK   )


    call XSCGetIMol( &
      & ChemSym, &
      & IMol &
      & )

    call XSCStoreDataInObj( &
      & IMol, &
      & NWaveNum, NTemp, Press, w_WaveNum, t_Temp, wt_Coef, &
      & XSCP  &
      & )

    deallocate( w_WaveNum )
    deallocate( t_Temp    )
    deallocate( wt_Coef   )


  end subroutine ReadASIIXSCFile

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

end program main
