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 IAINTLL (KIFELD, KILEN, PWEST, PEAST, PNORTH,
     1   PSOUTH, PNSINC, PWEINC, KOFELD, KOLEN, KOBITS, KPR, KERR)
C
C---->
C**** *IAINTLL*
C
C     PURPOSE
C     _______
C
C     The global controlling routine for interpolating between a GRIB
C     input field and a regular latitude longitude output field.
C
C     INTERFACE
C     _________
C
C     IERR = IAINTLL (KIFELD, KILEN, PWEST, PEAST, PNORTH, PSOUTH,
C    1   PNSINC, PWEINC, KOFELD, KOLEN, KOBITS, KPR, KERR)
C
C     Input parameters
C     ________________
C
C     KIFELD     - The input field provided by the calling routine.
C
C     KILEN      - The length of the input field.
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     KOLEN      - The length of the output field.
C
C     KOBITS     - The number of bits used for packing the output array.
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     KOFELD     - The output field returned to the calling routine.
C
C     KOLEN      - The amount of the output array used for the packed
C                  GRIB field.
C
C     Return value
C     ____________
C
C     The error indicator (INTEGER).
C
C     Error and Warning Return Values
C     _______________________________
C
C     21301 The number of bits requested was outside the allowed
C           range 0 to 24.
C     21302 The input data representation was not valid when the GRIB
C           field had been expanded.
C
C     Common block usage
C     __________________
C
C     grfixed.h    - The include file contains all the array space
C                    for grid to grid interpolation.
C
C     MILLEN       - The array of latitude line lengths for a quasi
C                    regular input field is used.
C     RIGAUSS      - Real array of input field Gaussian latitudes is
C                    used.
C
C     ouspace.h    - This file contains the work space array
C                    definitions for the arrays to hold the unpacked
C                    real data from GRIB fields.
C
C     RIFELD       - The expanded input field is set and used.
C     ROFELD       - The expanded output field is set and used.
C
C     nifld.common - This file contains all the input field
C                    definition variables.
C
C     LCHANGE      - Process change flag is set.
C
C     NIAREA       - Input field area definition (N/W/S/E) is set.
C     NIGAUSS      - Input field Gaussian truncation is used.
C     NIGRID       - Input field grid definition (WE/NS) is used.
C     NINS         - Number of grid points in NS direction for input
C                    field is used.
C     NIREPR       - Input field representation is used.
C     NIWE         - Number of grid points in WE direction for input
C                    field is used.
C
C     nofld.common - This file contains all the output field
C                    definition variables.
C
C     NOACC        - Number of packing bits to be used for output
C                    GRIB field is set.
C     NOAREA       - Output field area definition (N/W/S/E) is set.
C     NOGRID       - Output field grid definition (WE/NS) is used..
C     NONS         - Number of grid points in NS direction for output
C                    field is set and used.
C     NOWE         - Number of grid points in WE direction for output
C                    field is set and used.
C
C     EXTERNALS
C     _________
C
C     ABORTX     - Standard routine to kill task.
C     GRIBEX     - Standard routine to unpack or pack a GRIB field.
C     IAGCNTL    - Perform regular grid to grid point interpolation.
C     IARCNTL    - Perform regular grid to grid point interpolation.
C     IAIDEF     - Initialise the input field definition variables
C                  from a GRIB definition
C     IAOLDEF    - Initialise the output field definition variables
C                  from the user supplied values.
C     IARESET    - Create the output field definition in GRIB format.
C     IARMEM     - Get space for the unpacked input and output
C                  fields.
C     IGLSIZE    - Evaluate the array sizes for a regular
C                  latitude/longitude grid and area.
C     IGSIZE     - Evaluate the array sizes for a Gaussian truncation
C                  and area.
C     IRSIZE     - Evaluate the array sizes for a quasi regular
C                  Gaussian field.
C     INTLOG     - Logs messages.
C
C     METHOD
C     ______
C
C     This is purely a controlling routine with all the work being
C     performed in the external routines.
C
C     REFERENCE
C     _________
C
C     None
C
C     COMMENTS
C     ________
C
C     Program contains sections 0 to 7 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"
#include "nofld.common"
#include "grfixed.h"
#include "ouspace.h"
C
C     Dummy arguments
C
      INTEGER KILEN, KOLEN, KOBITS, KPR, KERR
C
      REAL PWEST, PEAST, PNORTH, PSOUTH, PNSINC, PWEINC
