SUBROUTINE PRESPFPOS(CDCONF,LDVPP,LDHFP,LDRESP)

!**** *PRESPFPOS*  - Prepare before dynamic post-processing

!     Purpose.
!     --------
!        To save and possibly pack the data before post-processing
!         If in-line vertical post-processing (=> packing) : 
!         - pack spectral arrays
!         - save and pack gridpoint upperair fields
!         - save gridpoint surface fields and pack Ts
!         After post-processing : 
!         - reset gridpoint orography
!         - recover gridpoint upperair fields
!         - recover gridpoint surface fields (for Ts)
!         Remark : saving and recovering the whole surface field buffer
!         just to handle with Ts is a heavy but easy way to do things ... 

!**   Interface.
!     ----------
!        *CALL* *PRESPFPOS(CDCONF,LDVPP,LDHFP)

!        Explicit arguments :
!        --------------------
!           CDCONF : configuration of inverse legendre transforms
!           LDVPP  : .TRUE. if vertical   post-processing expected
!           LDHFP  : .TRUE. if horizontal post-processing expected
!           LDRESP : .TRUE. if model data should be read

!        Implicit arguments :
!        --------------------
!        None

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

!     Externals.    
!     ----------    
!        WRSPEC   - write out spectral arrays
!        RDSPEC   - read in spectral arrays
!        SPACONVERT - convert model fields spectral array into file fields
!                     spectral arrays and reverse
!        PKSURFA  - pack gridpoint arrays/workfile - Arpege
!        PKSPECA  - pack spectral arrays/workfile - Arpege
!        Called by STEPO

!     Reference.
!     ----------
!        ECMWF Research Department documentation of the IFS

!     Author.
!     -------
!        R. El Khatib  *METEO-FRANCE*

!     Modifications.
!     --------------
!        Original : 98-01-28 from STEPO
!     R. El Khatib : 01-03-16 Control with NGRSP for aladin
!     R. El Khatib 02-03-19 lagged Fourier diffusion before packing
!     R. El Khatib : 01-08-07 Pruning options
!     M.Hamrud      01-Oct-2003 CY28 Cleaning
!     K.Yessad (Dec 2003): cleaning in horizontal diffusion.
!     R. El Khatib : 04-12-08 remove broken backup of upper-air gp fields
!     R. El Khatib  25-Apr-2005 SPA* not saved if 1st part 927 (Only 1 scan)
!        M.Hamrud      01-Jul-2006  Revised surface fields
!     ------------------------------------------------------------------

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

USE YOMCT0   , ONLY : LFPART2  ,NCONF    ,LARPEGEF ,LFPOS    ,NSTOP
USE YOMSP    , ONLY : SPA2     ,SPA3
USE YOMDIM   , ONLY : NSPEC2   ,NFLEVL   ,NS2D     ,NS3D
USE SURFACE_FIELDS_MIX  , ONLY : SURF_STORE, SURF_RESTORE, YSP_RRD  ,SP_RR
USE YOMFPC   , ONLY : NFPINCR
USE YOMFPCT0 , ONLY : NFPCT0

IMPLICIT NONE
CHARACTER(LEN=1)  ,INTENT(IN)    :: CDCONF 
LOGICAL           ,INTENT(IN)    :: LDVPP 
LOGICAL           ,INTENT(IN)    :: LDHFP 
LOGICAL           ,INTENT(INOUT) :: LDRESP 

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

LOGICAL,SAVE  :: LLFSCAN=.TRUE. ! LLFSCAN: .TRUE. if first scan of post-proc.

REAL(KIND=JPRB) :: ZSPEC(NSPEC2,NFLEVL*NS3D+NS2D)

INTEGER(KIND=JPIM) :: IFLD, JF, JLEV, JS
REAL(KIND=JPRB) :: ZHOOK_HANDLE

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

#include "pksurfa.intfb.h"
#include "pkspeca.intfb.h"
#include "rdspec.intfb.h"
#include "spaconvert.intfb.h"
#include "sualspa.intfb.h"
#include "wrspec.intfb.h"

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

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

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

