#include "OBCS_OPTIONS.h"

C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
CBOP
C     !ROUTINE: OBCS_INIT_FIXED

C     !INTERFACE:
      SUBROUTINE OBCS_INIT_FIXED( myThid )

C     !DESCRIPTION:
C     *==========================================================*
C     | SUBROUTINE OBCS_INIT_FIXED
C     | o Initialise OBCs fixed arrays
C     *==========================================================*

C     !USES:
      IMPLICIT NONE

C     === Global variables ===
#include "SIZE.h"
#include "EEPARAMS.h"
#include "PARAMS.h"
#include "GRID.h"
#include "OBCS_PARAMS.h"
#include "OBCS_GRID.h"

C     !INPUT/OUTPUT PARAMETERS:
C     myThid   :: my Thread Id. number
      INTEGER myThid
CEOP

#ifdef ALLOW_OBCS
C     !LOCAL VARIABLES:
C     msgBuf   :: Informational/error message buffer
C     OB_ApplX :: number of grid points (in X dir) overwritten by obcs_apply
C     OB_ApplY :: number of grid points (in Y dir) overwritten by obcs_apply
C     bi,bj    :: tile indices
C     i, j     :: Loop counters
      CHARACTER*(MAX_LEN_MBUF) msgBuf, errMsg
      INTEGER OB_ApplX
      INTEGER OB_ApplY
      INTEGER bi, bj
      INTEGER  i, j
      INTEGER im, jm
      INTEGER iB, jB
      LOGICAL flag
      INTEGER ioUnit

#ifdef ALLOW_DEBUG
      IF (debugMode) CALL DEBUG_ENTER('OBCS_INIT_FIXED',myThid)
#endif

C==   Set Interior mask at Cell Center:

      DO bj = myByLo(myThid), myByHi(myThid)
       DO bi = myBxLo(myThid), myBxHi(myThid)
        DO j=1-OLy,sNy+OLy
         DO i=1-OLx,sNx+OLx
           OBCS_insideMask(i,j,bi,bj) = 1.
         ENDDO
        ENDDO
       ENDDO
      ENDDO

      IF ( insideOBmaskFile.EQ.' ' ) THEN
C--   If no maskFile is provided, set Interior mask from OB list of indices

       DO bj = myByLo(myThid), myByHi(myThid)
        DO bi = myBxLo(myThid), myBxHi(myThid)
         DO j=1,sNy
C-    Eastern boundary
          IF ( OB_Ie(j,bi,bj).NE.OB_indexNone ) THEN
           flag = .TRUE.
           DO i=OB_Ie(j,bi,bj),sNx
             flag = flag .AND.
     &              kSurfC(i,j,bi,bj).LE.Nr .AND. i.NE.OB_Iw(j,bi,bj)
             IF ( flag ) OBCS_insideMask(i,j,bi,bj) = 0.
           ENDDO
          ENDIF
C-    Western boundary
          IF ( OB_Iw(j,bi,bj).NE.OB_indexNone ) THEN
           flag = .TRUE.
           DO i=OB_Iw(j,bi,bj),1,-1
             flag = flag .AND.
     &              kSurfC(i,j,bi,bj).LE.Nr .AND. i.NE.OB_Ie(j,bi,bj)
             IF ( flag ) OBCS_insideMask(i,j,bi,bj) = 0.
           ENDDO
          ENDIF
         ENDDO
         DO i=1,sNx
C-    Northern boundary
          IF ( OB_Jn(i,bi,bj).NE.OB_indexNone ) THEN
           flag = .TRUE.
           DO j=OB_Jn(i,bi,bj),sNy
             flag = flag .AND.
     &              kSurfC(i,j,bi,bj).LE.Nr .AND. j.NE.OB_Js(i,bi,bj)
             IF ( flag ) OBCS_insideMask(i,j,bi,bj) = 0.
           ENDDO
          ENDIF
C-    Southern boundary
          IF ( OB_Js(i,bi,bj).NE.OB_indexNone ) THEN
           flag = .TRUE.
           DO j=OB_Js(i,bi,bj),1,-1
             flag = flag .AND.
     &              kSurfC(i,j,bi,bj).LE.Nr .AND. j.NE.OB_Jn(i,bi,bj)
             IF ( flag ) OBCS_insideMask(i,j,bi,bj) = 0.
           ENDDO
          ENDIF
         ENDDO

C--   end bi,bj loops
        ENDDO
       ENDDO

      ELSE
C--   Read in Interior mask from file :

       CALL READ_FLD_XY_RS( insideOBmaskFile, ' ', OBCS_insideMask,
     &                      0, myThid )

       DO bj = myByLo(myThid), myByHi(myThid)
        DO bi = myBxLo(myThid), myBxHi(myThid)
         DO j=1,sNy
          DO i=1,sNx
           IF ( OBCS_insideMask(i,j,bi,bj).NE.0. )
     &          OBCS_insideMask(i,j,bi,bj) = 1.
          ENDDO
         ENDDO
        ENDDO
       ENDDO