C
      INTEGER KIFELD (*), KOFELD (*)
C
C     Local variables
C
      CHARACTER*1 HFUNC
      LOGICAL GIWEGLOBE, GINPOLE, GISPOLE, GOWEGLOBE, GONPOLE,
     1   GOSPOLE, GICHNG, GOCHNG
C
      INTEGER IILN, ITOTAL, IOLN
C
      INTEGER IIAREA (4), IOAREA (4)
C
      INTEGER JLAT, JSET
C
      INTEGER IERR
C
      INTEGER ISEC0 (JPGRIB_ISEC0), ISEC1 (JPGRIB_ISEC1)
      INTEGER ISEC2 (JPGRIB_ISEC2), ISEC3 (JPGRIB_ISEC3)
      INTEGER ISEC4 (JPGRIB_ISEC4)
C
      INTEGER ZSEC2 (JPGRIB_RSEC2), ZSEC3 (JPGRIB_RSEC3)
C
      INTEGER JPROUTINE
C
      PARAMETER (JPROUTINE = 21300)
C
C     External functions
C
      INTEGER IAGCNTL, IARCNTL, IAIDEF, IAOLDEF, IARESET, IARMEM,
     1   IGSIZE, IGLSIZE, IRSIZE
C
C     Transform definition variables that must be preserved
C
      SAVE IILN, IIAREA, IOLN, IOAREA, ITOTAL
      SAVE GIWEGLOBE, GINPOLE, GISPOLE, GOWEGLOBE, GONPOLE,
     1   GOSPOLE
C
C     _______________________________________________________
C
C
C*    Section 1. Initialisation
C     _______________________________________________________
C
  100 CONTINUE
C
      IF (KPR.GE.1) CALL INTLOG(JP_DEBUG,'IAINTLL: Section 1.',JPQUIET)
C
      IAINTLL = 0
C
      IERR = 0
C
      IF (KPR .GE. 1) THEN
         CALL INTLOG(JP_DEBUG,'IAINTLL: Input parameters',JPQUIET)
         CALL INTLOG(JP_DEBUG,'IAINTLL: Input array length = ',KILEN)
         CALL INTLOG(JP_DEBUG,'IAINTLL: Output array length = ',KOLEN)
         CALL INTLOG(JP_DEBUG,'IAINTLL: Out field packing bits=',KOBITS)
         CALL INTLOGR(JP_DEBUG,'IAINTLL: W-E increment is ',PWEINC)
         CALL INTLOGR(JP_DEBUG,'IAINTLL: N-S increment is ',PNSINC)
         CALL INTLOGR(JP_DEBUG,'IAINTLL: Area North = ',PNORTH)
         CALL INTLOGR(JP_DEBUG,'IAINTLL: Area West = ',PWEST)
         CALL INTLOGR(JP_DEBUG,'IAINTLL: Area South = ',PSOUTH)
         CALL INTLOGR(JP_DEBUG,'IAINTLL: Area East = ',PEAST)
      ENDIF
C
      IF (KOBITS .LT. 0 .OR. KOBITS .GT. 24) THEN
C
        IAINTLL = JPROUTINE + 1
        IF (KERR .GE. 0) THEN
          CALL INTLOG(JP_ERROR,
     X      'IAINTLL: No. bits requested = ',KOBITS)
          CALL INTLOG(JP_ERROR,
     X      'IAINTLL: Range allowed is <0 - 24>',JPQUIET)
          IF (KERR .EQ. 0) CALL INTLOG(JP_FATAL,
     X      'IAINTLL: Interpolation failing.',JPQUIET)
        ENDIF
        GO TO 900
C
      ENDIF
C
      NOACC = KOBITS
C
C     _______________________________________________________
C
C
C*    Section 2. Input grid definition from GRIB file
C     _______________________________________________________
C
  200 CONTINUE
C
      IF (KPR.GE.1) CALL INTLOG(JP_DEBUG,'IAINTLL: Section 2.',JPQUIET)
C
C     Unpack GRIB sections 0, 1 and 2 only
C
      IERR = KERR
C
C     CALL GRSDBG (KPR)
C
      CALL GRIBEX (ISEC0, ISEC1, ISEC2, ZSEC2, ISEC3, ZSEC3, ISEC4,
     1   RIFELD, 1, KIFELD, KILEN, KOLEN, 'I', IERR)
