SUBROUTINE PRE_CALC (PVIEANG, PSOLANG,     &
&                     PRP, PGP, PRM_AUX, PGB, PRMU, PGA, PPL, PPSL_AUX)

!****PRE_CALC*** PRELIMINARY CALCULATIONS FOR GAUSS INTEGRATIONS 


!     INTERFACE
!     ---------
! PRE_CALC IS CALLED BY RT6S_GEMS ONLY ONCE. THE RESULTS ARE 
! INDEPENDANT OF KLON

!     INPUTS
!     ------


!     OUTPUTS
!     -------
! PSOLANG(KLON)                   : SOLAR ZENITH ANGLE
! PVIEANG(KLON)                   : VIEWING ZENITH ANGLE
! PRP(KNP)                        : GAUSSIAN ANGLES FOR AZIMUTH [rad]
! PGP(KNP)                        : GUASSIAN WEIGHTS FOR AZIMUTH
! PRMU(KMU)                       : GAUSSIAN ANGLES FOR TRUNCATION OF PHASE FUNCTION [in cosine]
! PGA(KMU)                        : GAUSSIAN WEIGHTS FOR TRUNCATION OF PHASE FUNCTION
! PRM_AUX(KLON,-KMU:KMU)                   : GAUSSIAN ANGLES FOR THE ZENITH [in cosine]
! PGB(-KMU:KMU)                   : GAUSSIAN WEIGHTS FOR THE ZENITH
! PPL(KNBMU,-1:KNANG+1)           : USED IN TRUNCATION OF PHASE FUNCTION
! PPSL_AUX(KLON,0:KNANG,-1:KNANG,-KMU:KMU) :

!     EXTERNALS.
!     ----------
!          GAUSS, KERNEL_PPSL

!     MODIFICATIONS.
!     -------------
!          N.HUNEEUS 02.05.2007
!          A.BENEDETTI - ECMWF 06.08.2008

!     SOURCE
!     ------
! ADAPTED FROM ORIGINAL 6S CODE, SEE VERMOTE ET AL. (1997)

!     MODEL PARAMETERS
!     ----------------
!--------------------------------------------------------------------------------------

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

USE RT6SVALUES

IMPLICIT NONE

REAL(KIND=JPRB),INTENT(IN)  :: PSOLANG(KLON), PVIEANG(KLON)
REAL(KIND=JPRB),INTENT(OUT) :: PRP(KNP), PGP(KNP)
REAL(KIND=JPRB),INTENT(OUT) :: PRMU(KNBMU), PGA(KNBMU)
REAL(KIND=JPRB),INTENT(OUT) :: PRM_AUX(KLON,-KMU:KMU),PGB(-KMU:KMU)
REAL(KIND=JPRB),INTENT(OUT) :: PPL(KNBMU,-1:KNANG+1)
REAL(KIND=JPRB),INTENT(OUT) :: PPSL_AUX(KLON,0:KNANG,-1:KNANG,-KMU:KMU)

! LOCAL VARIABLES
! ---------------

INTEGER(KIND=JPIM) :: IK, IMU, J, J1, J2, JLON
REAL(KIND=JPRB) :: ZPI2,ZXMUV,ZXMUS
REAL(KIND=JPRB) :: ZANGLEM(KMU2), ZWEIGHTM(KMU2)
REAL(KIND=JPRB) :: ZCOSANG(KNANG),ZWEIGHT(KNANG)

REAL(KIND=JPRB) :: ZHOOK_HANDLE


#include "gauss_gems.intfb.h"
#include "kernel_ppsl.intfb.h"


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

PRM_AUX(:,:)=0.0_JPRB
ZPI2=2.0_JPRB*ZPI
! GAUSSIAN ANGLES AND WEIGHTS FOR ZENITH
 CALL GAUSS_GEMS(0.0_JPRB,ZPI2,KNP,PRP,PGP)

! GAUSSIAN ANGLES AND WEIGHTS FOR AZIMUTH
 CALL GAUSS_GEMS(-1.0_JPRB,1.0_JPRB,KMU2,ZANGLEM,ZWEIGHTM)

IMU=KMU-1
DO J=-IMU,-1
  IK=KMU+J
  PRM_AUX(:,-J-KMU)=ZANGLEM(IK)
  PGB(-J-KMU)=ZWEIGHTM(IK)
ENDDO

DO J=1,IMU
  IK=IMU+J
  PRM_AUX(:,KMU-J)=ZANGLEM(IK)
  PGB(KMU-J)=ZWEIGHTM(IK)
ENDDO

PGB(-KMU)=0.0_JPRB
PGB(0)=0.0_JPRB
PGB(KMU)=0.0_JPRB
DO JLON=1,KLON
  ZXMUS=cos(PSOLANG(JLON)*zpi/180.0_JPRB)
  ZXMUV=cos(PVIEANG(JLON)*zpi/180.0_JPRB)
  PRM_AUX(JLON,-KMU)=-ZXMUV
  PRM_AUX(JLON,KMU)=ZXMUV
  PRM_AUX(JLON,0)=-ZXMUS
ENDDO

!*******************************************************
! GAUSS VALUES FOR THE TRUNCATION OF THE PHASE FUNCTION
!*******************************************************

 CALL GAUSS_GEMS(-1._JPRB,1._JPRB,KNANG,ZCOSANG,ZWEIGHT)

DO J=1,KNANG/2
  PRMU(J+1)=ZCOSANG(J)
  PGA(J+1)=ZWEIGHT(J)
ENDDO
PRMU(1)=-1.0_JPRB
PGA(1)=0.0_JPRB
PRMU(KNANG/2+2)=0.0_JPRB
PGA(KNANG/2+2)=0.0_JPRB
DO J=1+KNANG/2,KNANG
  PRMU(J+2)=ZCOSANG(J)
  PGA(J+2)=ZWEIGHT(J)
ENDDO
PRMU(KNBMU)=1.0_JPRB
PGA(KNBMU)=0.0_JPRB

! OTHER CALCULATIONS FOR TRUNCATION
PPL(:,:)=0.0_JPRB
DO J1=1,KNBMU
  PPL(J1,-1)=0.0_JPRB
  PPL(J1,0)=1.0_JPRB
  DO J2=0,KNANG
    PPL(J1,J2+1)=((2.0_JPRB*DBLE(J2)+1.0_JPRB)*PRMU(J1)*PPL(J1,J2)-DBLE(J2)*PPL(J1,J2-1))/(DBLE(J2)+1.0_JPRB)
  ENDDO
ENDDO  


!*******************************************************
! KERNEL CALCULATIONS
!*******************************************************

 CALL KERNEL_PPSL(PRM_AUX,PPSL_AUX)

IF (LHOOK) CALL DR_HOOK('PRE_CALC',1,ZHOOK_HANDLE)

END SUBROUTINE PRE_CALC
