!-------------------------------------- LICENCE BEGIN ------------------------------------
!Environment Canada - Atmospheric Science and Technology License/Disclaimer,
!                     version 3; Last Modified: May 7, 2008.
!This is free but copyrighted software; you can use/redistribute/modify it under the terms
!of the Environment Canada - Atmospheric Science and Technology License/Disclaimer
!version 3 or (at your option) any later version that should be found at:
!http://collaboration.cmc.ec.gc.ca/science/rpn.comm/license.html
!
!This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
!without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
!See the above mentioned License/Disclaimer for more details.
!You should have received a copy of the License/Disclaimer along with this software;
!if not, you can write to: EC-RPN COMM Group, 2121 TransCanada, suite 500, Dorval (Quebec),
!CANADA, H9P 1J3; or send e-mail to service.rpn@ec.gc.ca
!-------------------------------------- LICENCE END --------------------------------------
!

      SUBROUTINE LAYERAVG2(KFLAG,PX1,PX2,PY2,PY2INCR,KNO,KNI, 2,2
     &     PPS,PMEAN,PZ,PZS,PZPS,knprof,pvo)
C
      IMPLICIT NONE
C
C*    Declaration of arguments
C
      INTEGER KNO,KNI,KFLAG,knprof
      REAL*8 PX1(KNO),PX2(KNI,knprof),PY2(KNI,knprof),PY2INCR(KNI,knprof
     &     )
      REAL*8 PPS(knprof),PMEAN(kno,knprof),PZ(KNI),PZPS(kno,knprof)
     &     ,PZS(KNI,knprof),pvo(kno,knprof)
C
*---------------------------------------------------------
#if defined (DOC)
*
***s/r LAYERAVG - Perform integration between points PX1(KI-1) and
*                 PX1(KI+1) with  piecewise linear weighting having 
*                 weights of zero at  ki-1 and ki+1 and max weight at ki
c .
*
*                  Output: Weighted mean value, its contribution to
*                          the TLM*increment or to the adjoint.
*
*Author  : Y.J. Rochon *ARQX/EC Nov. 2005
*
**Revisions: 
*          S. Pellerin, ARMA, August 2008
*              - Introduction of version 2
*              - Introduction of profile and kno loops to reduce the
*                number of calls (optimisation)
*
*    -------------------
*
*Purpose: Perform integration between points PX1(KI-1) and
*         PX1(KI+1) with  piecewise linear weighting having 
*         weights of zero at  ki-1 and ki+1 and max weight at ki.
*  
*         Output: Weighted mean value, its contribution to
*                 the TLM*increment or to the adjoint.
*
*Arguments:
*
*   INPUT
*
*     KFLAG:    Indicates purpose of calc
*               0 - Application as forward interpolator
*               1 - Application for TLM* increments
*               2 - Setting of adjoint elements
*
*     PX1:      Reference levels (e.g. lnP; in increasing values)
*     PX2:      Available levels (e.g. lnP; in increasing values)
*     PY2:      Values at levels (e.g. temperature) 
*     PY2INCR:  Not relevant when kflag=0 or 2
*               Increments when kflag=1
*     PZ:       Extra array related to gradients w.r.t. Ps for KFLAG.gt
c .0
*     PMEAN:    Mean weigthed value for PX1(KI-1) to PX1(KI+1) when
c KFLAG=2.
*               Output otherwise.
*     KNO:      Dimension of PX1.
*     KNI:      Dimension of other arrays.
*     PZS:      dlnP/dPs
*     KI:       Identifies region of interest: PX1(KI-1) to PX1(KI+1)
*     PPS:      Surface pressure increment when KFLAG=1, not needed
c otherwise.
*
*   OUTPUT:
*
*     PMEAN:    Mean weigthed value for PX1(KI-1) to PX1(KI+1) using
*               background values when kflag=0 and increments when kflag
c =1.
*     PZ:       Resultant accumulated contribution factors
*               Adjoint when KFLAG=2 
*               TLM when KFLAG=1 or 0.
*     PZPS:     Surface pressure related adjoint term when KFLAG=2
*               Surface pressure related TLM*increment term when KFLAG=1
*
*-----------------------------------------------------------
#endif
C
C*    Declaration of local variables
C
      REAL*8 Z1,Z2,Z3,ZW1,ZW2
      REAL*8 zsum
      INTEGER J,IC,ISKIP,jo,jn