C
      IF (IERR .NE. 0) THEN
         IAINTLL = IERR
         GO TO 900
      ENDIF
C
      IERR = IAIDEF (ISEC1, ISEC2, IIAREA, MILLEN, GICHNG, KPR, KERR)
C
      IF (IERR .GT. 0) THEN
         IAINTLL = IERR
         GO TO 900
      ENDIF
C
      IF (GICHNG) THEN
C
        DO 210 JSET = 1, 4
          NIAREA (JSET) = IIAREA (JSET)
  210   CONTINUE
C
        IF (NIREPR .EQ. JPGAUSSIAN) THEN
C
          IERR = IGSIZE (NIGAUSS, NIAREA, NIWE, NINS, IILN, RIGAUSS,
     1         GIWEGLOBE, GINPOLE, GISPOLE, KPR, KERR)
C
          IF (IERR .GT. 0) THEN
            IAINTLL = IERR
            GO TO 900
          ENDIF
C
          ITOTAL = NIWE * NINS
C
        ELSE IF (NIREPR .EQ. JPQUASI) THEN
C
          IERR = IRSIZE (NIGAUSS, NIAREA, MILLEN, NIWE, NINS, IILN,
     1         ITOTAL, RIGAUSS, GIWEGLOBE, GINPOLE, GISPOLE, KPR, KERR)
C
          IF (IERR .GT. 0) THEN
            IAINTLL = IERR
            GO TO 900
          ENDIF
C
        ELSE IF (NIREPR .EQ. JPREGULAR) THEN
C
          IERR = IGLSIZE (NIGRID, NIAREA, NIWE, NINS, IILN,
     1         GIWEGLOBE, GINPOLE, GISPOLE, KPR, KERR)
C
          IF (IERR .GT. 0) THEN
            IAINTLL = IERR
            GO TO 900
          ENDIF
C
          ITOTAL = NIWE * NINS
C
        ELSE
C
          IAINTLL = JPROUTINE + 2
          IF (KERR .GE. 0) CALL INTLOG(JP_ERROR,
     X      'IAINTLL: Invalid input representation = ',NIREPR)
          IF (KERR .EQ. 0) CALL INTLOG(JP_FATAL,
     X      'IAINTLL: Interpolation failing.',JPQUIET)

          GO TO 900
C
        ENDIF
C
      ELSE
        IF (NIREPR .NE. JPQUASI) THEN
          ITOTAL = NIWE * NINS
        ELSE
          ITOTAL = 0
          DO 220 JLAT = 1, NINS
            ITOTAL = ITOTAL + MILLEN (JLAT)
  220     CONTINUE
        ENDIF
      ENDIF
C
      LCHANGE = LCHANGE .OR. GICHNG
C
C     _______________________________________________________
C
C
C*    Section 3. Output field definiton from parameters
C     _______________________________________________________
C
  300 CONTINUE
C
      IF (KPR.GE.1) CALL INTLOG(JP_DEBUG,'IAINTLL: Section 3.',JPQUIET)
C
      IERR = IAOLDEF (PWEST, PEAST, PNORTH, PSOUTH, PNSINC, PWEINC,
     1   IOAREA, GOCHNG, GIWEGLOBE, GINPOLE, GISPOLE, NIAREA, KPR,
     2   KERR)
C
      IF (IERR .GT. 0) THEN
         IAINTLL = IERR
         GO TO 900
      ENDIF
C
      IF (GOCHNG) THEN
C
         DO 310 JSET = 1, 4
            NOAREA (JSET) = IOAREA (JSET)
  310    CONTINUE
C
         NOWE = 0
         NONS = 0
C
         IERR = IGLSIZE (NOGRID, NOAREA, NOWE, NONS, IOLN, GOWEGLOBE,
     1      GONPOLE, GOSPOLE, KPR, KERR)
C
         IF (IERR .GT. 0) THEN
            IAINTLL = IERR
            GO TO 900
         ENDIF
      ENDIF
C
      LCHANGE = LCHANGE .OR. GOCHNG
C
C     _______________________________________________________
C
C
C*    Section 4. Get space for REAL input and output arrays
C     _______________________________________________________
C
  400 CONTINUE
C
      IF (KPR.GE.1) CALL INTLOG(JP_DEBUG,'IAINTLL: Section 4.',JPQUIET)
C
      IF (LCHANGE) THEN
C
         IERR = IARMEM (ITOTAL, NOWE * NONS, KPR, KERR)
