!
!#######
!#     #  #####    #####     #     ####   #    #   ####
!#     #  #    #     #       #    #    #  ##   #  #
!#     #  #    #     #       #    #    #  # #  #   ####
!#     #  #####      #       #    #    #  #  # #       #
!#     #  #          #       #    #    #  #   ##  #    #
!#######  #          #       #     ####   #    #   ####
!
!  $Author: pkubota $
!  $Date: 2008/09/23 17:51:54 $
!  $Revision: 1.9 $
!
MODULE Options
  USE Constants, Only: &
       r8,             &
       i8
  USE Parallelism, ONLY: &
       MsgOne,           &
       FatalError

  IMPLICIT NONE
  CHARACTER(LEN=10),PUBLIC   :: rootmode='JACKSON'    ! Jackson et al., 1996:   or !rootmode='MILENA'  Milena et al., 2020: 
  CHARACTER(LEN=20) , PUBLIC           :: NMSOILM='soilmaoi'
  REAL(KIND=r8), PUBLIC      :: DELTAIN =3600.0_r8*6.0_r8 !s 
  REAL(KIND=r8), PUBLIC      :: DELTAOUT=3600.0_r8!*6.0_r8 !s 
   REAL(KIND=r8), PUBLIC   , PARAMETER :: pi   = 3.1415927_r8   ! you know, that constant thingy
  LOGICAL           , PUBLIC           :: reducedGrid=.FALSE.
  INTEGER           , PUBLIC           :: initlz=2
  INTEGER           , PUBLIC           :: monl(12)=(/31,28,31,30,31,30,31,31,30,31,30,31/)
  REAL(KIND=r8)    , PUBLIC           :: yrl=365.25_r8
  INTEGER           , PUBLIC           :: ifalb=0
  INTEGER           , PUBLIC           :: ifsst=-1
  INTEGER           , PUBLIC           :: ifslm=3
  INTEGER           , PUBLIC           :: ifsnw=3
  INTEGER           , PUBLIC           :: ifozone=0
  REAL(KIND=r8)    , PUBLIC           :: sstlag =3.5_r8
  INTEGER           , PUBLIC           :: intsst =-1
  REAL(KIND=r8)    , PUBLIC           :: fint    =6.0_r8
  INTEGER           , PUBLIC           :: iglsm_w =0
  INTEGER           , PUBLIC           :: mxiter  =200
  INTEGER , PUBLIC                     :: nftgz0=61     ! ground temperature file
  INTEGER , PUBLIC                     :: nfzol=71      ! Roughness Length file
  INTEGER , PUBLIC                     :: nfsoiltp=22   ! soil type GL_FAO_01patches file
  INTEGER , PUBLIC                     :: nfvegtp=23    ! vegetation type GL_VEG_SIB_05patches file
  INTEGER , PUBLIC                     :: nfslmtp=24    ! soil moisture GL_SM file
  INTEGER , PUBLIC                     :: nfsibi=77     ! sib prognostic variable input  file
  INTEGER                              :: nNameList=17     ! namelist read
  INTEGER , PUBLIC                     :: nfsibt=99     ! sib surface vegetation type
  INTEGER , PUBLIC                     :: nfslm=53      ! soil moisture file
  CHARACTER(len=3)  , PUBLIC           :: iswrad="LCH"
  CHARACTER(len=3)  , PUBLIC           :: ilwrad="HRS"  
  CHARACTER(len=4)  , PUBLIC           :: isimp ="NO  "
  INTEGER           , PUBLIC           :: intndvi=-1
  INTEGER , PUBLIC                     :: nfprt=6 !standard print out unit
  !0 no print, 1 less detail, 2 more detail, 3 most detail
  INTEGER , PUBLIC                     :: nfctrl(100)=(/& ! print control: from 0 (noprint) to 3 (most detail)
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /)
  INTEGER , PUBLIC                     :: nfsibd=88     ! sib vegetation parameter
  INTEGER , PUBLIC                     :: nfalb=52      ! albedo file

  REAL(KIND=r8)     , PUBLIC           :: filta=0.92e0_r8
  INTEGER            , PUBLIC           :: ifndvi=-1
  INTEGER           , PUBLIC           :: ifslmSib2=3  
  REAL(KIND=r8)    , PUBLIC            :: epsflt
  LOGICAL           , PUBLIC           :: Model1D=.FALSE.
  INTEGER, PUBLIC :: schemes=1
  CHARACTER(LEN=211), PUBLIC           :: fNameTg3zrl
  CHARACTER(LEN=255), PUBLIC           :: fNameRouLen
  CHARACTER(LEN=253), PUBLIC           :: fNameList
  CHARACTER(LEN=206), PUBLIC           :: fNameSibVeg
  CHARACTER(LEN=255), PUBLIC           :: fNameSibmsk
  CHARACTER(LEN=255), PUBLIC           :: fNameIBISMask
  CHARACTER(LEN=200), PUBLIC           :: fNameSSTAOI
  CHARACTER(LEN=255), PUBLIC           :: fNameIBISDeltaTemp
  CHARACTER(LEN=255), PUBLIC           :: fNameSandMask
  CHARACTER(LEN=255), PUBLIC           :: fNameClayMask
  CHARACTER(LEN=255), PUBLIC           :: fNameClimaTemp
  CHARACTER(LEN=211), PUBLIC           :: fNameSoilmsWkl
  CHARACTER(LEN=211), PUBLIC           :: fNameSoilms
  LOGICAL           , PUBLIC          :: RESTART=.FALSE.
  LOGICAL           , PUBLIC          :: UNDIMENSION=.FALSE.
  CHARACTER(LEN=255), PUBLIC           :: path_inp
  CHARACTER(LEN=255), PUBLIC           :: path_out
  CHARACTER(LEN=255), PUBLIC           :: icn_data='GLDAS'
  INTEGER , PUBLIC                     :: idate (4)
  INTEGER , PUBLIC                     :: idatec(4)
  INTEGER , PUBLIC                     :: idatep(4)
  INTEGER , PUBLIC                     :: maxtim=0
  REAL(KIND=r8) , PUBLIC              :: dt
  REAL(KIND=r8) , PUBLIC              :: tod
  REAL(KIND=r8) , PUBLIC              :: tod2
  INTEGER , PUBLIC                     :: ifday
  INTEGER , PUBLIC                     :: ifday2
  CHARACTER(LEN=10 ), PUBLIC           :: labelsi
  CHARACTER(LEN=10 ), PUBLIC           :: labelsj
  INTEGER , PUBLIC                     :: intg
  INTEGER , PUBLIC                     :: istrt
  INTEGER , PARAMETER                    :: nsoilay=6
  INTEGER  ,  PUBLIC, PARAMETER                    :: nSite=10
  INTEGER , PUBLIC	      :: type_veg(nSite)
  REAL(KIND=r8)   ,  PUBLIC	     :: lon_site   (nSite)
  REAL(KIND=r8)   ,  PUBLIC	     :: lat_site   (nSite)
  REAL(KIND=r8)   ,  PUBLIC	     :: deltat_site(nSite)
  REAL(KIND=r8)   ,  PUBLIC	     :: sand_site (nsoilay*nSite)
  REAL(KIND=r8)   ,  PUBLIC	     :: clay_site (nsoilay*nSite)
  REAL(KIND=r8)   ,  PUBLIC	     :: clmt_site (12     *nSite)
  REAL(KIND=r8)   ,  PUBLIC	     :: tgrnd_site (nSite)        
  REAL(KIND=r8)   ,  PUBLIC	     :: wsoil_site (nSite)         
  REAL(KIND=r8)   ,  PUBLIC	     :: zorol_site (nSite)         
  REAL(KIND=r8)   ,  PUBLIC	     :: gtsea_site (nSite)