C
C --- Identify boundary points
C
      do jn = 1, knprof
        do jo = 1, kno
          z2=px1(jo)
C
          if (jo.eq.1) then 
            z1=2.0*z2-px1(jo+1)
          else
            z1=px1(jo-1)
          endif   
C
          if (jo.eq.kno) then
            z3=2.0*z2-z1
          else   
            z3=px1(jo+1)
          endif
          if (z3.gt.px2(kni,jn)) z3=px2(kni,jn)
C
          iskip=0
          if (z2.ge.px2(kni,jn)) then
            z3=px2(kni,jn)
            z2=px2(kni,jn)
            iskip=1
          endif
C
C --- Determine forward interpolator (kflag=0) or TLM (kflag>0)
C
          pzps(jo,jn)=0.0
          pz(1:kni)=0.0
          ic=0

c          call sublayer2(z1,z2,z3,px2(:,jn),kflag,
c     &         py2(:,jn),pzs(:,jn),pzps(jo,jn),pz,kni,ic,iskip)
          do j=1,kni-1
            if (px2(j,jn).ge.z3) go to 1000
C
            if (px2(j,jn).le.z2.and.px2(j+1,jn).gt.z1) then 
C
              call sublayer(z1,z2,z3,px2(j,jn),px2(j+1,jn),kflag,
     &             py2(j,jn),py2(j+1,jn),zw1,zw2,
     &             pzs(j,jn),pzs(j+1,jn),pzps(jo,jn))
              pz(j)=pz(j)+zw1
              pz(j+1)=pz(j+1)+zw2
              ic=1
            endif
C
            if (px2(j,jn).lt.z3.and.px2(j+1,jn).ge.z2.and.iskip.eq.0)
     &           then
C
              call sublayer(z3,z2,z1,px2(j,jn),px2(j+1,jn),kflag,
     &             py2(j,jn),py2(j+1,jn),zw1,zw2,
     &             pzs(j,jn),pzs(j+1,jn),pzps(jo,jn))
              pz(j)=pz(j)+zw1
              pz(j+1)=pz(j+1)+zw2
              ic=1
            endif
          enddo
 1000     continue
          if (ic.eq.0) pz(j)=1.0
C --- Apply forward interpolator (kflag=0), determine TLM*increment
c (kflag=1)
C     or use TLM for adjoint calc (kflag=2)

          zsum=0.0
          if (kflag.eq.0) then
            pmean(jo,jn)=0.0
            do j=1,kni
              pmean(jo,jn)=pmean(jo,jn)+pz(j)*py2(j,jn)
              zsum=zsum+pz(j)
            end do
            pmean(jo,jn)=pmean(jo,jn)/zsum
          else if (kflag.eq.1) then
            pmean(jo,jn)=0.0
            do j=1,kni      
              pmean(jo,jn)=pmean(jo,jn)+pz(j)*py2incr(j,jn)
              zsum=zsum+pz(j)
            end do
            pmean(jo,jn)=pmean(jo,jn)/zsum
            if (ic.ne.0) pzps(jo,jn)=pzps(jo,jn)*pps(jn)/zsum
            PVO(JO,JN)=pmean(jo,jn)+PZPS(jo,jn)
          else if (kflag.eq.2) then
            do j=1,kni
              zsum=zsum+pz(j)         
            end do
            pz(1:kni)=pz(1:kni)*pmean(jo,jn)/zsum
            py2incr(1:KNI,JN)=py2incr(1:KNI,JN)+PZ(1:KNI)
            if (ic.ne.0) pzps(jo,jn)=pzps(jo,jn)*pmean(jo,jn)/zsum
            PPS(JN)=PPS(JN)+PZPS(jo,jn)
          endif
        enddo
      enddo
C
      RETURN
      END