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 IAIDEF (KSEC1, KSEC2, KIAREA, KLLEN, OICHNG,
     1   KPR, KERR)
C
C---->
C**** *IAIDEF*
C
C     PURPOSE
C     _______
C
C     Generate an input field definition from the GRIB definition.
C
C     INTERFACE
C     _________
C
C     IERR = IAIDEF (KSEC1, KSEC2, KIAREA, KLLEN, OICHNG, KPR, KERR)
C
C     Input parameters
C     ________________
C
C     KSEC1      - The GRIB Section 1 array for the input field.
C
C     KSEC2      - The GRIB Section 2 array for the input field.
C
C     KIAREA     - The previous input field area used for comparison.
C
C     KLLEN      - The previous latitude line lengths for a quasi
C                  regular Gaussian field used for comparison.
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     KIAREA     - The area for this field.
C
C     KLLEN      - The latitude line lengths for a quasi regular
C                  Gaussian field.
C
C     OICHNG     - A flag indicating whether the field definition has
C                  changed since the previous call to this routine.
C
C     Return value
C     ____________
C
C     The error indicator (INTEGER).
C
C     Error and Warning Return Values
C     _______________________________
C
C     21701 The data representation was not valid.
C     21702 The scan mode was not valid.
C
C     Common block usage
C     __________________
C
C     nifld.common - This file contains all the input field
C                    definition variables.
C
C     LSMCHNG      - LSM change flag is set.
C     LSM          - LSM usage flag is set.
C     LSMPAR       - LSM parameter flag is set.
C     LPREC        - Precipitation flag is set.
C     LWIND        - Wind flag is set.
C
C     NIGAUSS      - Input field Gaussian truncation is used and set.
C     NIGRID       - Input field grid definition (WE/NS) is used and
C                    set.
C     NINS         - Number of grid points in NS direction for input
C                    field is used and set.
C     NIPARAM      - Input field parameter number is used and set.
C     NIREPR       - Input field representation is used and set.
C     NISCNM       - Input field scanning mode is set.
C     NITABLE      - Input field table number is used and set.
C     NIWE         - Number of grid points in WE direction for input
C                    field is used and set.
C
C     EXTERNALS
C     _________
C
C     PRECIP       - Says if field is to have 'precipitation' treatment
C     SETPAR       - Standard routine used to generate "missing" data
C                    values for GRIB fields.
C     INTLOG       - Logs messages.
C
C     METHOD
C     ______
C
C     This routine uses sections 1 and 2 of the input GRIB field to
C     generate the input field definition. This definition is
C     compared with the previous field definition to see if any
C     change of definition has occurred.
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 "nifld.common"
C
C     Subroutine arguments
      LOGICAL OICHNG
      INTEGER KPR, KERR
      INTEGER KSEC1 (JPGRIB_ISEC1), KSEC2 (JPGRIB_ISEC2), KIAREA (4)
      INTEGER KLLEN (*)
C
C     Local variables
      LOGICAL GNLSM
      INTEGER ITEMP, IMISS, IWEST, IEAST, IERR
      INTEGER JSET
      INTEGER JPROUTINE
      PARAMETER (JPROUTINE = 21700)
C
C     External functions
C
      LOGICAL PRECIP
C
C     _______________________________________________________
C
C*    Section 1. Initialisation
C     _______________________________________________________
C
  100 CONTINUE
C
      IF (KPR.GE.1) CALL INTLOG(JP_DEBUG,'IAIDEF: Section 1.',JPQUIET)
C
      IAIDEF = 0
      IERR = 0
      OICHNG = .FALSE.
C
C     Get GRIB missing data value
C
      CALL SETPAR (ITEMP, IMISS, KPR)
C
C     _______________________________________________________
C
C*    Section 2. Set Grib Section 2 variables and check consistency
C     _______________________________________________________
C
  200 CONTINUE
C
      IF (KPR.GE.1) CALL INTLOG(JP_DEBUG,'IAIDEF: Section 2.',JPQUIET)
C
C     Representation
C
      IF (KSEC2 (JPSEC2_REP) .EQ. JPGAUSSIAN .AND.
     1   KSEC2 (JPSEC2_QUASI) .EQ. 1) THEN
         ITEMP = JPQUASI
      ELSE
         ITEMP = KSEC2 (JPSEC2_REP)
      ENDIF
C
      IF (ITEMP .NE. NIREPR) THEN
         NIREPR = ITEMP
         OICHNG = .TRUE.
      ENDIF
