SUBROUTINE TSL(KH,KDJ,PMU0,PGELAT,PGELAM,PGEMU)
!****-------------------------------------------------------------------
!****   TSL : CALCUL DU TEMPS SOLAIRE LOCAL MODIFIE
!****   ---
!**** Auteur :   D. Giard 05/94
!****            F. Bouyssel 02/04 : Cosinus de l'angle zenithal local a T-3h
!****-------------------------------------------------------------------

!*** BUT : CALCUL DU TEMPS SOLAIRE LOCAL MODIFIE, ARRONDI A L'HEURE LA PLUS
!*** ---    PROCHE, POUR L'UTILISATION DES POLYNOMES DE F.BOUTTIER DANS
!***        L'ANALYSE DE SURFACE ASSOCIEE A ISBA
!***        CALCUL DE LA DUREE DU JOUR (EN HEURES)

!*** SEQUENCE D'APPEL : CALL TSL(KH,KDJ,PGELAT,PGELAM,PGEMU), DANS CACSTS
!*** ----------------

!*** ARGUMENTS D'ENTREE :  PGELAT, PGELAM, PGEMU: REPERAGE GEOGRAPHIQUE
!*** ------------------

!*** ARGUMENTS DE SORTIE : KH   : TEMPS SOLAIRE LOCAL MODIFIE, EN HEURE
!*** ------------------    KDJ  : DUREE DU JOUR, EN HEURES
!                          PMU0 : COSINUS DE L'ANGLE ZENITHAL LOCAL

!*** COMMONS UTILISES : - YOMCST - CONSTANTES FONDAMENTALES D'ARPEGE
!*** ----------------   - YOMRIP - CONSTANTES LIEES A LA DATE ET L'HEURE

!*** ALGORITHME : - CALCUL DE LA DUREE DU JOUR A LA LATITUDE DU POINT
!*** ----------   - CALCUL DU TEMPS SOLAIRE LOCAL
!***              - MODIFICATION POUR SE RAMENER A UN RAPPORT JOUR/NUIT=1
!***              - ARRONDI A L'HEURE LA PLUS PROCHE
!***-----------------------------------------------------------------

USE PARKIND1  ,ONLY : JPIM     ,JPRB
USE YOMHOOK   ,ONLY : LHOOK,   DR_HOOK

USE YOMCST   , ONLY : RPI      ,RDAY     ,REA      ,REPSM
USE YOMRIP   , ONLY : NSSSSS   ,RTIMST   ,RWSOVR   ,RCODEC   ,RSIDEC
USE YOMDYNCORE, ONLY : LAQUA
USE YOMORB, ONLY : LCORBMD, SHR_ORB_UPD

IMPLICIT NONE

INTEGER(KIND=JPIM),INTENT(INOUT) :: KH 
INTEGER(KIND=JPIM),INTENT(INOUT) :: KDJ 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PMU0 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PGELAT 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PGELAM 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PGEMU 
REAL(KIND=JPRB) :: Z2PI, ZCV, ZDJ, ZDN, ZEPS, ZH, ZJ, ZMJ, ZMN, ZMU0, ZN, ZTG
REAL(KIND=JPRB) :: ZRSTATI, ZRTIMTR, ZRHGMT, ZTETA, ZRDECLI, ZREQTIM
REAL(KIND=JPRB) :: ZRSOVR, ZRWSOVR, ZRCODEC, ZRSIDEC, ZRCOVSR, ZRSIVSR
REAL(KIND=JPRB) :: ZHOOK_HANDLE
REAL(KIND=JPRB) :: ZCALDAY

#include "abor1.intfb.h"

#include "fctast.h"

IF (LHOOK) CALL DR_HOOK('TSL',0,ZHOOK_HANDLE)

Z2PI= 2.0_JPRB*RPI
ZEPS= 1.E-10_JPRB
! latitude et declinaison differentes de +/- pi/2
IF (ABS(PGEMU) < 1.0_JPRB-ZEPS .AND. ABS(RCODEC) > ZEPS) THEN
  ZTG= TAN(PGELAT)*RSIDEC/RCODEC