C--   end computing/reading Interior mask
      ENDIF

C--   Fill in the overlap:
      _EXCH_XY_RS( OBCS_insideMask, myThid )

C==   Set interior mask at U & V location (grid-cell Wester & Southern edges)
C     leave OB edges inside (maskIn=1) (e.g., Eastern OB: maskInW(OB_Ie)=1 )
C     so that velocity normal-component at OB is still in Interior region.
      DO bj = myByLo(myThid), myByHi(myThid)
       DO bi = myBxLo(myThid), myBxHi(myThid)
         DO j=2-OLy,sNy+OLy
          DO i=2-OLx,sNx+OLx
            maskInW(i,j,bi,bj) = maskInW(i,j,bi,bj)
     &                     *MAX( OBCS_insideMask(i-1,j,bi,bj),
     &                           OBCS_insideMask(i,j,bi,bj) )
            maskInS(i,j,bi,bj) = maskInS(i,j,bi,bj)
     &                     *MAX( OBCS_insideMask(i,j-1,bi,bj),
     &                           OBCS_insideMask(i,j,bi,bj) )
          ENDDO
         ENDDO
       ENDDO
      ENDDO

C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|

C--   After exchange, set tiled index arrays OB_Jn/Js/Ie/Iw in overlap region
C     issue a warning if not consistent (similar to OBCS_CHECK but for overlap)

c     IF ( .TRUE. ) THEN
      IF ( OBCS_indexStatus .LT. 2 ) THEN
       ioUnit = standardMessageUnit
       WRITE(msgBuf,'(2A)')
     &      'OBCS_INIT_FIXED: Setting OB indices in Overlap'
       CALL PRINT_MESSAGE( msgBuf, ioUnit, SQUEEZE_RIGHT, myThid )
       WRITE(errMsg,'(2A)') 'S/R OBCS_INIT_FIXED: ',
     &              'Inside Mask and OB locations disagree :'
       flag = .TRUE.
       DO bj = myByLo(myThid), myByHi(myThid)
        DO bi = myBxLo(myThid), myBxHi(myThid)

C-    Eastern boundary
         DO j=1-OLy,sNy+OLy
          DO i=1,sNx+1
           IF ( OBCS_insideMask(i,j,bi,bj).LT.
     &          OBCS_insideMask(i-1,j,bi,bj)
     &          .AND. ( j.LT.1 .OR. j.GT.sNy )
     &          .AND. kSurfW(i,j,bi,bj).LE.Nr ) THEN
            IF ( OB_Ie(j,bi,bj).EQ.OB_indexNone ) THEN
              OB_Ie(j,bi,bj) = i
              WRITE(msgBuf,'(A,I5,2(A,I3),2(A,I5))')
     &        ' Sets OBE(j,bi,bj=',j,',',bi,',',bj,')=', OB_Ie(j,bi,bj)
              CALL PRINT_MESSAGE( msgBuf,ioUnit,SQUEEZE_RIGHT,myThid )
            ELSEIF ( OB_Ie(j,bi,bj).NE.i ) THEN
              IF ( flag ) CALL PRINT_ERROR( errMsg, myThid )
              flag = .FALSE.
              WRITE(msgBuf,'(A,I5,2(A,I3),2(A,I5))')
     &        ' OBE(j,bi,bj=',j,',',bi,',',bj,')=', OB_Ie(j,bi,bj),
     &        ' but from insideMask expects I=', i
              CALL PRINT_ERROR( msgBuf, myThid )
            ENDIF
           ENDIF
          ENDDO
         ENDDO
C-    Western boundary
         DO j=1-OLy,sNy+OLy
          DO i=0,sNx
           IF ( OBCS_insideMask(i,j,bi,bj).LT.
     &          OBCS_insideMask(i+1,j,bi,bj)
     &          .AND. ( j.LT.1 .OR. j.GT.sNy )
     &          .AND. kSurfW(i+1,j,bi,bj).LE.Nr ) THEN
            IF ( OB_Iw(j,bi,bj).EQ.OB_indexNone ) THEN
              OB_Iw(j,bi,bj) = i
              WRITE(msgBuf,'(A,I5,2(A,I3),2(A,I5))')
     &        ' Sets OBW(j,bi,bj=',j,',',bi,',',bj,')=', OB_Iw(j,bi,bj)
              CALL PRINT_MESSAGE( msgBuf,ioUnit,SQUEEZE_RIGHT,myThid )
            ELSEIF ( OB_Iw(j,bi,bj).NE.i ) THEN
              IF ( flag ) CALL PRINT_ERROR( errMsg, myThid )
              flag = .FALSE.
              WRITE(msgBuf,'(A,I5,2(A,I3),2(A,I5))')
     &        ' OBW(j,bi,bj=',j,',',bi,',',bj,')=', OB_Iw(j,bi,bj),
     &        ' but from insideMask expects I=', i
              CALL PRINT_ERROR( msgBuf, myThid )
            ENDIF
           ENDIF
          ENDDO
         ENDDO