C
C     Only grid point input data allowed now
C
      IF (NIREPR .NE. JPQUASI .AND. NIREPR .NE. JPGAUSSIAN .AND.
     X  NIREPR .NE. JPREGULAR) THEN
        IAIDEF = JPROUTINE + 1
        IF (KERR .GE. 0) THEN
          CALL INTLOG(JP_ERROR,
     X      'IAIDEF: Illegal input representation = ',NIREPR)
          IF (KERR .EQ. 0) CALL INTLOG(JP_FATAL,
     X      'IAIDEF: Interpolation failing.',JPQUIET)
        ENDIF
        GO TO 900
      ENDIF
C
C     scan mode
C
      NISCNM  = KSEC2 (JPSEC2_SCAN)
C
      IF (NISCNM .NE. 0) THEN
        IAIDEF = JPROUTINE + 2
        IF (KERR .GE. 0) THEN
          CALL INTLOG(JP_ERROR,'IAIDEF: Illegal scan mode = ',NISCNM)
          IF (KERR .EQ. 0) CALL INTLOG(JP_FATAL,
     X      'IAIDEF: Interpolation failing.',JPQUIET)
        ENDIF
        GO TO 900
      ENDIF
C
C     Number of lines North-South and West-East
C
      IF (KSEC2 (JPSEC2_NLAT) .NE. NINS) THEN
        NINS = KSEC2 (JPSEC2_NLAT)
        OICHNG = .TRUE.
      ENDIF
C
      IF (NIREPR.NE.JPQUASI .AND. KSEC2(JPSEC2_NLONG).NE.NIWE) THEN
        NIWE = KSEC2 (JPSEC2_NLONG)
        OICHNG = .TRUE.
      ENDIF
C
C     North, South, West and East limits
C
      IF (KSEC2 (JPSEC2_NORTH) * 10 .NE. KIAREA (JPNORTH) ) THEN
        KIAREA (JPNORTH) = KSEC2 (JPSEC2_NORTH) * 10
        OICHNG = .TRUE.
      ENDIF
C
      IF (KSEC2 (JPSEC2_SOUTH) * 10 .NE. KIAREA (JPSOUTH) ) THEN
        KIAREA (JPSOUTH) = KSEC2 (JPSEC2_SOUTH) * 10
        OICHNG = .TRUE.
      ENDIF
C
      IWEST = KSEC2 (JPSEC2_WEST) * 10
C
C     Make West and East points an ordered pair
C
      IF (NIREPR .EQ. JPQUASI) THEN
        IEAST = 0
      ELSE
        IEAST = KSEC2 (JPSEC2_EAST) * 10
C
        IF (IEAST .LT. IWEST) THEN
          IF (IEAST .LE. 0) THEN
            IEAST = IEAST + JP360
          ELSE
            IWEST = IWEST - JP360
          ENDIF
        ENDIF
      ENDIF
C
      IF (IEAST .NE. KIAREA (JPEAST) ) THEN
        KIAREA (JPEAST) = IEAST
        OICHNG = .TRUE.
      ENDIF
C
      IF (IWEST .NE. KIAREA (JPWEST) ) THEN
        KIAREA (JPWEST) = IWEST
        OICHNG = .TRUE.
      ENDIF
C
      IF (NIREPR .EQ. JPREGULAR) THEN
C
C       Direction increments for regular grids
C
        IF (KSEC2 (JPSEC2_DLONG) .EQ. IMISS) THEN
          ITEMP = (KIAREA (JPEAST) - KIAREA (JPWEST) ) / NIWE + 1
        ELSE
          ITEMP = KSEC2 (JPSEC2_DLONG) * 10
        ENDIF
C
        IF (NIGRID (JPWESTEP) .NE. ITEMP) THEN
          NIGRID (JPWESTEP) = ITEMP
          OICHNG = .TRUE.
        ENDIF
C
        IF (KSEC2 (JPSEC2_DLAT) .EQ. IMISS) THEN
          ITEMP = (KIAREA (JPNORTH) - KIAREA (JPSOUTH) ) / NINS + 1
        ELSE
          ITEMP = KSEC2 (JPSEC2_DLAT) * 10
        ENDIF
C
        IF (NIGRID (JPNSSTEP) .NE. ITEMP) THEN
          NIGRID (JPNSSTEP) = ITEMP
          OICHNG = .TRUE.
        ENDIF