CONTAINS

  SUBROUTINE InitOptions (iMax,jMax,kMax)
    INTEGER       , INTENT(OUT  ) :: iMax
    INTEGER       , INTENT(OUT  ) :: jMax  
    INTEGER       , INTENT(OUT  ) :: kMax
    CHARACTER(LEN= 10)                 :: LABELI
    CHARACTER(LEN= 10)                 :: LABELC
    CHARACTER(LEN= 10)                 :: LABELF
    INTEGER          :: IDATEI(4)
    INTEGER          :: IDATEF(4)
    INTEGER          :: ierr
    INTEGER          :: i
    LOGICAL          :: lexist
    CHARACTER(LEN=8)  :: c0
    CHARACTER(LEN=8)  :: LABELS

    CHARACTER(LEN=*), PARAMETER :: h="**(InitOptions)**"

    NAMELIST /IBIS_RES/UNDIMENSION,iMax,jMax,kMax,IDATEI,IDATEF,dt,NMSOILM, rootmode,icn_data,DELTAIN , DELTAOUT,path_inp,path_out
    NAMELIST /IBIS_DATA/type_veg,lon_site, lat_site,deltat_site,sand_site,clay_site,clmt_site,tgrnd_site,&
                      wsoil_site,zorol_site,gtsea_site

    ! Reads namelist file
    
    !INTEGER :: IARGC
    !EXTERNAL IARGC

    !IF (iargc().eq.0) THEN
       fnamelist="IBISIN"
    !ELSE
    !   CALL getarg(1,fnamelist)
    !ENDIF
    OPEN(UNIT=nNameList,FILE=fNameList, ACTION="read",STATUS="old", IOSTAT=ierr)
    IF (ierr /= 0) THEN
       WRITE(c0,"(i8)") ierr
       CALL FatalError(h//" open namelist file "//TRIM(ADJUSTL(fNameList))//&
            " returned iostat="//TRIM(ADJUSTL(c0)))
    END IF
    READ (nNameList,IBIS_RES, iostat=ierr)
    IF (ierr /= 0) THEN
       WRITE(c0,"(i8)") ierr
       CALL FatalError(h//" read namelist IBIS_RES from file "//&
            TRIM(ADJUSTL(fNameList))//" returned iostat="//&
            TRIM(ADJUSTL(c0)))
    END IF
    READ (nNameList,IBIS_DATA, iostat=ierr)

    IF (ierr /= 0) THEN
       WRITE(c0,"(i8)") ierr
       CALL FatalError(h//" read namelist IBIS_DATA from file "//&
            TRIM(ADJUSTL(fNameList))//" returned iostat="//&
            TRIM(ADJUSTL(c0)))
    END IF

     idate(1) = IDATEI(1)
     idate(3) = IDATEI(2)
     idate(2) = IDATEI(3)
     idate(4) = IDATEI(4)

    CALL ntimestep(IDATEI,IDATEF,dt,maxtim)

     idatec=idate
     idatep=idate
    c0='        '
    WRITE(LABELS,'(i4.4,2i2.2)')idate(4),idate(2),idate(3)
    WRITE (labelsi(1: 4), '(I4.4)') idate(4)
    WRITE (labelsi(5: 6), '(I2.2)') 01
    WRITE (labelsi(7: 8), '(I2.2)') 16
    WRITE (labelsi(9:10), '(I2.2)') 12
    WRITE (labelsj(1: 4), '(I4.4)') idate(4)
    WRITE (labelsj(5: 6), '(I2.2)') 02
    WRITE (labelsj(7: 8), '(I2.2)') 14
    WRITE (labelsj(9:10), '(I2.2)') 00

    WRITE(LABELI,'(i4.4,3i2.2)')IDATEI(4),IDATEI(3),IDATEI(2),IDATEI(1)
    WRITE(LABELC,'(i4.4,3i2.2)')IDATEI(4),IDATEI(3),IDATEI(2),IDATEI(1)
    WRITE(LABELF,'(i4.4,3i2.2)')IDATEF(4),IDATEF(3),IDATEF(2),IDATEF(1)

    IF(TRIM(NMSOILM) == 'soilmdyd')THEN
       iglsm_w=0
       ifslm=5
    ELSE IF(TRIM(NMSOILM) =='soilmwkl')THEN
       iglsm_w=1
       ifslm=1
    ELSE IF(TRIM(NMSOILM) == 'soilmaoi') THEN
       iglsm_w=0
       ifslm=3
    ELSE
       iglsm_w=0
       ifslm=3
    END IF
!    if (myid.eq.0) write(*,*) 'ifslm',  ifslm
    IF(iglsm_w == 1) THEN
       ifslm=0
       ifslmSib2=0
    END IF 


    WRITE(c0,"(i5.5)") jMax
    IF(.NOT.UNDIMENSION )THEN
       ! SET DEEP SOIL TEMPERATURE FIELD FILE NAME
 
       fNameTg3zrl = TRIM(path_inp)//'/DeepSoilTemperature'//'.G'//TRIM(c0)
       INQUIRE (FILE=TRIM(fNameTg3zrl),exist=lexist)
       IF (.NOT. lexist) THEN
          CALL FatalError(h//" file "//TRIM(fNameTg3zrl)//" does not exist")
       END IF

       ! SET ROUGHNESS LENGTH FIELD FILE NAME

       fNameRouLen = TRIM(path_inp)//'/RoughnessLength'//'.G'//TRIM(c0)
       INQUIRE (FILE=TRIM(fNameRouLen),exist=lexist)
       IF (.NOT. lexist) THEN
          CALL FatalError(h//" file "//TRIM(fNameRouLen)//" does not exist")
       END IF

       ! SET SSIB PARAMETER OF VEGETATION FILE NAME

       fNameSibVeg = TRIM(path_inp)//'/VegetationSSiB'
       INQUIRE (FILE=TRIM(fNameSibVeg),exist=lexist)
       IF (.NOT. lexist) THEN
          CALL FatalError(h//" file "//TRIM(fNameSibVeg)//" does not exist")
       END IF

       ! SET CLIMATOLOGICAL VEGETATION MASK FILE NAME

       fNameSibmsk = TRIM(path_inp)//'/VegetationMask'//'.G'//TRIM(c0)
       INQUIRE (FILE=TRIM(fNameSibmsk),exist=lexist)
       IF (.NOT. lexist) THEN
          CALL FatalError(h//" file "//TRIM(fNameSibmsk)//" does not exist")
       END IF

       ! SET LOOKUP MAP OF SOIL TYPES FILE NAME	  

       fNameIBISMask = TRIM(path_inp)//'/VegetationMaskIBIS'//'.G'//TRIM(c0)
       INQUIRE (FILE=TRIM(fNameIBISMask),exist=lexist)
       IF (.NOT. lexist) THEN
          CALL FatalError(h//" file "//TRIM(fNameIBISMask)//" does not exist")
       END IF

       ! SET CLIMATOLOGICAL SEA SURFACE TEMPERATURE FILE NAME	  

       !fNameSSTAOI=TRIM(path_inp)//'/SSTClima'//LABELS//'.G'//TRIM(c0)
       !INQUIRE (FILE=TRIM(fNameSSTAOI),exist=lexist)
       !IF (.NOT. lexist) THEN
       !   CALL FatalError(h//" file "//TRIM(fNameSSTAOI)//" does not exist")
       !END IF

       ! SET FILE NAME OF THE ABSOLUTE MINIMUM TEMPERATURE - TEMP ON AVERAGE OF COLDEST MONTH (C)

       fNameIBISDeltaTemp = TRIM(path_inp)//'/DeltaTempColdes'//'.G'//TRIM(c0)
       INQUIRE (FILE=TRIM(fNameIBISDeltaTemp),exist=lexist)
       IF (.NOT. lexist) THEN
          CALL FatalError(h//" file "//TRIM(fNameIBISDeltaTemp)//" does not exist")
       END IF
    
       ! SET LOOKUP MAP OF SOIL PERCENT SAND    FILE NAME

       fNameSandMask = TRIM(path_inp)//'/PorceSandMaskIBIS'//'.G'//TRIM(c0)
       INQUIRE (FILE=TRIM(fNameSandMask),exist=lexist)
       IF (.NOT. lexist) THEN
          CALL FatalError(h//" file "//TRIM(fNameSandMask)//" does not exist")
       END IF
    
       ! SET LOOKUP MAP OF SOIL PERCENT CLAY  FILE NAME

       fNameClayMask = TRIM(path_inp)//'/PorceClayMaskIBIS'//'.G'//TRIM(c0)
       INQUIRE (FILE=TRIM(fNameClayMask),exist=lexist)
       IF (.NOT. lexist) THEN
          CALL FatalError(h//" file "//TRIM(fNameClayMask)//" does not exist")
       END IF

       ! SET LOOKUP MAP OF CLIMATE TEMPERATURE 2 METERS  FILE NAME

       fNameClimaTemp = TRIM(path_inp)//'/Temperature'//'.G'//TRIM(c0)
       INQUIRE (FILE=TRIM(fNameClimaTemp),exist=lexist)
       IF (.NOT. lexist) THEN
          CALL FatalError(h//" file "//TRIM(fNameClimaTemp)//" does not exist")
       END IF	 

       ! SET CLIMATOLOGICAL SOIL MOISTURE FILE NAME

       fNameSoilms = TRIM(path_inp)//'/SoilMoisture'//'.G'//TRIM(c0)
       INQUIRE (FILE=TRIM(fNameSoilms),exist=lexist)
       IF (.NOT. lexist) THEN
          CALL FatalError(h//" file "//TRIM(fNameSoilms)//" does not exist")
       END IF 

       ! SET OBSERVED SOIL MOISTURE FILE NAME
                                      
       fNameSoilmsWkl = TRIM(path_inp)//'SoilMoistureWeekly'//'.'//LABELI(1:8)//'.G'//c0
    
    END IF
    !
    !     intg=2  time integration of surface physical variable is done
    !     by leap-frog implicit scheme. this conseves enegy and h2o.
    !     intg=1  time integration of surface physical variable is done
    !     by backward implicit scheme.
    !
    intg =2
    IF(intg == 1) THEN
       epsflt=0.0e0_r8
    ELSE
       epsflt=0.5e0_r8 *(1.0e0_r8 -filta)
    END IF

  END SUBROUTINE InitOptions


 SUBROUTINE ntimestep(idate,idatec,dt,ntstep)
   IMPLICIT NONE
   INTEGER, INTENT(IN	  ) :: idate (4)
   INTEGER, INTENT(IN	  ) :: idatec(4)
   REAL(KIND=r8),INTENT(IN) :: dt
   INTEGER, INTENT(OUT	  ) :: ntstep
   INTEGER                  :: yi
   INTEGER		    :: mi
   INTEGER		    :: di
   INTEGER		    :: hi
   INTEGER		    :: yf
   INTEGER		    :: mf
   INTEGER		    :: df
   INTEGER		    :: hf
   REAL(KIND=r8)            :: dh
   REAL(KIND=r8)	    :: xday
   REAL(KIND=r8)	    :: datehr
   REAL(KIND=r8)	    :: datehf
   INTEGER		    :: nday
   INTEGER                  :: md(12)
   REAL(KIND=r8)            :: ybi
   INTEGER                  :: nts
    hi = idate (1)
    di = idate (2)
    mi = idate (3)
    yi = idate (4)
    hf = idatec(1)
    df = idatec(2)
    mf = idatec(3)
    yf = idatec(4)
    CALL jull(yi,mi,di,hi,xday)
    datehr=yi+(xday/365.25e0_r8)
    CALL jull(yf,mf,df,hf,xday)
    datehf=yf+(xday/365.25e0_r8)
    nday=0
    IF(yi == yf .AND. mi==mf .AND. di==df) THEN
       nday=0
    ELSE
       DO WHILE (datehr < datehf)
          nday=nday+1
          ybi=MOD(yi,4)
          IF ( ybi == 0.0_r8 )THEN
             md =(/31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31/)
          ELSE
             md =(/31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31/)
          END IF
          di=di+1
          IF( di > md(mi) )THEN
             di=1
             mi=mi+1
             IF ( mi > 12 ) THEN
                mi=1
                yi=yi+1
             END IF
          END IF
          CALL jull(yi,mi,di,hi,xday)
          datehr=yi+(xday/365.25e0_r8)
       END DO
    END IF
    ntstep=(nday)*86400.0_r8/dt
    IF ( hi /= hf ) THEN
       dh =hf-hi
       nts=dh*3600.0_r8/dt
       ntstep=ntstep+nts
    END IF  
 END SUBROUTINE ntimestep
 SUBROUTINE jull(yi,mi,di,hi,xday)

   INTEGER, INTENT(IN	) :: yi
   INTEGER, INTENT(IN	) :: mi
   INTEGER, INTENT(IN	) :: di
   INTEGER, INTENT(IN	) :: hi
   REAL(KIND=r8)   , INTENT(OUT  ) :: xday
   REAL(KIND=r8)		   :: tod
   REAL(KIND=r8)		   :: yrl
   INTEGER		  :: monl(12)
   INTEGER		  :: monday(12)
   INTEGER		  :: m
   REAL(KIND=r8)   , PARAMETER     :: f3600=3.6e3_r8
   tod=0.0_r8
   yrl=365.25e0_r8
   MONL    =   (/31,28,31,30,31,30,31,31,30,31,30,31/)
   !
   !	 id is now assumed to be the current date and hour
   !
   monday(1)=0
   DO m=2,12
      monday(m)=monday(m-1)+monl(m-1)
   END DO
   xday=hi*f3600
   xday=xday+MOD(tod,f3600)
   xday=monday(mi)+di+xday/86400.0_r8
   xday=xday-MOD(yi+3,4)*0.25_r8
   IF(MOD(yi,4).EQ.0.AND.mi.GT.2)xday=xday+1.0e0_r8
   xday= MOD(xday-1.0_r8,yrl)
 END SUBROUTINE jull

  
END MODULE Options
