*-----------------------------------------------------------------------
*     Copyright (C) 2000-2022 GFD Dennou Club. All rights reserved.
*-----------------------------------------------------------------------
      SUBROUTINE UVDIFZ(N,UPX,UPY1,UPY2,ITPAT1,ITPAT2)

      REAL      UPX(*),UPY1(*),UPY2(*)

      LOGICAL   LMISS, LXUNI, LYC1, LYC2
      CHARACTER COBJ*80

      COMMON    /SZBTN2/ IRMODE, IRMODR
      COMMON    /SZBTN3/ LCLIP
      LOGICAL   LCLIP


      IF (N.LT.1) THEN
        CALL MSGDMP('E','UVDIFZ','NUMBER OF POINTS IS LESS THAN 1.')
      END IF
      IF (ITPAT1.EQ.0 .OR. ITPAT2.EQ.0) THEN
        CALL MSGDMP('M','UVDIFZ','TONE PAT. INDEX IS 0 / DO NOTHING.')
        RETURN
      END IF
      IF (ITPAT1.LT.0 .OR. ITPAT2.LT.0) THEN
        CALL MSGDMP('E','UVDIFZ','TONE PAT. INDEX IS LESS THAN 0.')
      END IF

      CALL SGLGET('LCLIP' , LCLIP)
      CALL GLRGET('RUNDEF', RUNDEF)
      CALL GLRGET('RMISS' , RMISS)
      CALL GLLGET('LMISS' , LMISS)

      CALL STFPR2(0., 0., RX0, RY0)
      CALL STFPR2(0., 1., RX1, RY1)
      CALL STFPR2(1., 0., RX2, RY2)

      ROT = (RX2-RX0)*(RY1-RY0) - (RY2-RY0)*(RX1-RX0)

      IF (ROT.GT.0) THEN
        IR = 0
      ELSE
        IR = 1
      END IF

      WRITE(COBJ,'(2I8)') ITPAT1, ITPAT2
      CALL CDBLK(COBJ)
      CALL SWOOPN('UVDIFZ',COBJ)

      LXUNI = UPX(1).EQ.RUNDEF
      LYC1  = UPY1(1).EQ.RUNDEF
      LYC2  = UPY2(1).EQ.RUNDEF

      IF (LXUNI) THEN
        CALL UUQIDV(UXMIN, UXMAX)
        IF (UXMIN.EQ.RUNDEF) CALL SGRGET('UXMIN', UXMIN)
        IF (UXMAX.EQ.RUNDEF) CALL SGRGET('UXMAX', UXMAX)
        DX = (UXMAX-UXMIN)/(N-1)
      END IF

      IF (LYC1 .OR. LYC2) THEN
        CALL UURGET('UREF', UREF)
      END IF

      DO 20 I=1,N-1
        IF (LXUNI) THEN
          UXP = UXMIN + DX*(I-1)
          UXN = UXMIN + DX*I
        ELSE
          UXP = UPX(I)
          UXN = UPX(I+1)
        END IF

        IF (LYC1) THEN
          UY1P = UREF
          UY1N = UREF
        ELSE
          UY1P = UPY1(I)
          UY1N = UPY1(I+1)
        END IF

        IF (LYC2) THEN
          UY2P = UREF
          UY2N = UREF
        ELSE
          UY2P = UPY2(I)
          UY2N = UPY2(I+1)
        END IF

        IF (.NOT.
     #    ((UXP .EQ.RMISS .OR. UXN .EQ.RMISS .OR.
     #      UY1P.EQ.RMISS .OR. UY1N.EQ.RMISS .OR.
     #      UY2P.EQ.RMISS .OR. UY2N.EQ.RMISS) .AND. LMISS)) THEN

          CALL STFTRF(UXP, UY1P, VXP, VY1P)
          CALL STFTRF(UXP, UY2P, VXP, VY2P)
          CALL STFTRF(UXN, UY1N, VXN, VY1N)
          CALL STFTRF(UXN, UY2N, VXN, VY2N)

          IF ((VY2P-VY1P)*(VY2N-VY1N) .GE. 0) THEN
            IF (VY2P.GE.VY1P) THEN
              IRMODE = 0
            ELSE
              IRMODE = 1
            END IF
            IRMODR = MOD(IRMODE+IR, 2)

            IF (UY2P .GT. UY1P) THEN
              CALL SZSTNI(ITPAT1)
            ELSE
              CALL SZSTNI(ITPAT2)
            END IF

            CALL SZOPTV
            CALL SZSTTV(VXP, VY2P)
            CALL SZSTTV(VXP, VY1P)
            CALL SZSTTV(VXN, VY1N)
            CALL SZSTTV(VXN, VY2N)
            CALL SZSTTV(VXP, VY2P)
            CALL SZCLTV
          ELSE
            DYP = ABS(VY2P-VY1P)
            DYN = ABS(VY2N-VY1N)
            VXC = (VXP*DYN  + VXN*DYP ) / (DYP + DYN)
            VYC = (VY1P*DYN + VY1N*DYP) / (DYP + DYN)

            IF (VY2P.GE.VY1P) THEN
              IRMODE = 0
            ELSE
              IRMODE = 1
            END IF
            IRMODR = MOD(IRMODE+IR, 2)

            IF (UY2P .GT. UY1P) THEN
              CALL SZSTNI(ITPAT1)
            ELSE
              CALL SZSTNI(ITPAT2)
            END IF

            CALL SZOPTV
            CALL SZSTTV(VXP, VY2P)
            CALL SZSTTV(VXP, VY1P)
            CALL SZSTTV(VXC, VYC )
            CALL SZSTTV(VXP, VY2P)
            CALL SZCLTV

            IRMODE = MOD(IRMODE+1,  2)
            IRMODR = MOD(IRMODE+IR, 2)

            IF (UY2N .GT. UY1N) THEN
              CALL SZSTNI(ITPAT1)
            ELSE
              CALL SZSTNI(ITPAT2)
            END IF

            CALL SZOPTV
            CALL SZSTTV(VXN, VY1N)
            CALL SZSTTV(VXN, VY2N)
            CALL SZSTTV(VXC, VYC )
            CALL SZSTTV(VXN, VY1N)
            CALL SZCLTV
          END IF
        END IF
   20 CONTINUE

      CALL SWOCLS('UVDIFZ')

      END
