C Copyright 1981-2012 ECMWF.
C
C This software is licensed under the terms of the Apache Licence 
C Version 2.0 which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
C
C In applying this licence, ECMWF does not waive the privileges and immunities 
C granted to it by virtue of its status as an intergovernmental organisation 
C nor does it submit to any jurisdiction.
C

      INTEGER FUNCTION IAOLDEF (PWEST, PEAST, PNORTH, PSOUTH,
     1   PNSINC, PWEINC, KAREA, OCHNG, OIWEGLOBE, OINPOLE, OISPOLE,
     2   KIAREA, KPR, KERR)
C
C---->
C**** *IAOLDEF*
C
C     PURPOSE
C     _______
C
C     Set the output field definition variables for a regular
C     latitude longitude field.
C
C     INTERFACE
C     _________
C
C     IERR = IAOLDEF (PWEST, PEAST, PNORTH, PSOUTH, PNSINC, PWEINC,
C    1   KAREA, OCHNG, OIWEGLOBE, OINPOLE, OISPOLE, KIAREA, KPR, KERR)
C
C     Input parameters
C     ________________
C
C     PWEST      - The Western limit of the output field area.
C
C     PEAST      - The Eastern limit of the output field area.
C
C     PNORTH     - The Northern limit of the output field area.
C
C     PSOUTH     - The Southern limit of the output field area.
C
C     PNSINC     - The North-South stride for the output field.
C
C     PWEINC     - The West-East stride for the output field.
C
C     KAREA      - The previous output field area used for checking
C                  for definition changes.
C
C     OIWEGLOBE  - Flag indicating whether the INPUT field spans the
C                  globe in the West-East direction.
C
C     OINPOLE    - Flag indicating whether the INPUT field includes
C                  the North polar line of latitude.
C
C     OISPOLE    - Flag indicating whether the INPUT field includes
C                  the South polar line of latitude.
C
C     KIAREA     - The input field area which will be used for an
C                  uninitialised output field area when the input
C                  field is not global.
C
C     KPR        - The debug print switch.
C                  0  , No debugging output.
C                  1  , Produce debugging output.
C
C     KERR       - The error control flag.
C                  -ve, No error message. Return error code.
C                  0  , Hard failure with error message.
C                  +ve, Print error message. Return error code.
C
C     Output parameters
C     ________________
C
C     KAREA      - The output field area if the definition has changed.
C
C     OCHNG      - A flag variable indicating whether the definition
C                  has changed.
C
C     Return value
C     ____________
C
C     The error indicator (INTEGER).
C
C     Error and Warning Return Values
C     _______________________________
C
C     None
C
C     Common block usage
C     __________________
C
C     nofld.common - This file contains all the output field
C                    definition variables.
C
C     NOGRID       - Output field grid definition (WE/NS) is set.
C     NOREPR       - Output field representation is set.
C     NOSCNM       - Output field scanning mode is set.
C
C     EXTERNALS
C     _________
C
C     INTLOG     - Logs messages.
C
C     METHOD
C     ______
C
C     Check the output definition against the previous definition and
C     update appropriate definition variables.
C
C     REFERENCE
C     _________
C
C     None
C
C     COMMENTS
C     ________
C
C     Program contains sections 0 to 3 and 9
C
C     AUTHOR
C     ______
C
C     K. Fielding      *ECMWF*      Apr 1994
C
C     MODIFICATIONS
C     _____________
C
C     None
C
C----<
C     _______________________________________________________
C
C
C*    Section 0. Definition of variables.
C     _______________________________________________________
C
C*    Prefix conventions for variable names
C
C     Logical      L (but not LP), global or common.
C                  O, dummy argument
C                  G, local variable
C                  LP, parameter.
C     Character    C, global or common.
C                  H, dummy argument
C                  Y (but not YP), local variable
C                  YP, parameter.
C     Integer      M and N, global or common.
C                  K, dummy argument
C                  I, local variable
C                  J (but not JP), loop control
C                  JP, parameter.
C     REAL         A to F and Q to X, global or common.
C                  P (but not PP), dummy argument
C                  Z, local variable
C                  PP, parameter.
C
C     Implicit statement to force declarations
C
      IMPLICIT NONE
C
#include "parim.h"
#include "nofld.common"
C
C     Subroutine arguments
      LOGICAL OCHNG, OIWEGLOBE, OINPOLE, OISPOLE
      INTEGER KPR, KERR
      INTEGER KAREA (4), KIAREA (4)
      REAL PWEST, PEAST, PNORTH, PSOUTH, PNSINC, PWEINC
C
C     Local variables
      LOGICAL GLOBE
      INTEGER INORTH, ISOUTH, IWEST, IEAST, IWEINC, INSINC, IWETMP,
     1   INSTMP, ITEMP
      INTEGER IERR
      INTEGER JPROUTINE
      PARAMETER (JPROUTINE = 21400)
C
C     External functions
C
C     Transform definition variables that must be preserved
C
C     _______________________________________________________
C
C*    Section 1. Initialisation
C     _______________________________________________________
C
  100 CONTINUE
