SUBROUTINE LAITRE_GFL( &
 & KASLB1,KPROMA,KSTART,KPROF,KFLEV,KFLDN,KFLDX,KHVI, &
 & CDINT, &
 & KL0,PDLO,PCLO,PCLOSLD, &
 & PDLAT,PCLA,PCLASLD,PVINTW,PVINTWSLD,PVINTWS, &
 & PVDERW,PHVW, &
 & PXSL,PXSPSL, &
 ! --- OUTPUT --------------------------------------------------------
 & POUT)

! Purpose :
! -------
!   LAITRE_GFL - semi-Lagrangian scheme: origin point interpolations 
!   for GFL variables.

! Interface :
! ---------
!   INPUT:
!     KASLB1     - horizontal dimension of SLBUF1
!     KPROMA     - horizontal dimension
!     KSTART     - first element of arrays where computations are performed
!     KPROF      - depth of work
!     KFLEV      - vertical dimension
!     KFLDN      - number of the first field
!     KFLDX      - number of the last field
!     KHVI       - 1/0: Cubic Hermite vert. interp. are needed/not needed
!     CDINT      - kind of interpolation used
!     KL0        - indices of the four western points of the 16 point
!                  interpolation grid
!     PDLO       - distances for horizontal linear interpolations
!                  in longitude (latitude rows 0, 1, 2, 3)
!     PCLO       - weights for horizontal cubic interpolations in longitude
!                  (latitude rows 1, 2)
!     PCLOSLD    - weights for horizontal cubic interpolations in longitude,
!                  SLHD case (latitude rows 1, 2)
!     PDLAT      - distance for horizontal linear interpolations in latitude
!     PCLA       - weights for horizontal cubic interpolations in latitude
!     PCLASLD    - weights for horizontal cubic interpolations in latitude,
!                  SLHD case
!     PVINTW     - weights for cubic vertical interpolation
!     PVINTWSLD  - weights for cubic vertical interpolation, SLHD case
!     PVINTWS    - vertical spline interpolation weights
!     PVDERW     - weights to compute vertical derivatives necessary for
!                  Hermite cubic vertical interpolation
!     PHVW       - Hermite vertical cubic interpolation weights
!     PXSL       - quantity to interpolate at O in U-wind eqn
!     PXSPSL     - spline representation of above
!   OUTPUT:
!     POUT       - interpolated quantity at O

! Externals :
! ---------
!   ABOR1
!   LAIHVT
!   LAITVSPCQM
!   LAITRI

! Method :
! ------
!   See documentation.

! Reference :
! ---------

! Author :
! ------
!   ??-Nov-2004, F. Vana (CHMI) and K. YESSAD (Meteo-France)

! Modifications :
! -------------
!   30-06-2008 J. Masek   Dataflow for new SLHD interpolators.
!   17-Sep-2008 F. Vana   Weights driven interp. for LAITVSPCQM and LAIHVT(..) 
!   K. Yessad Nov 2008: rationalisation of dummy argument interfaces
!   K. Yessad Nov 2008: interpolation routines: merge QM with not-QM version.
! End Modifications
!   -----------------------------------------------------------------------

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

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

IMPLICIT NONE

INTEGER(KIND=JPIM),INTENT(IN)    :: KASLB1 
INTEGER(KIND=JPIM),INTENT(IN)    :: KPROMA 
INTEGER(KIND=JPIM),INTENT(IN)    :: KSTART 
INTEGER(KIND=JPIM),INTENT(IN)    :: KPROF 
INTEGER(KIND=JPIM),INTENT(IN)    :: KFLEV 
INTEGER(KIND=JPIM),INTENT(IN)    :: KFLDN 
INTEGER(KIND=JPIM),INTENT(IN)    :: KFLDX 
INTEGER(KIND=JPIM),INTENT(IN)    :: KHVI 
CHARACTER(LEN=12) ,INTENT(IN)    :: CDINT
INTEGER(KIND=JPIM),INTENT(IN)    :: KL0(KPROMA,KFLEV,0:3)
REAL(KIND=JPRB)   ,INTENT(IN)    :: PDLO(KPROMA,KFLEV,0:3)
REAL(KIND=JPRB)   ,INTENT(IN)    :: PCLO(KPROMA,KFLEV,3,2)
REAL(KIND=JPRB)   ,INTENT(IN)    :: PCLOSLD(KPROMA,KFLEV,3,2)
REAL(KIND=JPRB)   ,INTENT(IN)    :: PDLAT(KPROMA,KFLEV) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PCLA(KPROMA,KFLEV,3) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PCLASLD(KPROMA,KFLEV,3) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PVINTW(KPROMA,KFLEV,3)
REAL(KIND=JPRB)   ,INTENT(IN)    :: PVINTWSLD(KPROMA,KFLEV,3)
REAL(KIND=JPRB)   ,INTENT(IN)    :: PVINTWS(KPROMA,KFLEV,1:4) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PVDERW(KPROMA,KFLEV,2*KHVI,2*KHVI) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PHVW(KPROMA,KFLEV,4*KHVI) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PXSL(KASLB1,KFLDN:KFLDX) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PXSPSL(KASLB1,KFLDN:KFLDX) 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: POUT(KPROMA,KFLEV) 