C-    Northern boundary
         DO j=1,sNy+1
          DO i=1-OLx,sNx+OLx
           IF ( OBCS_insideMask(i,j,bi,bj).LT.
     &          OBCS_insideMask(i,j-1,bi,bj)
     &          .AND. ( i.LT.1 .OR. i.GT.sNx )
     &          .AND. kSurfS(i,j,bi,bj).LE.Nr ) THEN
            IF ( OB_Jn(i,bi,bj).EQ.OB_indexNone ) THEN
              OB_Jn(i,bi,bj) = j
              WRITE(msgBuf,'(A,I5,2(A,I3),2(A,I5))')
     &        ' Sets OBN(i,bi,bj=',i,',',bi,',',bj,')=', OB_Jn(i,bi,bj)
              CALL PRINT_MESSAGE( msgBuf,ioUnit,SQUEEZE_RIGHT,myThid )
            ELSEIF ( OB_Jn(i,bi,bj).NE.j ) THEN
              IF ( flag ) CALL PRINT_ERROR( errMsg, myThid )
              flag = .FALSE.
              WRITE(msgBuf,'(A,I5,2(A,I3),2(A,I5))')
     &        ' OBN(i,bi,bj=',i,',',bi,',',bj,')=', OB_Jn(i,bi,bj),
     &        ' but from insideMask expects J=', j
              CALL PRINT_ERROR( msgBuf, myThid )
            ENDIF
           ENDIF
          ENDDO
         ENDDO
C-    Southern boundary
         DO j=0,sNy
          DO i=1-OLx,sNx+OLx
           IF ( OBCS_insideMask(i,j,bi,bj).LT.
     &          OBCS_insideMask(i,j+1,bi,bj)
     &          .AND. ( i.LT.1 .OR. i.GT.sNx )
     &          .AND. kSurfS(i,j+1,bi,bj).LE.Nr ) THEN
            IF ( OB_Js(i,bi,bj).EQ.OB_indexNone ) THEN
              OB_Js(i,bi,bj) = j
              WRITE(msgBuf,'(A,I5,2(A,I3),2(A,I5))')
     &        ' Sets OBS(i,bi,bj=',i,',',bi,',',bj,')=', OB_Js(i,bi,bj)
              CALL PRINT_MESSAGE( msgBuf,ioUnit,SQUEEZE_RIGHT,myThid )
            ELSEIF ( OB_Js(i,bi,bj).NE.j ) THEN
              IF ( flag ) CALL PRINT_ERROR( errMsg, myThid )
              flag = .FALSE.
              WRITE(msgBuf,'(A,I5,2(A,I3),2(A,I5))')
     &        ' OBS(i,bi,bj=',i,',',bi,',',bj,')=', OB_Js(i,bi,bj),
     &        ' but from insideMask expects J=', j
              CALL PRINT_ERROR( msgBuf, myThid )
            ENDIF
           ENDIF
          ENDDO
         ENDDO

        ENDDO
       ENDDO
       WRITE(msgBuf,'(2A)')
     &      'OBCS_INIT_FIXED: Setting OB indices in Overlap <= done'
       CALL PRINT_MESSAGE( msgBuf, ioUnit, SQUEEZE_RIGHT, myThid )
      ENDIF

C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|

C==   After EXCH: reset Interior mask to zero beyond OB: this is necessary
C     when EXCH are not disabled (e.g. with EXCH1) between tile Edges
C     that are closed by OB.
C     Do it over OLx,OLy grid points beyond OB, in agreement with OBCS code
C     (apply_tracer) which overwrites tracer over the same width.
      OB_ApplX = OLx
      OB_ApplY = OLy

      DO bj = myByLo(myThid), myByHi(myThid)
       DO bi = myBxLo(myThid), myBxHi(myThid)

C--   Set Interior mask to zero beyond OB
C-    Eastern boundary
        DO j=1-OLy,sNy+OLy
         jm = MAX( j-1, 1-OLy )
         iB = OB_Ie(j,bi,bj)
         IF ( iB.NE.OB_indexNone ) THEN
           DO i=iB,iB+OB_ApplX-1
             OBCS_insideMask(i,j,bi,bj) = 0.
           ENDDO
           DO i=iB+1,iB+OB_ApplX-1
             maskInW(i,j,bi,bj) = 0.
           ENDDO
           IF ( OB_Ie(jm,bi,bj).NE.OB_indexNone ) THEN
            iB = MAX( iB, OB_Ie(jm,bi,bj) )
            DO i=iB,iB+OB_ApplX-1
             maskInS(i,j,bi,bj) = 0.
            ENDDO
           ENDIF
         ENDIF
        ENDDO
