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 IGTOGR (PIFELDN, PIFELDS, KNINDEX, KSINDEX,
     1   PWFACT, KOWE, POFELD, KPR, KERR)
C
C---->
C**** *IGTOGR*
C
C     Purpose
C     -------
C
C     Perform basic interpolation for one line of latitude of the
C     output field using its two neighbouring input field lines of
C     latitude.
C
C     Interface
C     ---------
C
C     IERR = IGTOGR (PIFELDN, PIFELDS, KNINDEX, KSINDEX, PWFACT,
C    1   KOWE, POFELD, KPR, KERR)
C
C     Input parameters
C     ----------------
C
C     PIFELDN    - The line of latitude of the input field North of
C                  the output row.
C
C     PIFELDS    - The line of latitude of the input field South of
C                  the output row.
C
C     KNINDEX    - This array contains the array offsets of the West
C                  and East points in the input array North of the
C                  output row.
C
C     KSINDEX    - This array contains the array offsets of the West
C                  and East points in the input array South of the
C                  output row.
C
C     PWFACT     - The array of interpolating weights to the four
C                  neighbouring points for every output point of this
C                  line of latitude.
C
C     KOWE       - The number of points in the West-East direction in
C                  the output field.
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     POFELD     - The interpolated output field line of latitude
C                  returned to the calling routine.
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     None
C
C     Externals
C     ---------
C
C     INTLOG   - Logs messages.
C
C     Method
C     ------
C
C     This routine performs basic linear interpolation using the four
C     neighbouring points in the input array to generate the output
C     array.
C
C     The parameter list is designed to allow for quasi regular input
C     fields with different grid spacing in the Northern and Southern
C     lines of latitude.
C
C     Reference
C     ---------
C
C     None
C
C     Comments
C     --------
C
C     Program contains sections 0 to 2 and 9
C
C     Author
C     ------
C
C     K. Fielding      *ECMWF*      Oct 1993
C
C     Modifications
C     -------------
C
C     Allow for missing data values
C     J.D.Chambers      ECMWF       August 2000
C
C     Force nearest neighbour processing with env variable or
C     INTOUT parameter
C     S.Curic           ECMWF       September 2005
C
C----<
C     -----------------------------------------------------------------|
C
      IMPLICIT NONE
C
#include "parim.h"
#include "nifld.common"
#include "nofld.common"
C
C     Function arguments
C
      INTEGER KOWE, KPR, KERR
      INTEGER KNINDEX (2, KOWE), KSINDEX (2, KOWE)
      REAL PIFELDN (*), PIFELDS (*), POFELD (KOWE)
      REAL PWFACT (4, KOWE)
C
C     Local variables
C
      INTEGER JOLON, COUNT
      CHARACTER*12 YFLAG
      REAL NEAREST
      LOGICAL LVEGGY
C
C     Statement function
C
      REAL A, B
      LOGICAL NOTEQ
      NOTEQ(A,B) = (ABS((A)-(B)).GT.(ABS(A)*1E-3))
C
C     -----------------------------------------------------------------|
C*    Section 1. Initialisation
C     -----------------------------------------------------------------|
C
  100 CONTINUE
C
      IGTOGR = 0
C
      IF( KPR.GE.1 ) THEN
         CALL INTLOG(JP_DEBUG,'IGTOGR: Section 1.',JPQUIET)
         CALL INTLOG(JP_DEBUG,'IGTOGR: Input parameters.',JPQUIET)
         CALL INTLOG(JP_DEBUG,
     X     'IGTOGR:  Number of output field longitudes is -',KOWE)
      ENDIF
C
      LVEGGY = (NITABLE.EQ.128).AND.
     X         ((NIPARAM.EQ.27).OR.
     X          (NIPARAM.EQ.28).OR.
     X          (NIPARAM.EQ.29).OR.
     X          (NIPARAM.EQ.30).OR.
     X          (NIPARAM.EQ.43) )