REAL(KIND=JPRB) :: ZHOOK_HANDLE

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

#include "abor1.intfb.h"
#include "laihvt.intfb.h"
#include "laitvspcqm.intfb.h"
#include "laitri.intfb.h"

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

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

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

! 1. Origin point interpolations for GFL variables
!    ---------------------------------------------

! 1.1 SLHD interpolations
!     -------------------
! NOTE:
!   The SLHD versions of the LAIHVT and
!   LAITVSPCQM interpolations are currently not coded.

IF (CDINT == 'LAITQM(SLD) ') THEN

  ! Lagrange cubic polynomial with SLHD, quasi-monotonic
  CALL LAITRI(KASLB1,KPROMA,KSTART,KPROF,KFLEV,KFLDN,KFLDX,2, &
   & PDLAT,PCLASLD,PDLO,PCLOSLD,KL0(1,1,0),PVINTWSLD, &
   & PXSL,POUT)

ELSEIF (CDINT == 'LAITQMH(SLD)') THEN

  ! Lagrange cubic polynomial with SLHD, quasi-monotonic in horizontal
  CALL LAITRI(KASLB1,KPROMA,KSTART,KPROF,KFLEV,KFLDN,KFLDX,1, &
   & PDLAT,PCLASLD,PDLO,PCLOSLD,KL0(1,1,0),PVINTWSLD, &
   & PXSL,POUT)

ELSEIF (CDINT == 'LAITRI(SLD) ') THEN

  ! Lagrange cubic polynomial with SLHD
  CALL LAITRI(KASLB1,KPROMA,KSTART,KPROF,KFLEV,KFLDN,KFLDX,0, &
   & PDLAT,PCLASLD,PDLO,PCLOSLD,KL0(1,1,0),PVINTWSLD, &
   & PXSL,POUT)

! 1.2 non-SLHD interpolations
!     -----------------------

ELSEIF (CDINT == 'LAIHVTQM    ') THEN 

  ! Hermite cubic polynomial on the vertical "HVT", quasi-monotonic
  CALL LAIHVT(KASLB1,KPROMA,KSTART,KPROF,KFLEV,KFLDN,KFLDX,2, &
   & PDLAT,PCLA,PDLO,PCLO,KL0(1,1,0),PVDERW,PHVW, &
   & PXSL,POUT)

ELSEIF (CDINT == 'LAIHVTQMH   ') THEN

  ! Hermite cubic polynomial on the vertical "HVT", quasi-monotonic 
  ! in horizontal
  CALL LAIHVT(KASLB1,KPROMA,KSTART,KPROF,KFLEV,KFLDN,KFLDX,1, &
   & PDLAT,PCLA,PDLO,PCLO,KL0(1,1,0),PVDERW,PHVW, &
   & PXSL,POUT)

ELSEIF (CDINT == 'LAIHVT      ') THEN

  ! Hermite cubic polynomial on the vertical "HVT"
  CALL LAIHVT(KASLB1,KPROMA,KSTART,KPROF,KFLEV,KFLDN,KFLDX,0, &
   & PDLAT,PCLA,PDLO,PCLO,KL0(1,1,0),PVDERW,PHVW, &
   & PXSL,POUT)

ELSEIF (CDINT == 'LAITVSPCQM  ') THEN

  ! spline "VSPC", quasi-monotonic
  CALL LAITVSPCQM(KASLB1,KPROMA,KSTART,KPROF,KFLEV,KFLDN,KFLDX, &
   & PDLAT,PCLA,PDLO,PCLO,KL0(1,1,0),PVINTWS,&
   & PXSPSL,POUT,&
   & PXSL)

ELSEIF (CDINT == 'LAITQM      ') THEN

  ! Lagrange cubic polynomial, quasi-monotonic
  CALL LAITRI(KASLB1,KPROMA,KSTART,KPROF,KFLEV,KFLDN,KFLDX,2, &
   & PDLAT,PCLA,PDLO,PCLO,KL0(1,1,0),PVINTW, &
   & PXSL,POUT)

ELSEIF (CDINT == 'LAITQMH     ') THEN

  ! Lagrange cubic polynomial, quasi-monotonic in horizontal
  CALL LAITRI(KASLB1,KPROMA,KSTART,KPROF,KFLEV,KFLDN,KFLDX,1, &
   & PDLAT,PCLA,PDLO,PCLO,KL0(1,1,0),PVINTW, &
   & PXSL,POUT)

ELSEIF (CDINT == 'LAITRI      ') THEN

  ! Lagrange cubic polynomial
  CALL LAITRI(KASLB1,KPROMA,KSTART,KPROF,KFLEV,KFLDN,KFLDX,0, &
   & PDLAT,PCLA,PDLO,PCLO,KL0(1,1,0),PVINTW, &
   & PXSL,POUT)

ELSE
  CALL ABOR1('LAITRE_GFL: UNKNOWN INTERPOLATION TYPE: ' // CDINT)
ENDIF

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

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