C
      ELSE IF (NIREPR .EQ. JPGAUSSIAN) THEN
C
        IF (NIGAUSS .NE. KSEC2 (JPSEC2_GTRUNC) ) THEN
          NIGAUSS = KSEC2 (JPSEC2_GTRUNC)
          OICHNG = .TRUE.
        ENDIF
C
      ELSE IF (NIREPR .EQ. JPQUASI) THEN
C
        IF (NIGAUSS .NE. KSEC2 (JPSEC2_GTRUNC) ) THEN
          NIGAUSS = KSEC2 (JPSEC2_GTRUNC)
          NIWE = NIGAUSS * 4
          OICHNG = .TRUE.
        ENDIF
C
C     Set line length definitions for Quasi regular field
C
        DO 210 JSET = 1, NINS
          IF (KLLEN (JSET) .NE. KSEC2 (JPSEC2_QUDEF + JSET) ) THEN
            KLLEN (JSET) = KSEC2 (JPSEC2_QUDEF + JSET)
            OICHNG = .TRUE.
          ENDIF
  210   CONTINUE
C
      ENDIF
C
C     _______________________________________________________
C
C*    Section 3. Set Grib Section 1 variables and flags
C     _______________________________________________________
C
  300 CONTINUE
C
      IF (KPR.GE.1) CALL INTLOG(JP_DEBUG,'IAIDEF: Section 3.',JPQUIET)
C
      NITABLE = KSEC1 (JPSEC1_TABLE)
      NIPARAM = KSEC1 (JPSEC1_PARAM)
C
C     Setup ECMWF local definition number and stream if applicable
C
      IF( KSEC1(24).EQ.1 ) THEN
        NILOCAL = KSEC1(37)
        NISTREM = KSEC1(40)
      ELSE
        NILOCAL = 0
        NISTREM = 0
      ENDIF
C
      LPREC = PRECIP()
C
      IF (NITABLE .EQ. 1) THEN
C
C       WMO International table for meteorological parameters
C
        LWIND = NIPARAM .EQ. JP_WMO_U .OR. NIPARAM .EQ. JP_WMO_V
C
        LSMPAR = NIPARAM .EQ. JP_WMO_LSM
C
        GNLSM = .NOT. (NIPARAM .EQ. JP_WMO_MSL .OR. LSMPAR)
C
        IF (GNLSM .NEQV. LSM) THEN
          LSMCHNG = .TRUE.
          LSM = GNLSM
        ENDIF
C
      ELSE IF (NITABLE .EQ. 128) THEN
C
C       ECMWF local code table 2 for meteorological parameters
C
        LWIND = NIPARAM .EQ. JP_U .OR. NIPARAM .EQ. JP_V .OR.
     X      NIPARAM .EQ. JP_10U .OR. NIPARAM .EQ. JP_10V
C
        LSMPAR = NIPARAM .EQ. JP_LSM
C
        GNLSM = .NOT. (NIPARAM .EQ. JP_MSL .OR. LSMPAR)
C
        IF (GNLSM .NEQV. LSM) THEN
          LSMCHNG = .TRUE.
          LSM = GNLSM
        ENDIF
C
      ELSE IF (NITABLE .EQ. 129) THEN
C
C       ECMWF local code table for gradients of parameters
C
        LWIND = .FALSE.
        LSMPAR = .FALSE.
C
        IF (.NOT. LSM) THEN
          LSMCHNG = .TRUE.
          LSM = .TRUE.
        ENDIF
C
      ELSE IF (NITABLE .EQ. 130) THEN
C
C       ECMWF local code table for ASTEX experiments
C
        LWIND = .FALSE.
        LSMPAR = .FALSE.
C
        IF (.NOT. LSM) THEN
          LSMCHNG = .TRUE.
          LSM = .TRUE.
        ENDIF
C
      ELSE IF (NITABLE .EQ. 131) THEN
C
C       ECMWF local code table for probability forecasts
C
        LWIND = .FALSE.
        LSMPAR = .FALSE.
C
        IF (.NOT. LSM) THEN
          LSMCHNG = .TRUE.
          LSM = .TRUE.
        ENDIF
C
      ELSE IF (NITABLE .EQ. 140) THEN
C
C       ECMWF local code table for wave models
C
        LWIND = .FALSE.
        LSMPAR = .FALSE.
C
        IF (.NOT. LSM) THEN
          LSMCHNG = .TRUE.
          LSM = .TRUE.
        ENDIF