C     Force nearest neighbour processing with env variable
        CALL GETENV('NEAREST_NEIGHBOUR', YFLAG)
        IF( YFLAG(1:1).EQ.'1' ) LVEGGY = .TRUE.

C     Force nearest neighbour processing with INTOUT parameter
        IF( LMETHOD ) LVEGGY = .TRUE.

      IF( LVEGGY ) CALL INTLOG(JP_DEBUG,
     X  'IGTOGR: nearest neighbour processing (vegetation)',JPQUIET)
C
C     -----------------------------------------------------------------|
C*    Section 2. Basic interpolation
C     -----------------------------------------------------------------|
C
  200 CONTINUE
C
      IF( KPR.GE.1 ) CALL INTLOG(JP_DEBUG,'IGTOGR: Section 2.',JPQUIET)
C
      DO JOLON = 1, KOWE
C
C       Count non-missing data values
C
        IF( LIMISSV ) THEN
          COUNT = 0
          IF( NOTEQ(PIFELDN(KNINDEX(JP_I_W,JOLON)),RMISSGV) )
     X      COUNT = COUNT + 1
          IF( NOTEQ(PIFELDN(KNINDEX(JP_I_E,JOLON)),RMISSGV) )
     X      COUNT = COUNT + 1
          IF( NOTEQ(PIFELDN(KSINDEX(JP_I_W,JOLON)),RMISSGV) )
     X      COUNT = COUNT + 1
          IF( NOTEQ(PIFELDN(KSINDEX(JP_I_E,JOLON)),RMISSGV) )
     X      COUNT = COUNT + 1
        ELSE
          COUNT = 4
        ENDIF
C
C       Interpolate using four neighbours if none are missing
C
        IF( (COUNT.EQ.4).AND.(.NOT.LVEGGY) ) THEN
          POFELD(JOLON) =
     X      PIFELDN(KNINDEX(JP_I_W,JOLON)) * PWFACT(JP_I_NW,JOLON) +
     X      PIFELDN(KNINDEX(JP_I_E,JOLON)) * PWFACT(JP_I_NE,JOLON) +
     X      PIFELDS(KSINDEX(JP_I_W,JOLON)) * PWFACT(JP_I_SW,JOLON) +
     X      PIFELDS(KSINDEX(JP_I_E,JOLON)) * PWFACT(JP_I_SE,JOLON)
C
C       Set missing if all neighbours are missing
C
        ELSE IF( COUNT.EQ.0 ) THEN
          POFELD(JOLON) = RMISSGV
C
C       Otherwise, use the nearest neighbour
C
        ELSE
          NEAREST = PWFACT(JP_I_NW,JOLON)
          POFELD(JOLON) = PIFELDN(KNINDEX(JP_I_W,JOLON))
C
          IF( PWFACT(JP_I_NE,JOLON).GT.NEAREST ) THEN
            NEAREST = PWFACT(JP_I_NE,JOLON)
            POFELD(JOLON) = PIFELDN(KNINDEX(JP_I_E,JOLON))
          ENDIF
C
          IF( PWFACT(JP_I_SW,JOLON).GT.NEAREST ) THEN
            NEAREST = PWFACT(JP_I_SW,JOLON)
            POFELD(JOLON) = PIFELDS(KSINDEX(JP_I_W,JOLON))
          ENDIF
C
          IF( PWFACT(JP_I_SE,JOLON).GT.NEAREST ) THEN
            NEAREST = PWFACT(JP_I_SE,JOLON)
            POFELD(JOLON) = PIFELDS(KSINDEX(JP_I_E,JOLON))
          ENDIF
        ENDIF
C
      ENDDO
C
C     -----------------------------------------------------------------|
C*    Section 9. Return to calling routine. Format statements
C     -----------------------------------------------------------------|
C
  900 CONTINUE
C
      IF( KPR.GE.1 ) CALL INTLOG(JP_DEBUG,'IGTOGR: Section 9.',JPQUIET)
C
      RETURN
      END