C
         IF (IERR .GT. 0) THEN
            IAINTLL = IERR
            GO TO 900
         ENDIF
      ENDIF
C
C     _______________________________________________________
C
C
C*    Section 5. Fully unpack the GRIB array
C     _______________________________________________________
C
  500 CONTINUE
C
      IF (KPR.GE.1) CALL INTLOG(JP_DEBUG,'IAINTLL: Section 5.',JPQUIET)
C
      IERR = KERR
C
C     CALL GRSDBG (KPR)
C
      ISEC3(2) = NINT(RMISSGV)
      ZSEC3(2) = RMISSGV
      CALL GRIBEX (ISEC0, ISEC1, ISEC2, ZSEC2, ISEC3, ZSEC3, ISEC4,
     1   RIFELD, ITOTAL, KIFELD, KILEN, KOLEN, 'D', IERR)
C
      IF (IERR .NE. 0) THEN
         IAINTLL = IERR
         GO TO 900
      ENDIF
C
C     _______________________________________________________
C
C
C*    Section 6. Basic interpolation from input to output field
C     _______________________________________________________
C
  600 CONTINUE
C
      IF (KPR.GE.1) CALL INTLOG(JP_DEBUG,'IAINTLL: Section 6.',JPQUIET)
C
      IF (NIREPR .EQ. JPQUASI) THEN
         IERR = IARCNTL (RIFELD, ITOTAL, ROFELD, NOWE * NONS, IILN,
     1      GIWEGLOBE, GINPOLE, GISPOLE, IOLN, GOWEGLOBE, GONPOLE,
     1      GOSPOLE, KPR, KERR)
      ELSE
         IERR = IAGCNTL (RIFELD, ITOTAL, ROFELD, NOWE * NONS, IILN,
     1      GIWEGLOBE, GINPOLE, GISPOLE, IOLN, GOWEGLOBE, GONPOLE,
     1      GOSPOLE, KPR, KERR)
      ENDIF
C
      IF (IERR .NE. 0) THEN
         IAINTLL = IERR
         GO TO 900
      ENDIF
C
C     _______________________________________________________
C
C
C*    Section 7. Repack GRIB code
C     _______________________________________________________
C
  700 CONTINUE
C
      IF (KPR.GE.1) CALL INTLOG(JP_DEBUG,'IAINTLL: Section 7.',JPQUIET)
C
      IERR = IARESET (ISEC2, ISEC4, NOWE * NONS, KPR, KERR)
C
      IF (IERR .NE. 0) THEN
         IAINTLL = IERR
         GO TO 900
      ENDIF
C
      IERR = KERR
C
C     CALL GRSDBG (KPR)
C
C     PACKING specified can be second-order, simple or archive value
C
      IF( NOHFUNC.EQ.'K' ) THEN
        HFUNC = 'K'
        ISEC4(4)  = 64
        ISEC4(6)  = 16
        ISEC4(9)  = 32
        ISEC4(10) = 16
        ISEC4(12) = 8
        ISEC4(13) = 4
        ISEC4(14) = 0
        ISEC4(15) = -1
      ELSE IF( NOHFUNC.EQ.'S' ) THEN
        HFUNC = 'C'
        ISEC4(4)  = 0
        ISEC4(6)  = 0
      ELSE IF( NOHFUNC.EQ.'A' ) THEN
        IF( ISEC4(4).EQ.64 ) THEN
          HFUNC = 'K'
        ELSE
          HFUNC = 'C'
        ENDIF
      ENDIF
C
      IF( LIMISSV ) THEN
        ISEC1(5) = 192
        ISEC3(2) = NINT(RMISSGV)
        ZSEC3(2) = RMISSGV
      ENDIF
      CALL GRIBEX (ISEC0, ISEC1, ISEC2, ZSEC2, ISEC3, ZSEC3, ISEC4,
     1   ROFELD, NOWE * NONS, KOFELD, KOLEN, KOLEN, HFUNC, IERR)
C
      IF (IERR .NE. 0) THEN
         IAINTLL = IERR
         GO TO 900
      ENDIF
C
      IF (KPR .GE. 1) CALL INTLOG(JP_DEBUG,
     X  'IAINTLL: Output array length = ',KOLEN)
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,'IAINTLL: Section 9.',JPQUIET)
C
 9002 FORMAT (' IAINTLL ERROR', I6, ' - Input representation', I6,
     1   ' is not valid')
C
      RETURN
      END
