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 IGDIWE (KILONG, KIWE, KOLONG, KOWE, OWEGLOBE,
     1   KWEIND, KWEDIST, KPR, KERR)
C
C---->
C**** *IGDIWE*
C
C     PURPOSE
C     _______
C
C     Calculate the distances between points in an output longitude
C     array and its West and East neighbours in the input longitude
C     array.
C
C     INTERFACE
C     _________
C
C     IERR = IGDIWE (KILONG, KIWE, KOLONG, KOWE, OWEGLOBE, KWEIND,
C    1   KWEDIST, KPR, KERR)
C
C     Input parameters
C     ________________
C
C     KILONG     - The array of input longitudes.
C
C     KIWE       - The number of points in the West-East direction in
C                  the input field.
C
C     KOLONG     - The array of output longitudes.
C
C     KOWE       - The number of points in the West-East direction in
C                  the output field.
C
C     OWEGLOBE   - This variable will be true if the input array of
C                  longitudes spans the globe.
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     KWEIND     - This array will contain the array offsets of the
C                  West and East points in the input array required
C                  for interpolation.
C
C     KWEDIST    - This array holds the distances to longitude values
C                  in the input field from the associated longitude
C                  values in the output field.
C
C     Return value
C     ____________
C
C     The error indicator (INTEGER).
C
C     Error and Warning Return Values
C     _______________________________
C
C     24601 An output longitude was found that was outside the range
C           spanned by the input longitudes.
C
C     Common block usage
C     __________________
C
C     None
C
C     EXTERNALS
C     _________
C
C     INTLOG(R)    - Logs messages.
C
C     METHOD
C     ______
C
C     This routine will create the arrays of offsets and distance
C     as two arrays of length (2, Number of output longitudes).
C     This will be used for all latitude rows when both the input
C     and output grids are regular.
C
C     This routine is used to provide the values for one line of
C     latitude for quasi regular Gaussian input fields.
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     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"
C
C     Dummy arguments
      LOGICAL OWEGLOBE
      INTEGER KIWE, KOWE, KPR, KERR
      INTEGER KILONG (KIWE + 1), KOLONG (KOWE)
      INTEGER KWEIND (2, KOWE), KWEDIST (2, KOWE)
C
C     Local variables
      INTEGER IBASE, ILOW, IUP
      INTEGER JINP, JOUT
      INTEGER JPROUTINE
      PARAMETER (JPROUTINE = 24600)
C
C     _______________________________________________________
C
C*    Section 1. Initialisation
C     _______________________________________________________
C
  100 CONTINUE
C
      IF (KPR.GE.1) CALL INTLOG(JP_DEBUG,'IGDIWE: Section 1.',JPQUIET)
C
      IGDIWE = 0
C
      IF (KPR .GE. 1) THEN
        CALL INTLOG(JP_DEBUG,'IGDIWE: Input parameters.',JPQUIET)
        CALL INTLOG(JP_DEBUG,'IGDIWE: No.input fld pts = ',KIWE)
        CALL INTLOG(JP_DEBUG,'IGDIWE: No.output fld pts = ',KOWE)
        CALL INTLOG(JP_DEBUG,'IGDIWE: Input fld spread from ',KILONG(1))
        CALL INTLOG(JP_DEBUG,'IGDIWE: to ',KILONG(KIWE))
        CALL INTLOG(JP_DEBUG,'IGDIWE: Output spread from ',KOLONG(1))
        CALL INTLOG(JP_DEBUG,'IGDIWE: to ',KOLONG(KOWE))
        IF( OWEGLOBE ) THEN
          CALL INTLOG(JP_DEBUG,
     X      'IGDIWE: Input W-E fld is global',JPQUIET)
        ELSE
          CALL INTLOG(JP_DEBUG,
     X      'IGDIWE: Input W-E fld is NOT global',JPQUIET)
        ENDIF
      ENDIF
C
C     _______________________________________________________
C
C*    Section 2. Select points around a line of latitude.
C     _______________________________________________________
C
  200 CONTINUE
C
      IF (KPR.GE.1) CALL INTLOG(JP_DEBUG,'IGDIWE: Section 2.',JPQUIET)
C
      IF (OWEGLOBE) THEN
C
        DO 230 JINP = 1, KIWE
C
C       NOTE that point number 1 is repeated as point KIWE + 1
C       to simplify the wrap around case
C
          ILOW = KILONG (JINP)
          IUP = KILONG (JINP + 1)
C
          IF (IUP .GT. ILOW) THEN
C
C           Normal case IUP > ILOW
C
            DO 210 JOUT = 1, KOWE
C
              IF (KOLONG(JOUT).GE.ILOW .AND.  KOLONG(JOUT).LT.IUP) THEN
C
C               Longitude point found
C
                KWEIND (JP_I_W, JOUT) = JINP
C
                IF (JINP .LT. KIWE) THEN
                  KWEIND (JP_I_E, JOUT) = JINP + 1
                ELSE
                  KWEIND (JP_I_E, JOUT) = 1
                ENDIF