C
      IF (KPR.GE.1) CALL INTLOG(JP_DEBUG,'IAOLDEF: Section 1.',JPQUIET)
C
      IAOLDEF = 0
C
      IERR = 0
C
      OCHNG = .FALSE.
C
      GLOBE = OIWEGLOBE .AND. OINPOLE .AND. OISPOLE
C
      IF (KPR .GE. 1) THEN
        CALL INTLOG(JP_DEBUG,'IAOLDEF: Input parameters.',JPQUIET)
        CALL INTLOGR(JP_DEBUG,'IAOLDEF: W-E increment is ',PWEINC)
        CALL INTLOGR(JP_DEBUG,'IAOLDEF: N-S increment is ',PNSINC)
        CALL INTLOGR(JP_DEBUG,'IAOLDEF: AREA North ',PNORTH)
        CALL INTLOGR(JP_DEBUG,'IAOLDEF: AREA West ',PWEST)
        CALL INTLOGR(JP_DEBUG,'IAOLDEF: AREA South ',PSOUTH)
        CALL INTLOGR(JP_DEBUG,'IAOLDEF: AREA East ',PEAST)
      ENDIF
C
C     _______________________________________________________
C
C
C*    Section 2. Convert parameters to integer
C     _______________________________________________________
C
  200 CONTINUE
C
      IF (KPR.GE.1) CALL INTLOG(JP_DEBUG,'IAOLDEF: Section 2.',JPQUIET)
C
C     Representation
C
      IF (NOREPR .NE. JPREGULAR) THEN
         NOREPR = JPREGULAR
         OCHNG = .TRUE.
      ENDIF
C
      NOSCNM = 0
C
C     North, South, West and East limits
C
      INORTH = NINT (PNORTH * PPMULT)
      ISOUTH = NINT (PSOUTH * PPMULT)
      IWEST = NINT (PWEST * PPMULT)
      IEAST = NINT (PEAST * PPMULT)
C
C     Direction increments for regular grids
C
      IWEINC = NINT (ABS (PWEINC) * PPMULT)
      IWEINC = MAX (IWEINC, JPMIN)
C
      INSINC = NINT (ABS (PNSINC) * PPMULT)
      INSINC = MAX (INSINC, JPMIN)
C
C     _______________________________________________________
C
C
C*    Section 3. Adjust grid stride and area
C     _______________________________________________________
C
  300 CONTINUE
C
      IF (KPR.GE.1) CALL INTLOG(JP_DEBUG,'IAOLDEF: Section 3.',JPQUIET)
C
C     Global field if all area limits are 0
C
      IF (INORTH .EQ. 0 .AND. ISOUTH .EQ. 0 .AND.
     1   IWEST .EQ. 0 .AND. IEAST .EQ. 0) THEN
C
         IF (GLOBE) THEN
C
  310 CONTINUE
            IF (MOD (JP90, IWEINC) .EQ. 0) GO TO 320
               IWEINC = IWEINC - 1
               GO TO 310
  320 CONTINUE
C
            IF (MOD (JP90, INSINC) .EQ. 0) GO TO 330
               INSINC = INSINC - 1
               GO TO 320
  330 CONTINUE
C
            INORTH = JP90
            ISOUTH = - JP90
            IWEST = 0
            IEAST = JP360 - IWEINC
C
         ELSE
C
            IF (OINPOLE) THEN
               INORTH = JP90
            ELSE
               INORTH = KIAREA (JPNORTH)
            ENDIF
C
            IF (OISPOLE) THEN
               ISOUTH = - JP90
            ELSE
               ISOUTH = KIAREA (JPSOUTH)
            ENDIF
C
            IF (OIWEGLOBE) THEN
C
  340 CONTINUE
               IF (MOD (JP90, IWEINC) .EQ. 0) GO TO 350
                  IWEINC = IWEINC - 1
                  GO TO 340
  350 CONTINUE
C
               IWEST = 0
               IEAST = JP360 - IWEINC
            ELSE
               IWEST = KIAREA (JPWEST)
               IEAST = KIAREA (JPEAST)
C
  360 CONTINUE
               IF (MOD (IEAST - IWEST, IWEINC) .EQ. 0) GO TO 370
                  IWEINC = IWEINC - 1
                  GO TO 360
  370 CONTINUE
C
            ENDIF
C
  380 CONTINUE
            IF (MOD (INORTH - ISOUTH, INSINC) .EQ. 0) GO TO 390
               INSINC = INSINC - 1
               GO TO 380
  390 CONTINUE
C
         ENDIF
      ELSE
C
C     Try to produce fields representable in GRIB for 0.5625 degree
C     strides
C
         IF (IEAST .LT. IWEST) THEN
            IF (IEAST .LE. 0) THEN
               IEAST = IEAST + JP360
            ELSE
               IWEST = IWEST - JP360
            ENDIF
         ENDIF
C
         GLOBE = IEAST - IWEST + IWEINC .EQ. JP360 .OR.
     1      IEAST - IWEST + IWEINC .EQ. 0
C
         IF (MOD (IWEINC, 10) .EQ. 5 .AND. .NOT. GLOBE) THEN
            IWETMP = IWEINC * 2
         ELSE
            IWETMP = IWEINC
         ENDIF