C
      ELSE IF (NITABLE .EQ. 150) THEN
C
C       ECMWF local code table ocean data
C
        LWIND = .FALSE.
        LSMPAR = .FALSE.
C
        IF (.NOT. LSM) THEN
          LSMCHNG = .TRUE.
          LSM = .TRUE.
        ENDIF
C
      ELSE
C
C       Unexpected code table found
C
        LWIND = .FALSE.
        LSMPAR = .FALSE.
C
        IF (.NOT. LSM) THEN
          LSMCHNG = .TRUE.
          LSM = .TRUE.
        ENDIF
C
      ENDIF
C
      IF (KPR .GE. 1) THEN
        CALL INTLOG(JP_DEBUG,
     X    'IAIDEF: Input field definition parameters.',JPQUIET)
        CALL INTLOG(JP_DEBUG,'IAIDEF: Parameter value = ',NIPARAM)
        CALL INTLOG(JP_DEBUG,'IAIDEF: Representation = ',NIREPR)
        IF (NIWE .NE. 0) CALL INTLOG(JP_DEBUG,
     X    'IAIDEF: Number W-E = ',NIWE)
        IF (NINS .NE. 0) CALL INTLOG(JP_DEBUG,
     X    'IAIDEF: Number N-S = ',NINS)
        IF (NIREPR .EQ. JPGAUSSIAN .OR. NIREPR .EQ. JPQUASI)
     X    CALL INTLOG(JP_DEBUG,'IAIDEF: Gaussian truncation = ',NIGAUSS)
        IF (NIREPR .EQ. JPREGULAR .AND. NIGRID (1) .NE. 0) THEN
          CALL INTLOG(JP_DEBUG,'IAIDEF: Grid WE = ',NIGRID (1))
          CALL INTLOG(JP_DEBUG,'IAIDEF: Grid NS = ',NIGRID (2))
        ENDIF
        IF (KIAREA (1) .NE. 0) THEN
          CALL INTLOG(JP_DEBUG,'IAIDEF: Area North = ',KIAREA(1))
          CALL INTLOG(JP_DEBUG,'IAIDEF: Area West  = ',KIAREA(2))
          CALL INTLOG(JP_DEBUG,'IAIDEF: Area South = ',KIAREA(3))
          CALL INTLOG(JP_DEBUG,'IAIDEF: Area East  = ',KIAREA(4))
        ENDIF
C
        CALL INTLOG(JP_DEBUG,'IAIDEF: Control flag status:',JPQUIET)
C
        IF( OICHNG ) THEN
          CALL INTLOG(JP_DEBUG,'IAIDEF:Input fld change TRUE',JPQUIET)
        ELSE
          CALL INTLOG(JP_DEBUG,'IAIDEF:Input fld change FALSE',JPQUIET)
        ENDIF
C
        IF( LSMCHNG ) THEN
          CALL INTLOG(JP_DEBUG,'IAIDEF: LSM change TRUE',JPQUIET)
        ELSE
          CALL INTLOG(JP_DEBUG,'IAIDEF: LSM change FALSE',JPQUIET)
        ENDIF
C
        IF( LSM ) THEN
          CALL INTLOG(JP_DEBUG,'IAIDEF: LSM flag TRUE',JPQUIET)
        ELSE
          CALL INTLOG(JP_DEBUG,'IAIDEF: LSM flag FALSE',JPQUIET)
        ENDIF
C
        IF( LWIND ) THEN
          CALL INTLOG(JP_DEBUG,'IAIDEF: Wind flag TRUE',JPQUIET)
        ELSE
          CALL INTLOG(JP_DEBUG,'IAIDEF: Wind flag FALSE',JPQUIET)
        ENDIF
C
        IF( LPREC ) THEN
          CALL INTLOG(JP_DEBUG,'IAIDEF: Precipitn flag TRUE',JPQUIET)
        ELSE
          CALL INTLOG(JP_DEBUG,'IAIDEF: Precipitn flag FALSE',JPQUIET)
        ENDIF
C
        IF( LSMPAR ) THEN
          CALL INTLOG(JP_DEBUG,'IAIDEF: LSM param flag TRUE',JPQUIET)
        ELSE
          CALL INTLOG(JP_DEBUG,'IAIDEF: LSM param flag FALSE',JPQUIET)
        ENDIF
      ENDIF
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,'IAIDEF: Section 9.',JPQUIET)
C
      RETURN
      END
