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 IRLREV (PMAT, KLEN, KLLEN, KCOL, KDIR, KPR,
     1   KERR)
C
C---->
C**** *IRLREV*
C
C     PURPOSE
C     _______
C
C     This routine reverses either the rows or the columns of a quasi
C     regular matrix.
C
C     INTERFACE
C     _________
C
C     IERR = IRLREV (PMAT, KLEN, KLLEN, KCOL, KDIR, KPR, KERR)
C
C     Input parameters
C     ________________
C
C     PMAT       - The input matrix of dimension (KLEN).
C
C     KLEN       - The length of the array PMAT.
C
C     KLLEN      - The lengths of each column within PMAT.
C
C     KCOL       - The number of entries in KLLEN and columns in PMAT.
C
C     KDIR       - 1   Reverses the order of the rows.
C                      West-East reversal for meteorological fields.
C                  2   Reverses the order of the columns.
C                      North-South reversal for meteorological fields.
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                  (No longer used, kept for backward compatibility.
C                   Used to be used as follows:
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
C     Output parameters
C     ________________
C
C     PMAT       - The transformed matrix.
C
C
C     Return value
C     ____________
C
C     The error indicator (INTEGER).
C
C     7501  A column swap has been attempted where the lengths in the
C           array KLLEN are not symmetric about the middle value.
C
C
C     Common block usage
C     __________________
C
C     None
C
C
C     EXTERNALS
C     _________
C
C     INTLOG     - Generate log messages.
C
C
C     METHOD
C     ______
C
C     KDIR = 1 is implemented by swapping corresponding columns of
C              the matrix.
C
C     KDIR = 2 is implemented by reversing the elements within each
C              column.
C
C
C     REFERENCE
C     _________
C
C     None
C
C
C     COMMENTS
C     ________
C
C     None.
C
C
C     AUTHOR
C     ______
C
C     K. Fielding      *ECMWF*      Jan 1994
C
C
C     MODIFICATIONS
C     _____________
C
C     J.D.Chambers      ECMWF        Sept 1995
C
C----<
C     _______________________________________________________
C
      IMPLICIT NONE
C
#include "parim.h"
C
C     Function arguments
      INTEGER KLEN, KCOL, KDIR, KPR, KERR
      INTEGER KLLEN (KCOL)
      REAL PMAT (KLEN)
C
C     Local variables
      INTEGER IHALF, ISTARTL, ISTARTU, ILINE
      INTEGER JSTEP, JMOVE
      REAL ZTEMP
C
C     Parameters.
      INTEGER JPROUTINE
      PARAMETER (JPROUTINE = 7500)
C
C     _______________________________________________________
C
C*    Section 1. Initialisation
C     _______________________________________________________
C
  100 CONTINUE
C
      IF (KPR.GE.1) CALL INTLOG(JP_DEBUG,'IRLREV: Section 1.',JPQUIET)
C
      IRLREV = 0
C
      IF (KPR .GE. 1) THEN
        CALL INTLOG(JP_DEBUG,'IRLREV: Input parameters.',JPQUIET)
        CALL INTLOG(JP_DEBUG,'IRLREV: Matrix length = ',KLEN)
        CALL INTLOG(JP_DEBUG,'IRLREV: Number of rows = ',KCOL)
        CALL INTLOG(JP_DEBUG,'IRLREV: Direction value = ',KDIR)
      ENDIF
C
C     _______________________________________________________
C
C*    Section 2. Matrix COLUMN reversal (Field row interchange - WE)
C     _______________________________________________________
C
  200 CONTINUE
C
      IF (KPR.GE.1) CALL INTLOG(JP_DEBUG,'IRLREV: Section 2.',JPQUIET)
C
      IF (KDIR .EQ. 1) THEN
C
        ISTARTL = 0
C
        DO 220 JSTEP = 1, KCOL
C
          ILINE = KLLEN (JSTEP)
          IHALF = ILINE / 2
C
          DO 210 JMOVE = 1, IHALF
            ZTEMP = PMAT(ISTARTL + ILINE + 1 - JMOVE)
            PMAT(ISTARTL + ILINE + 1 - JMOVE) = PMAT(ISTARTL + JMOVE)
            PMAT(ISTARTL + JMOVE) = ZTEMP
  210     CONTINUE
C
          ISTARTL = ISTARTL + ILINE
C
  220   CONTINUE
C
      ELSE
C
C     _______________________________________________________
C
C*    Section 3. Matrix ROW reversal (Field column interchange - NS)
C     _______________________________________________________
C
  300 CONTINUE
C
        IF (KPR.GE.1) CALL INTLOG(JP_DEBUG,'IRLREV: Section 3.',JPQUIET)
C
        IHALF = KCOL / 2
C
        ISTARTL = 0
        ISTARTU = KLEN - KLLEN (KCOL)
C
        DO 320 JMOVE = 1, IHALF
C
C         The quasi regular line lengths must be symmetric for this
C         operation.
C
          IF (KLLEN (JMOVE) .NE. KLLEN (KCOL + 1 - JMOVE) ) THEN
            IRLREV = JPROUTINE + 1
C
            CALL INTLOG(JP_ERROR,
     X        'IRLREV: Line of latitude reversal failed', JPQUIET)
            CALL INTLOG(JP_ERROR,'IRLREV: at lat.lines = ',JMOVE)
            CALL INTLOG(JP_ERROR,'IRLREV: and = ',(KCOL+1-JMOVE))
            CALL INTLOG(JP_ERROR,
     X        'IRLREV: Lengths are not the same.', JPQUIET)
            CALL INTLOG(JP_ERROR,'IRLREV: 1st length = ', KLLEN (JMOVE))
            CALL INTLOG(JP_ERROR,
     X        'IRLREV: 2nd length = ',KLLEN(KCOL+1-JMOVE))
C
          ENDIF
C
          DO 310 JSTEP = 1, KLLEN (JMOVE)
C
            ZTEMP = PMAT (ISTARTU + JSTEP)
            PMAT (ISTARTU + JSTEP) = PMAT (ISTARTL + JSTEP)
            PMAT (ISTARTL + JSTEP) = ZTEMP
C
  310     CONTINUE
C
          ISTARTL = ISTARTL + KLLEN (JMOVE)
          ISTARTU = ISTARTU - KLLEN (KCOL - JMOVE)
C
  320   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,'IRLREV: Section 9.',JPQUIET)
C
      RETURN
      END