C
         IF (MOD (IEAST - IWEST, IWETMP) .NE. 0) THEN
C
            IF (MOD (IEAST, IWETMP) .NE. 0) THEN
C
               ITEMP = ABS (IEAST) / IWETMP
C
               IF (IEAST .GT. 0) THEN
                  IEAST = (ITEMP + 1) * IWETMP
                  IF (IEAST .GT. JP360) IEAST = IEAST - IWETMP
               ELSE
                  IEAST = - ITEMP * IWETMP
               ENDIF
            ENDIF
C
            IF (MOD (IWEST, IWETMP) .NE. 0) THEN
C
               ITEMP = ABS (IWEST) / IWETMP
C
               IF (IWEST .LT. 0) THEN
                  IWEST = - (ITEMP + 1) * IWETMP
                  IF (IWEST .LT. - JP360) IWEST = IWEST + IWETMP
               ELSE
                  IWEST = ITEMP * IWETMP
               ENDIF
            ENDIF
         ENDIF
C
         IF (MOD (INSINC, 10) .EQ. 5) THEN
            INSTMP = INSINC * 2
         ELSE
            INSTMP = INSINC
         ENDIF
C
         IF (MOD (INORTH - ISOUTH, INSTMP) .NE. 0) THEN
C
            IF (MOD (INORTH, INSTMP) .NE. 0) THEN
C
               ITEMP = ABS (INORTH) / INSTMP
C
               IF (INORTH .GT. 0) THEN
                  INORTH = (ITEMP + 1) * INSTMP
                  IF (INORTH .GT. JP90) INORTH = INORTH - INSTMP
               ELSE
                  INORTH = - ITEMP * INSTMP
               ENDIF
            ENDIF
C
            IF (MOD (ISOUTH, INSTMP) .NE. 0) THEN
C
               ITEMP = ABS (ISOUTH) / INSTMP
C
               IF (ISOUTH .LT. 0) THEN
                  ISOUTH = - (ITEMP + 1) * INSTMP
                  IF (ISOUTH .LT. - JP90) ISOUTH = ISOUTH + INSTMP
               ELSE
                  ISOUTH = ITEMP * INSTMP
               ENDIF
            ENDIF
         ENDIF
C
      ENDIF
C
      IF (NOGRID (JPWESTEP) .NE. IWEINC) THEN
         NOGRID (JPWESTEP) = IWEINC
         OCHNG = .TRUE.
      ENDIF
C
      IF (NOGRID (JPNSSTEP) .NE. INSINC) THEN
         NOGRID (JPNSSTEP) = INSINC
         OCHNG = .TRUE.
      ENDIF
C
      IF (KAREA (JPNORTH) .NE. INORTH) THEN
         KAREA (JPNORTH) = INORTH
         OCHNG = .TRUE.
      ENDIF
C
      IF (KAREA (JPSOUTH) .NE. ISOUTH) THEN
         KAREA (JPSOUTH) = ISOUTH
         OCHNG = .TRUE.
      ENDIF
C
      IF (IWEST .NE. KAREA (JPWEST) ) THEN
         KAREA (JPWEST) = IWEST
         OCHNG = .TRUE.
      ENDIF
C
      IF (IEAST .NE. KAREA (JPEAST) ) THEN
         KAREA (JPEAST) = IEAST
         OCHNG = .TRUE.
      ENDIF
C
      IF (KPR .GE. 1) THEN
        CALL INTLOG(JP_DEBUG,
     X    'IAOLDEF: Output field definition parameters.',JPQUIET)
        CALL INTLOG(JP_DEBUG,
     X    'IAOLDEF: Representation is ',NOREPR)
        CALL INTLOG(JP_DEBUG,
     X    'IAOLDEF: Grid W-E is ', NOGRID(1))
        CALL INTLOG(JP_DEBUG,
     X    'IAOLDEF: Grid N-S is ', NOGRID(2))
        CALL INTLOG(JP_DEBUG,
     X    'IAOLDEF: Area North is ',KAREA(1))
        CALL INTLOG(JP_DEBUG,
     X    'IAOLDEF: Area West  is ',KAREA(2))
        CALL INTLOG(JP_DEBUG,
     X    'IAOLDEF: Area South is ',KAREA(3))
        CALL INTLOG(JP_DEBUG,
     X    'IAOLDEF: Area East  is ',KAREA(4))
C
        IF ( OCHNG ) THEN
          CALL INTLOG(JP_DEBUG,
     X      'IAOLDEF: Output field change is TRUE.',JPQUIET)
        ELSE
          CALL INTLOG(JP_DEBUG,
     X      'IAOLDEF: Output field change is FALSE.',JPQUIET)
        ENDIF
C
      ENDIF
C
C     _______________________________________________________
C
C
C*    Section 9. Return to calling routine. Format statements
C     _______________________________________________________
C
  900 CONTINUE
C
      IF (KPR.GE.1) CALL INTLOG(JP_DEBUG,'IAOLDEF: Section 9.',JPQUIET)
C
      RETURN
      END