!*       1.    VARIOUS INITIALIZATION
!              ----------------------
CALL GSTATS(1776,0)

IF (NCONF/100 == 1) THEN
  LDRESP=.FALSE.
ENDIF
IF (LFPART2.OR.(NFPINCR /= 0)) THEN
  LDRESP=.FALSE.
  LLFSCAN=.TRUE.
ENDIF

!*       2.    PREPARE FOR POST-PROCESSING
!              ---------------------------

IF (LFPOS.OR.LDVPP) THEN
!       Read model spectral arrays ?  
  IF (CDCONF == 'A'.AND.LDRESP) THEN
    CALL RDSPEC(LFPOS)
    IF (NSTOP > 0.AND.(.NOT.LFPART2).AND.LARPEGEF) THEN
      IF (YSP_RRD%NUMFLDS > 0) THEN
        CALL SURF_RESTORE
      ENDIF
    ENDIF
  ENDIF
  IF (CDCONF /= '0'.AND.LDVPP) THEN
!         Save model spectral arrays
    IF(LLFSCAN .AND. NFPCT0 >= 0) THEN
      CALL WRSPEC
      LDRESP=.TRUE.
    ENDIF
    IF (NSTOP > 0.AND.(.NOT.LFPART2).AND.LARPEGEF) THEN  
!           Set fields to be packed
      CALL SPACONVERT(.TRUE.)
!           Packing
      IFLD=0
      DO JF=1,NS3D
        DO JLEV=1,NFLEVL
          IFLD=IFLD+1
          DO JS=1,NSPEC2
            ZSPEC(JS,IFLD)=SPA3(JLEV,JS,JF)
          ENDDO
        ENDDO
      ENDDO
      DO JF=1,NS2D
        IFLD=IFLD+1
        DO JS=1,NSPEC2
          ZSPEC(JS,IFLD)=SPA2(JS,JF)
        ENDDO
      ENDDO
      IF (LARPEGEF) THEN
        CALL PKSPECA(ZSPEC,IFLD)
      ENDIF
      IFLD=0
      DO JF=1,NS3D
        DO JLEV=1,NFLEVL
          IFLD=IFLD+1
          DO JS=1,NSPEC2
            SPA3(JLEV,JS,JF)=ZSPEC(JS,IFLD)
          ENDDO
        ENDDO
      ENDDO
!           Here below : orography is packed as the others. This is not safe, 
!           but it is correct since orography is not used in spectral space
!           in the post-processing and SUOROG is not called.
      DO JF=1,NS2D
        IFLD=IFLD+1
        DO JS=1,NSPEC2
          SPA2(JS,JF)=ZSPEC(JS,IFLD)
        ENDDO
      ENDDO
!           Reset model fields
      CALL SPACONVERT(.FALSE.)
      IF (YSP_RRD%NUMFLDS > 0) THEN
        CALL SURF_STORE
        IF (LARPEGEF) THEN
          CALL PKSURFA(KN=YSP_RRD%NUMFLDS,P2=SP_RR)
        ENDIF
      ENDIF
    ENDIF
!         Reset LLFSCAN for next call
    LLFSCAN=.FALSE.
  ELSEIF (CDCONF == '0'.AND..NOT.LDHFP) THEN
!         Lagged vertical pp =>Reset LLFSCAN/LDRESP for next call
    LDRESP=.TRUE.
    LLFSCAN=.TRUE.
  ELSEIF (.NOT.LDHFP) THEN
!         Reset LLFSCAN/LDRESP for next call
    LDRESP=.FALSE.
    LLFSCAN=.TRUE.
  ENDIF
ELSEIF (CDCONF == 'A'.AND.LDRESP) THEN
  IF(.NOT.ALLOCATED(SPA3)) CALL SUALSPA
  CALL RDSPEC(LFPOS)
  LDRESP=.FALSE.
  LLFSCAN=.TRUE.
ENDIF
CALL GSTATS(1776,1)

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

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