#include "GAD_OPTIONS.h"

CBOP
C     !ROUTINE: GAD_SOM_PREP_CS_CORNER
C     !INTERFACE:
      SUBROUTINE GAD_SOM_PREP_CS_CORNER(
     U           smVol, smTr0, smTr, smCorners,
     I           prep4dirX, overlapOnly, interiorOnly,
     I           N_edge, S_edge, E_edge, W_edge,
     I           iPass, k, myNz, bi, bj, myThid )


C     !DESCRIPTION: \bv
C     *==========================================================*
C     | SUBROUTINE GAD_SOM_PREP_CS_CORNER
C     | o Prepare for Horizontal SOM Advection :
C     |   when using Cubed-Sphere Grid, fill corner-halo regions
C     |   of all Tracer-moments with proper values
C     *==========================================================*
C     \ev
C     !USES:
      IMPLICIT NONE

C     === Global variables ===
#include "SIZE.h"
#include "EEPARAMS.h"
#include "GAD.h"

C     !INPUT/OUTPUT PARAMETERS:
C     === Routine arguments ===
C     smVol      :: grid-cell volume
C     smTr0      :: tracer Zero Order moment
C     smTr       :: tracer 1rst & 2nd Order moments
C     smCorners  :: Temporary storage of Corner-halo-regions values
C                   ( 3rd dim = Number of corners = 4 : SW, SE, NE, NW )
C     prep4dirX  :: True = prepare for X direction advection
C                   otherwise, prepare for Y direction advection.
C  overlapOnly   :: only update the edges of myTile, but not the interior
C  interiorOnly  :: only update the interior of myTile, but not the edges
C [N,S,E,W]_edge :: true if N,S,E,W edge of myTile is an Edge of the cube
C     iPass      :: current passage index in SOM_ADVECT
C     k          :: current level index
C     myNz       :: 3rd dimension of array to exchange
C     bi,bj      :: current tile indices
C     myThid     :: my Thread Id number
      INTEGER myNz
      _RL     smVol(1-OLx:sNx+OLx,1-OLy:sNy+OLy,myNz)
      _RL     smTr0(1-OLx:sNx+OLx,1-OLy:sNy+OLy,myNz)
      _RL     smTr (1-OLx:sNx+OLx,1-OLy:sNy+OLy,myNz,nSx,nSy,nSOM)
      _RL     smCorners(OLx,OLy,4,-1:nSOM)
      LOGICAL prep4dirX, overlapOnly, interiorOnly
      LOGICAL N_edge, S_edge, E_edge, W_edge
      INTEGER iPass, k, bi, bj
      INTEGER myThid
CEOP

C     !LOCAL VARIABLES:
C     === Local variables ===
      INTEGER i,j, jPass, n
      LOGICAL southWestCorner
      LOGICAL southEastCorner
      LOGICAL northEastCorner
      LOGICAL northWestCorner

      southWestCorner = S_edge .AND. W_edge
      southEastCorner = S_edge .AND. E_edge
      northEastCorner = N_edge .AND. E_edge
      northWestCorner = N_edge .AND. W_edge

      IF ( overlapOnly ) THEN
C--   to avoid repeating 2 times the full sequence of FILL_CS_CORNER calls,
C     add a loop on jPass (from iPass to 2) to reproduce the following logic:
C     1 ) overlapOnly & iPass = 1  (face 3 & 6)
C         - fill corners for the other direction
C         - then store the corner values
C     2 ) IF overlapOnly           :: fill corners for the current direction
C         ELSEIF .NOT.interiorOnly :: get the corner values back from storage
C         ENDIF
       DO jPass = iPass,2

        IF ( ( jPass.EQ.2 .AND. prep4dirX ) .OR.
     &       ( jPass.EQ.1 .AND. .NOT.prep4dirX ) ) THEN
C--   Fill corners to prepare for calculations in X
          CALL GAD_SOM_FILL_CS_CORNER( .TRUE.,
     U                                 smVol(1-OLx,1-OLy,k),
     U                                 smTr0(1-OLx,1-OLy,k),
     U                                 smTr(1-OLx,1-OLy,k,bi,bj,1),
     U                                 smTr(1-OLx,1-OLy,k,bi,bj,2),
     U                                 smTr(1-OLx,1-OLy,k,bi,bj,3),
     U                                 smTr(1-OLx,1-OLy,k,bi,bj,4),
     U                                 smTr(1-OLx,1-OLy,k,bi,bj,5),
     U                                 smTr(1-OLx,1-OLy,k,bi,bj,6),
     U                                 smTr(1-OLx,1-OLy,k,bi,bj,7),
     U                                 smTr(1-OLx,1-OLy,k,bi,bj,8),
     U                                 smTr(1-OLx,1-OLy,k,bi,bj,9),
     I                                 bi, bj, myThid )
C--   End of filling for X dir
c       ENDIF

        ELSE
C Note: the 2 IF tests are equivalent to just 1 if/else test;
C       use this later option and leave the former commented.