! latitudes basses ou moyennes (jour et nuit)
  IF (ABS(ZTG) < 1.0_JPRB-ZEPS) THEN
!C duree de la nuit, duree du jour, milieu de la nuit, milieu du jour (radians)
    ZDN= 2.0_JPRB*ACOS(ZTG)
    ZDJ= Z2PI - ZDN
    ZMN= Z2PI - RWSOVR
    ZMJ= ZMN - SIGN(RPI,ZMN-RPI)
!C ecarts par rapport aux milieux de la nuit et du jour (heure reelle, radians)
    ZN= PGELAM -ZMN
    ZN= ZN +MAX(SIGN(Z2PI,-ZN-RPI),0.0_JPRB) -MAX(SIGN(Z2PI,ZN-RPI),0.0_JPRB)
    ZJ= PGELAM -ZMJ
    ZJ= ZJ +MAX(SIGN(Z2PI,-ZJ-RPI),0.0_JPRB) -MAX(SIGN(Z2PI,ZJ-RPI),0.0_JPRB)
!C temps solaire local modifie (radians) : cas de la nuit, du jour
    IF (ABS(ZN) <= 0.5_JPRB*ZDN) THEN
      ZH= ZN*RPI/ZDN + MAX(SIGN(Z2PI,-ZN),0.0_JPRB)
    ELSE
      ZH= RPI + ZJ*RPI/ZDJ
    ENDIF
!C conversion en heures
    ZCV= 12._JPRB/RPI
    KDJ= NINT(ZDJ*ZCV)
    KH= NINT(ZH*ZCV)
    IF (KH == 0) KH= 24
! hautes latitudes : jour polaire
  ELSEIF (ZTG >= 1.0_JPRB-ZEPS) THEN
    KDJ= 24
    KH= 12
! hautes latitudes : nuit polaire
  ELSE
    KDJ= 0
    KH= 0
  ENDIF
! poles ou declinaison egale a +/- pi/2
ELSE
  ZMU0= PGEMU*RSIDEC
  IF (ZMU0 > ZEPS) THEN
    KDJ= 24
    KH= 12
  ELSE
    KDJ= 0
    KH= 0
  ENDIF
ENDIF

IF (KH < 0.OR.KH > 24) CALL ABOR1(' PB TSL : HEURE ERRONEE')
IF (KDJ < 0.OR.KDJ > 24)CALL ABOR1(' PB TSL : DUREE DU JOUR ERRONEE')

ZRSTATI=75600.
ZRTIMTR=RTIMST+ZRSTATI
ZRHGMT=REAL(MOD(NINT(ZRSTATI)+NSSSSS,NINT(RDAY)),JPRB)
ZTETA=RTETA(ZRTIMTR)
IF( LAQUA ) THEN
  ZRDECLI=RDSAQUA(ZTETA)
  ZREQTIM=RETAQUA(ZTETA)
ELSE
  ZRDECLI=RDS(ZTETA)
  ZREQTIM=RET(ZTETA)
ENDIF

IF(LCORBMD) THEN
   CALL SHR_ORB_UPD(ZRSTATI, ZCALDAY, ZRDECLI)
ENDIF

ZRSOVR =ZREQTIM+ZRHGMT
ZRWSOVR=ZRSOVR*2.0_JPRB*RPI/RDAY
ZRCODEC=COS(ZRDECLI)
ZRSIDEC=SIN(ZRDECLI)
ZRCOVSR=COS(ZRWSOVR)
ZRSIVSR=SIN(ZRWSOVR)
PMU0=MAX(ZRSIDEC*PGEMU-ZRCODEC*ZRCOVSR*SQRT(1.0_JPRB-PGEMU**2)*COS(PGELAM)&
 & +ZRCODEC*ZRSIVSR*SQRT(1.0_JPRB-PGEMU**2)*SIN(PGELAM),0.0_JPRB)  

IF (LHOOK) CALL DR_HOOK('TSL',1,ZHOOK_HANDLE)
END SUBROUTINE TSL