C
                KWEDIST (JP_I_W, JOUT) = KOLONG (JOUT) - ILOW
                KWEDIST (JP_I_E, JOUT) = IUP - KOLONG (JOUT)
C
              ENDIF
C
  210       CONTINUE
C
          ELSE
C
C           Wrap around case
C
            DO 220 JOUT = 1, KOWE
C
              IF (KOLONG (JOUT) .GE. ILOW) THEN
C
C               Longitude point found between ILOW and 3600000
C
                KWEIND (JP_I_W, JOUT) = JINP
C
                IF (JINP .LT. KIWE) THEN
                  KWEIND (JP_I_E, JOUT) = JINP + 1
                ELSE
                  KWEIND (JP_I_E, JOUT) = 1
                ENDIF
C
                KWEDIST (JP_I_W, JOUT) = KOLONG (JOUT) - ILOW
                KWEDIST (JP_I_E, JOUT) = IUP + JP360 - KOLONG (JOUT)
C
              ENDIF
C
Cjdc          IF (KOLONG (JOUT) .LT. IUP) THEN
              IF (KOLONG (JOUT) .LE. IUP) THEN
C
C               Longitude point found between 0 and IUP
C
                KWEIND (JP_I_W, JOUT) = JINP
C
                IF (JINP .LT. KIWE) THEN
                  KWEIND (JP_I_E, JOUT) = JINP + 1
                ELSE
                  KWEIND (JP_I_E, JOUT) = 1
                ENDIF
C
                KWEDIST (JP_I_W, JOUT) = KOLONG (JOUT) + JP360 - ILOW
                KWEDIST (JP_I_E, JOUT) = IUP - KOLONG (JOUT)
C
              ENDIF
C
  220       CONTINUE
C
          ENDIF
C
  230   CONTINUE
C
      ELSE
C
C       Pointer to last point found if input grid is not global
C
        IBASE = 1
C
        DO 250 JOUT = 1, KOWE
C
          DO 240 JINP = IBASE, KIWE - 1
C
            ILOW = KILONG (JINP)
            IUP = KILONG (JINP + 1)
C
C           Normal case IUP > ILOW
C
Cjdc        IF (KOLONG(JOUT).GE.ILOW .AND. KOLONG(JOUT).LT.IUP) THEN
            IF (KOLONG(JOUT).GE.ILOW .AND. KOLONG(JOUT).LE.IUP) THEN
C
C             Longitude point found
C
              KWEIND (JP_I_W, JOUT) = JINP
              KWEIND (JP_I_E, JOUT) = JINP + 1
              IBASE = JINP
C
              KWEDIST (JP_I_W, JOUT) = KOLONG (JOUT) - ILOW
              KWEDIST (JP_I_E, JOUT) = IUP - KOLONG (JOUT)
C
              GO TO 250
C
C           Wrap around case
C
            ELSE IF (IUP .LT. ILOW) THEN
C
              IF (KOLONG (JOUT) .GE. ILOW) THEN
C
C               Longitude point found between ILOW and 3600000
C
                KWEIND (JP_I_W, JOUT) = JINP
                KWEIND (JP_I_E, JOUT) = JINP + 1
                IBASE = JINP
C
                KWEDIST (JP_I_W, JOUT) = KOLONG (JOUT) - ILOW
                KWEDIST (JP_I_E, JOUT) = IUP + JP360 - KOLONG (JOUT)
C
                GO TO 250
C
              ENDIF
C
Cjdc          IF (KOLONG (JOUT) .LT. IUP) THEN
              IF (KOLONG (JOUT) .LE. IUP) THEN
C
C               Longitude point found between 0 and IUP
C
                KWEIND (JP_I_W, JOUT) = JINP
                KWEIND (JP_I_E, JOUT) = JINP + 1
                IBASE = JINP
C
                KWEDIST (JP_I_W, JOUT) = KOLONG (JOUT) + JP360 - ILOW
                KWEDIST (JP_I_E, JOUT) = IUP - KOLONG (JOUT)
C
                GO TO 250
C
              ENDIF
C
            ENDIF
C
  240     CONTINUE
C
C         This statement will be reached if the output grid does not
C         fit within the input grid.
C
          IGDIWE = JPROUTINE + 1
          IF (KERR .GE. 0) THEN
            CALL INTLOG(JP_ERROR,
     X        'IGDIWE: Output long. value number = ',JOUT)
            CALL INTLOGR(JP_ERROR,
     X        'IGDIWE: Output long. value ',REAL(KOLONG(JOUT))/PPMULT)
            CALL INTLOGR(JP_ERROR,
     X        'IGDIWE: outside input range = ',REAL(KILONG(1))/PPMULT)
            CALL INTLOGR(JP_ERROR,
     X        'IGDIWE: to ',REAL(KILONG(KIWE))/PPMULT)
          ENDIF
C
          IF (KERR .EQ. 0) CALL INTLOGR(JP_FATAL,
     X      'IGDIWE: Interpolation failing.',IGDIWE)
C
          GO TO 900
C
  250   CONTINUE
C
      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,'IGDIWE: Section 9.',JPQUIET)
C
      RETURN
      END