c       IF ( ( jPass.EQ.1 .AND. prep4dirX ) .OR.
c    &       ( jPass.EQ.2 .AND. .NOT.prep4dirX ) ) THEN
C--   Fill corners to prepare for calculations in Y
          CALL GAD_SOM_FILL_CS_CORNER( .FALSE.,
     U                                 smVol(1-OLx,1-OLy,k),
     U                                 smTr0(1-OLx,1-OLy,k),
     U                                 smTr(1-OLx,1-OLy,k,bi,bj,1),
     U                                 smTr(1-OLx,1-OLy,k,bi,bj,2),
     U                                 smTr(1-OLx,1-OLy,k,bi,bj,3),
     U                                 smTr(1-OLx,1-OLy,k,bi,bj,4),
     U                                 smTr(1-OLx,1-OLy,k,bi,bj,5),
     U                                 smTr(1-OLx,1-OLy,k,bi,bj,6),
     U                                 smTr(1-OLx,1-OLy,k,bi,bj,7),
     U                                 smTr(1-OLx,1-OLy,k,bi,bj,8),
     U                                 smTr(1-OLx,1-OLy,k,bi,bj,9),
     I                                 bi, bj, myThid )
C--   End of filling for Y dir
        ENDIF

        IF ( jPass.EQ.1 ) THEN
C--   Store corner values (to be used on the next iPass)
         IF ( southWestCorner ) THEN
          DO j=1,OLy
           DO i=1,OLx
            smCorners(i,j,1,-1) = smVol(i-OLx,j-OLy,k)
            smCorners(i,j,1, 0) = smTr0(i-OLx,j-OLy,k)
            DO n=1,nSOM
             smCorners(i,j,1,n) = smTr (i-OLx,j-OLy,k,bi,bj,n)
            ENDDO
           ENDDO
          ENDDO
         ENDIF
         IF ( southEastCorner ) THEN
          DO j=1,OLy
           DO i=1,OLx
            smCorners(i,j,2,-1) = smVol(sNx+i,j-OLy,k)
            smCorners(i,j,2, 0) = smTr0(sNx+i,j-OLy,k)
            DO n=1,nSOM
             smCorners(i,j,2,n) = smTr (sNx+i,j-OLy,k,bi,bj,n)
            ENDDO
           ENDDO
          ENDDO
         ENDIF
         IF ( northEastCorner ) THEN
          DO j=1,OLy
           DO i=1,OLx
            smCorners(i,j,3,-1) = smVol(sNx+i,sNy+j,k)
            smCorners(i,j,3, 0) = smTr0(sNx+i,sNy+j,k)
            DO n=1,nSOM
             smCorners(i,j,3,n) = smTr (sNx+i,sNy+j,k,bi,bj,n)
            ENDDO
           ENDDO
          ENDDO
         ENDIF
         IF ( northWestCorner ) THEN
          DO j=1,OLy
           DO i=1,OLx
            smCorners(i,j,4,-1) = smVol(i-OLx,sNy+j,k)
            smCorners(i,j,4, 0) = smTr0(i-OLx,sNy+j,k)
            DO n=1,nSOM
             smCorners(i,j,4,n) = smTr (i-OLx,sNy+j,k,bi,bj,n)
            ENDDO
           ENDDO
          ENDDO
         ENDIF
C--   End storing block
        ENDIF

C--   End of loop on jPass
       ENDDO

      ELSEIF ( .NOT.interiorOnly ) THEN

C--   Get back corner values from storage
        IF ( southWestCorner ) THEN
          DO j=1,OLy
           DO i=1,OLx
            smVol(i-OLx,j-OLy,k )        = smCorners(i,j,1,-1)
            smTr0(i-OLx,j-OLy,k )        = smCorners(i,j,1, 0)
            DO n=1,nSOM
             smTr(i-OLx,j-OLy,k,bi,bj,n) = smCorners(i,j,1, n)
            ENDDO
           ENDDO
          ENDDO
        ENDIF
        IF ( southEastCorner ) THEN
          DO j=1,OLy
           DO i=1,OLx
            smVol(sNx+i,j-OLy,k )        = smCorners(i,j,2,-1)
            smTr0(sNx+i,j-OLy,k )        = smCorners(i,j,2, 0)
            DO n=1,nSOM
             smTr(sNx+i,j-OLy,k,bi,bj,n) = smCorners(i,j,2, n)
            ENDDO
           ENDDO
          ENDDO
        ENDIF
        IF ( northEastCorner ) THEN
          DO j=1,OLy
           DO i=1,OLx
            smVol(sNx+i,sNy+j,k )        = smCorners(i,j,3,-1)
            smTr0(sNx+i,sNy+j,k )        = smCorners(i,j,3, 0)
            DO n=1,nSOM
             smTr(sNx+i,sNy+j,k,bi,bj,n) = smCorners(i,j,3, n)
            ENDDO
           ENDDO
          ENDDO
        ENDIF
        IF ( northWestCorner ) THEN
          DO j=1,OLy
           DO i=1,OLx
            smVol(i-OLx,sNy+j,k )        = smCorners(i,j,4,-1)
            smTr0(i-OLx,sNy+j,k )        = smCorners(i,j,4, 0)
            DO n=1,nSOM
             smTr(i-OLx,sNy+j,k,bi,bj,n) = smCorners(i,j,4, n)
            ENDDO
           ENDDO
          ENDDO
        ENDIF
C--   End getting back corner values from storage

C---  End if/else - overlapOnly - block
      ENDIF

      RETURN
      END
