*-----------------------------------------------------------------------
*     Copyright (C) 2000-2022 GFD Dennou Club. All rights reserved.
*-----------------------------------------------------------------------
      SUBROUTINE UHDIFZ(N,UPX1,UPX2,UPY,ITPAT1,ITPAT2)

      REAL      UPX1(*),UPX2(*),UPY(*)

      LOGICAL   LMISS, LYUNI, LXC1, LXC2
      CHARACTER COBJ*80

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


      IF (N.LT.1) THEN
        CALL MSGDMP('E','UHDIFZ','NUMBER OF POINTS IS LESS THAN 1.')
      END IF
      IF (ITPAT1.EQ.0 .OR. ITPAT2.EQ.0) THEN
        CALL MSGDMP('M','UHDIFZ','TONE PAT. INDEX IS 0 / DO NOTHING.')
        RETURN
      END IF
      IF (ITPAT1.LT.0 .OR. ITPAT2.LT.0) THEN
        CALL MSGDMP('E','UHDIFZ','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('UHDIFZ',COBJ)

      LYUNI = UPY(1).EQ.RUNDEF
      LXC1  = UPX1(1).EQ.RUNDEF
      LXC2  = UPX2(1).EQ.RUNDEF

      IF (LYUNI) THEN
        CALL UUQIDV(UYMIN, UYMAX)
        IF (UYMIN.EQ.RUNDEF) CALL SGRGET('UYMIN', UYMIN)
        IF (UYMAX.EQ.RUNDEF) CALL SGRGET('UYMAX', UYMAX)
        DY = (UYMAX-UYMIN)/(N-1)
      END IF

      IF (LXC1 .OR. LXC2) THEN
        CALL UURGET('UREF', UREF)
      END IF

      DO 20 I=1,N-1
        IF (LYUNI) THEN
          UYP = UYMIN + DY*(I-1)
          UYN = UYMIN + DY*I
        ELSE
          UYP = UPY(I)
          UYN = UPY(I+1)
        END IF

        IF (LXC1) THEN
          UX1P = UREF
          UX1N = UREF
        ELSE
          UX1P = UPX1(I)
          UX1N = UPX1(I+1)
        END IF

        IF (LXC2) THEN
          UX2P = UREF
          UX2N = UREF
        ELSE
          UX2P = UPX2(I)
          UX2N = UPX2(I+1)
        END IF

        IF (.NOT.
     #    ((UYP .EQ.RMISS .OR. UYN .EQ.RMISS .OR.
     #      UX1P.EQ.RMISS .OR. UX1N.EQ.RMISS .OR.
     #      UX2P.EQ.RMISS .OR. UX2N.EQ.RMISS) .AND. LMISS)) THEN

          CALL STFTRF(UX1P, UYP, VX1P, VYP)
          CALL STFTRF(UX2P, UYP, VX2P, VYP)
          CALL STFTRF(UX1N, UYN, VX1N, VYN)
          CALL STFTRF(UX2N, UYN, VX2N, VYN)

          IF ((VX2P-VX1P)*(VX2N-VX1N) .GE. 0) THEN
            IF (VX2P.GE.VX1P) THEN
              IRMODE = 0
            ELSE
              IRMODE = 1
            END IF
            IRMODR = MOD(IRMODE+IR, 2)

            IF (UX2P .GT. UX1P) THEN
              CALL SZSTNI(ITPAT1)
            ELSE
              CALL SZSTNI(ITPAT2)
            END IF

            CALL SZOPTV
            CALL SZSTTV(VX1P, VYP)
            CALL SZSTTV(VX2P, VYP)
            CALL SZSTTV(VX2N, VYN)
            CALL SZSTTV(VX1N, VYN)
            CALL SZSTTV(VX1P, VYP)
            CALL SZCLTV
          ELSE
            DXP = ABS(VX2P-VX1P)
            DXN = ABS(VX2N-VX1N)
            VYC = (VYP*DXN  + VYN*DXP ) / (DXP + DXN)
            VXC = (VX1P*DXN + VX1N*DXP) / (DXP + DXN)

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

            IF (UX2P .GT. UX1P) THEN
              CALL SZSTNI(ITPAT1)
            ELSE
              CALL SZSTNI(ITPAT2)
            END IF

            CALL SZOPTV
            CALL SZSTTV(VX1P, VYP)
            CALL SZSTTV(VX2P, VYP)
            CALL SZSTTV(VXC , VYC )
            CALL SZSTTV(VX1P, VYP)
            CALL SZCLTV

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

            IF (UX2N .GT. UX1N) THEN
              CALL SZSTNI(ITPAT1)
            ELSE
              CALL SZSTNI(ITPAT2)
            END IF

            CALL SZOPTV
            CALL SZSTTV(VX2N, VYN)
            CALL SZSTTV(VX1N, VYN)
            CALL SZSTTV(VXC , VYC )
            CALL SZSTTV(VX2N, VYN)
            CALL SZCLTV
          END IF
        END IF
   20 CONTINUE

      CALL SWOCLS('UHDIFZ')

      END