C-    Western boundary
        DO j=1-OLy,sNy+OLy
         jm = MAX( j-1, 1-OLy )
         iB = OB_Iw(j,bi,bj)
         IF ( iB.NE.OB_indexNone ) THEN
           DO i=1-OB_ApplX+iB,iB
             OBCS_insideMask(i,j,bi,bj) = 0.
           ENDDO
           DO i=2-OB_ApplX+iB,iB
             maskInW(i,j,bi,bj) = 0.
           ENDDO
           IF ( OB_Iw(jm,bi,bj).NE.OB_indexNone ) THEN
            iB = MIN( iB, OB_Iw(jm,bi,bj) )
            DO i=1-OB_ApplX+iB,iB
             maskInS(i,j,bi,bj) = 0.
            ENDDO
           ENDIF
         ENDIF
        ENDDO
C-    Northern boundary
        DO i=1-OLx,sNx+OLx
         im = MAX( i-1, 1-OLx )
         jB = OB_Jn(i,bi,bj)
         IF ( jB.NE.OB_indexNone ) THEN
           DO j=jB,jB+OB_ApplY-1
             OBCS_insideMask(i,j,bi,bj) = 0.
           ENDDO
           DO j=jB+1,jB+OB_ApplY-1
             maskInS(i,j,bi,bj) = 0.
           ENDDO
           IF ( OB_Jn(im,bi,bj).NE.OB_indexNone ) THEN
            jB = MAX( jB, OB_Jn(im,bi,bj) )
            DO j=jB,jB+OB_ApplY-1
             maskInW(i,j,bi,bj) = 0.
            ENDDO
           ENDIF
         ENDIF
        ENDDO
C-    Southern boundary
        DO i=1-OLx,sNx+OLx
         im = MAX( i-1, 1-OLx )
         jB = OB_Js(i,bi,bj)
         IF ( jB.NE.OB_indexNone ) THEN
           DO j=1-OB_ApplY+jB,jB
             OBCS_insideMask(i,j,bi,bj) = 0.
           ENDDO
           DO j=2-OB_ApplY+jB,jB
             maskInS(i,j,bi,bj) = 0.
           ENDDO
           IF ( OB_Js(im,bi,bj).NE.OB_indexNone ) THEN
            jB = MIN( jB, OB_Js(im,bi,bj) )
            DO j=1-OB_ApplY+jB,jB
             maskInW(i,j,bi,bj) = 0.
            ENDDO
           ENDIF
         ENDIF
        ENDDO

C--   Apply mask to maskInC :
        DO j=1-OLy,sNy+OLy
          DO i=1-OLx,sNx+OLx
            maskInC(i,j,bi,bj) = maskInC(i,j,bi,bj)
     &                          *OBCS_insideMask(i,j,bi,bj)
          ENDDO
        ENDDO

C--   end bi,bj loops
       ENDDO
      ENDDO

C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|

C--   Set OB active tiles:
      DO bj = myByLo(myThid), myByHi(myThid)
       DO bi = myBxLo(myThid), myBxHi(myThid)
         tileHasOBE(bi,bj) = .FALSE.
         tileHasOBW(bi,bj) = .FALSE.
         tileHasOBN(bi,bj) = .FALSE.
         tileHasOBS(bi,bj) = .FALSE.
         DO j=1-OLy,sNy+OLy
          tileHasOBE(bi,bj) = tileHasOBE(bi,bj) .OR.
     &                      ( OB_Ie(j,bi,bj).NE.OB_indexNone )
          tileHasOBW(bi,bj) = tileHasOBW(bi,bj) .OR.
     &                      ( OB_Iw(j,bi,bj).NE.OB_indexNone )
         ENDDO
         DO i=1-OLx,sNx+OLx
          tileHasOBN(bi,bj) = tileHasOBN(bi,bj) .OR.
     &                      ( OB_Jn(i,bi,bj).NE.OB_indexNone )
          tileHasOBS(bi,bj) = tileHasOBS(bi,bj) .OR.
     &                      ( OB_Js(i,bi,bj).NE.OB_indexNone )
         ENDDO
       ENDDO
      ENDDO

C--   Set domain connected-piece Id for OB grid points:
      CALL OBCS_SET_CONNECT( myThid )

#ifdef ALLOW_DEBUG
      IF (debugMode) CALL DEBUG_LEAVE('OBCS_INIT_FIXED',myThid)
#endif

#endif /* ALLOW_OBCS */
      RETURN
      END
