C
C   Copyright (c) 1990 by Dwight Meglan     
C   
      SUBROUTINE DrawGraph( GrNum,VpXmin,VpXmax,VpYmin,VpYmax,ratio )
      implicit none

      include 'tel_cons.inc'
      include 'tel_strc.inc'
      include 'tel_grph.inc'

      include 'vogle.fi'

      integer*4 GrNum
      real*4    VpXmin,VpXmax,VpYmin,VpYmax,ratio
      
      CHARACTER AXISNUM*7,EventName(4)*3,EventName2*4
      integer*4 i,j,k,numchar,x,y,NumFilesDone,FilesDone(10),NumEvent,NumPlts,
     &          side,rt,lf,FileNum,NumDec(2)
      REAL*4    LENGTH,yd,xo,yo,xnum,inc,xinc,yinc,ynum,xl,yl,LgndPos(2,9),
     &          DataMax(2),DataMin(2),DataDel(2),Vp2Xmin,Vp2Xmax,Vp2Ymin, 
     &          Vp2Ymax,ratio2,chsize(2),xp,yp
      LOGICAL*4 DONE,skip,error

      data x,y,rt,lf / 1,2,1,2 /
      data LgndPos / 0.2,0.3, 0.45,0.3, 0.6,0.3,
     &               0.2,0.5, 0.45,0.5, 0.6,0.5,
     &               0.2,0.7, 0.45,0.7, 0.6,0.7 /
      data EventName / 'RHS','LHS','RTO','LTO' /
c                                                    
c     First check the data that is to be plotted to make sure that it is
c     valid.  Invalid data occurs when all the values are the same in the
c     x or y directions.  If it is OK then either autoscale the graph limits
c     or use the manual axis scales in the GROPT structure.
c       
      if ( .not. GROPT(GrNum).ManScale ) then
        do i= x, y
          if ( abs(GD(GrNum).Max(i)-GD(GrNum).Min(i)) .lt. 1.0e-05 ) then
            if ( abs(GD(GrNum).Max(i)) .lt. 1.0e-05 ) then
              DataMax(i)= GD(GrNum).Max(i) + 0.05
              DataMin(i)= GD(GrNum).Min(i) - 0.05
            else
              DataMax(i)= 1.01*GD(GrNum).Max(i)
              DataMin(i)= 0.99*GD(GrNum).Min(i)
            end if                 
          else                          
            DataMax(i)= GD(GrNum).Max(i)
            DataMin(i)= GD(GrNum).Min(i)
          end if
          DataDel(i)= DataMax(i) - DataMin(i)
        end do
        if ( GROPT(GrNum).SimpleAutoScale ) then
          do i= 1, 2
            call SimpleScaleData( DataMin(i),DataMax(i),GROPT(GrNum).NumDiv(i) )
            DataDel(i)= DataMax(i) - DataMin(i)
          end do
        else
c          call ScaleData( DataMin(x),DataMax(x),GROPT(GrNum).NumDiv(x) )
c          call ScaleData( DataMin(y),DataMax(y),GROPT(GrNum).NumDiv(y) )
          do i= 1, 2
            call LooseLabel( DataMin(i),DataMax(i),GROPT(GrNum).NumDiv(i),
     &                       DataDel(i),NumDec(i) )
            if ( DataMax(i) .lt. DataMin(i) ) call swapr( DataMin(i),DataMax(i) )
            if ( abs(DataMax(i)-DataMin(i)) .lt. 1.0e-05 ) then
              if ( abs(DataMax(i)) .lt. 1.0e-05 ) then
                DataMax(i)= DataMax(i) + 0.05
                DataMin(i)= DataMin(i) - 0.05
              else
                DataMax(i)= 1.01*DataMax(i)
                DataMin(i)= 0.99*DataMin(i)
              end if                 
            end if
            DataDel(i)= DataMax(i) - DataMin(i)
          end do
        end if
      else ! use manual scale limits
        do i= x, y
          if ( abs(GROPT(GrNum).ManMax(i)-GROPT(GrNum).ManMin(i)) .lt. 1.0e-5 ) then
            if ( abs(GROPT(GrNum).ManMax(i)) .lt. 1.0e-5 ) then
              DataMax(i)= GROPT(GrNum).ManMax(i) + 0.05
              DataMin(i)= GROPT(GrNum).ManMin(i) - 0.05
            else
              DataMax(i)= 1.01*GROPT(GrNum).ManMax(i)
              DataMin(i)= 0.99*GROPT(GrNum).ManMin(i)
            end if                    
          else
            DataMax(i)= GROPT(GrNum).ManMax(i)
            DataMin(i)= GROPT(GrNum).ManMin(i)
          end if  
          DataDel(i)= DataMax(i) - DataMin(i)
        end do                       
      end if
      call dviewport( VpXmin,VpXmax,VpYmin,VpYmax )
      ratio2= abs(VpYmax-VpYmin)/abs(VpXmax-VpXmin)
      CALL ortho2(0.0,1.0,0.0,ratio2)
      call clipping(.true.)
C                              
C       DRAW GRAPH BORDER
C                     
        if ( .not. GROPT(GrNum).UsePostPrint ) CALL COLOR(6)
        CALL MOVE2(0.1875,0.125*ratio2)
        CALL RDRAW2(0.75,0.0)
        CALL RDRAW2(0.0,0.75*ratio2)
        CALL RDRAW2(-0.75,0.0)
        CALL RDRAW2(0.0,-0.75*ratio2)
C
C       DRAW X AXIS TICK MARKS
C                             
        inc= 0.75/float(GROPT(GrNum).NumDiv(x))
        do i= 1, GROPT(GrNum).NumDiv(x)-1
          CALL RMOVE2(inc,0.01)
          CALL RDRAW2(0.0,-0.01)
        end do
C                               
C       DRAW Y AXIS TICK MARKS
C
        CALL MOVE2(.1875,0.125*ratio2)
        inc= (0.75*ratio2)/float(GROPT(GrNum).NumDiv(y))
        do i= 1, GROPT(GrNum).NumDiv(y)-1
          CALL RMOVE2(0.01,inc)
          CALL RDRAW2(-0.01,0.0)
        end do              
C
C       DRAW GRAPH TITLE AND SUBTITLE plus graph label
C
        chsize(x)= 0.01875
        chsize(y)= 0.01875
        call dfont(GROPT(GrNum).Font)
        call textsize(chsize(x),chsize(y))
        call bottomjustify
	call xcentertext()
        call textang(0.0)
        CALL MOVE2(0.5625,0.953*ratio2)
        CALL dstrg(GD(GrNum).Title)
        CALL MOVE2(0.5625,0.90*ratio2)
        CALL DSTRG(GD(GrNum).SubTitle)
        if ( GROPT(GrNum).GrLabelFlg ) then
          call leftjustify()
          call textsize(0.8*chsize(x),0.8*chsize(y))
          CALL MOVE2(0.05,0.015*ratio2)
          CALL DSTRG(GD(GrNum).GrLabel)
          call textsize(chsize(x),chsize(y))
        end if                   
C                                         
C       DRAW X AND Y AXIS LBLS
C
        CALL MOVE2(chsize(x),0.5*ratio2)
        call xcentertext()
        call ycentertext()
        CALL TEXTANG(90.0)                               
        CALL DSTRG( GD(GrNum).Ytitle )
        if ( 0.125*ratio2 - 4.5*chsize(y) .lt. 0.0 ) then
          CALL MOVE2(0.5625, chsize(y))
        else
          call move2(0.5625, 0.125*ratio2-4.0*chsize(y))
        end if
        call xcentertext()
        call bottomjustify()
        CALL TEXTANG(0.0)
        CALL DSTRG( GD(GrNum).Xtitle )   
C                             
C       DRAW Y AXIS SCALE
C                           
        YINC= (DataMax(y)-DataMin(y))/float(GROPT(GrNum).NumDiv(y))
        CALL MOVE2(0.1875-2.0*chsize(x),0.875*ratio2)
        call rightjustify()
        call ycentertext()
        CALL TEXTANG(0.0)
        inc= (-0.75*ratio2)/float(GROPT(GrNum).NumDiv(y))
        YNUM= DataMax(y)                              
        do i= 1, GROPT(GrNum).NumDiv(y)+1
          call GenNumChar( ynum,axisnum )
          CALL DSTRG(AXISNUM)
          YNUM= YNUM-YINC   
          CALL MOVE2(0.1875-2.0*chsize(x),0.875*ratio2+i*inc)
        end do
c                     
c      Draw x axis          
c                             
        XINC= (DataMax(x)-DataMin(x))/float(GROPT(GrNum).NumDiv(x))
        XNUM= DataMin(x)
        inc= 0.75/float(GROPT(GrNum).NumDiv(x))
        call xcentertext()
        call topjustify()
        CALL TEXTANG(0.0)
        yp= 0.125*ratio2-0.5*chsize(y)
        xp= 0.1875
        CALL MOVE2(xp,yp)
        do i= 1, GROPT(GrNum).NumDiv(x)+1
          call GenNumChar( xnum,axisnum )
          call dstrg(axisnum)
          XNUM= XNUM+XINC
          xp= xp + inc
          CALL MOVE2(xp,yp)
        end do                              
C                                                 
C     DRAW THE LEGEND LBLS     
C                             
        IF ( GROPT(GrNum).LgndFlg ) THEN
          xl= LgndPos(x,GROPT(GrNum).LgndPosNum)
          yl= LgndPos(y,GROPT(GrNum).LgndPosNum)*ratio2
          call textang(0.0)
          call leftjustify()
          call ycentertext()
          CALL TEXTSIZE(0.75*chsize(x),0.75*chsize(y))
          do i= 1,GD(GrNum).NumPlts
            if ( .not. GROPT(GrNum).UsePostPrint ) CALL COLOR(I)
            if ( GROPT(GrNum).SymFlg ) then
              call dlstyl(0)
              CALL dmark(xl,yl,chsize(x)/2.0,chsize(y)/2.0,i)           
              CALL dmark(xl+0.0375,yl,chsize(x)/2.0,chsize(y)/2.0,i)
              CALL dmark(xl+0.0750,yl,chsize(x)/2.0,chsize(y)/2.0,i)
            end if
            if ( GROPT(GrNum).LnFlg ) then
              CALL DLSTYL(I-1)       
              call move2(xl,yl)
              CALL RDRAW2(0.075,0.0)        
              CALL RMOVE2(0.025,0.0)
            else
              call move2(xl+0.1,yl)
            end if
            if ( .not. GROPT(GrNum).UsePostPrint ) CALL COLOR(6)   
            CALL DSTRG( PD(i,GrNum).Lgnd(y) )
            yl= yl - chsize(y)
          end do                
        end if               
C                                    
C     PLOT DATA POINTS
C             
      Vp2Xmin= VpXmin  + 0.1875*abs(VpXmax-VpXmin)
      Vp2Xmax= Vp2Xmin + 0.75*abs(VpXmax-VpXmin)
      Vp2Ymin= VpYmin  + 0.125*abs(VpYmax-VpYmin)
      Vp2Ymax= Vp2Ymin + 0.75*abs(VpYmax-VpYmin)
      call dviewport(Vp2Xmin,Vp2Xmax,Vp2Ymin,Vp2Ymax)
      ratio2= abs(Vp2Ymax-Vp2Ymin)/abs(Vp2Xmax-Vp2Xmin)
      call ortho2( DataMin(x),DataMax(x),DataMin(y),DataMax(y)  )
      call clipping(.true.)
      chsize(x)= 0.01875*DataDel(x)
      chsize(y)= 0.01875*DataDel(y)/ratio2                      
c*$ifdef DEBUG
c      write(4,311) DataDel(x),DataDel(y),ratio2,Vp2Xmin,Vp2Xmax,
c     &             Vp2Ymin,Vp2Ymax,chsize(x),chsize(y)
c 311  format(' delx: ',f10.4,' dely: ',f10.4,' ratio2: ',f10.6/
c     &       ' vp2xmin: ',f10.4,' vp2xmax: ',f10.4/
c     &       ' vp2ymin: ',f10.4,' vp2ymax: ',f10.4/
c     &       ' chsizex: ',f10.4,' chsizey: ',f10.4//)
c*$endif
c
c     if option to draw x and/or y zero lines is set then do it
c             
      if ( GROPT(GrNum).XZeroLine .and.
     &     (DataMin(x) .lt. 0.0) .and. (DataMax(x) .gt. 0.0) ) then
        if ( .not. GROPT(GrNum).UsePostPrint ) call color(1)
        call dlstyl(0)
        call move2( 0.0,DataMin(y) )
        call draw2( 0.0,DataMax(y) )
      end if
      if ( GROPT(GrNum).YZeroLine .and.
     &     (DataMin(y) .lt. 0.0) .and. (DataMax(y) .gt. 0.0) ) then
        if ( .not. GROPT(GrNum).UsePostPrint ) call color(1)
        call dlstyl(0)
        call move2( DataMin(x),0.0 )
        call draw2( DataMax(x),0.0 )
      end if
c             
c    if event_flag is set indicating that x axis contains cycle percentage
c    data, then draw vertical lines at the percents where gait events occur
c    and mark these                     
c                  
      if ( GROPT(GrNum).EventOn .and. GROPT(GrNum).PctCycleLn ) then
        NumFilesDone= 0
        call textang(90.0)            
        call djust(1,1)
        if ( .not. GROPT(GrNum).UsePostPrint ) call color(1)
        call dlstyl(0)
        call textsize( chsize(y),chsize(x) )
        NumPlts= GD(GrNum).NumPlts
        if ( GROPT(GrNum).FirstGaitEvent ) NumPlts= 1
        do j= 1, NumPlts                          
          skip= .false.
          do k= 1, NumFilesDone
            if ( FilesDone(k) .eq. PD(j,GrNum).FileNum(y) ) skip= .true.
          end do
          if ( .not. skip ) then
            NumEvent= 0
            do i= 1, PD(j,GrNum).NumPnts
              if ( PltEvent(i,y,j,GrNum) .ne. 0 ) then
                NumEvent= NumEvent + 1
                call move2( PltData(i,x,j,GrNum),DataMin(y) )
                call draw2( PltData(i,x,j,GrNum),DataMax(y) )
                if ( NumEvent .lt. 5 ) then
                  call move2( PltData(i,x,j,GrNum) + 1.5*chsize(x),
     &                        DataMin(y) + chsize(y) )
                else
                  call move2( PltData(i,x,j,GrNum) - 1.25*chsize(x),
     &                        DataMin(y) + chsize(y) )
                end if
                if ( GD(GrNum).SameFile .or.
     &                GROPT(GrNum).FirstGaitEvent ) then 
                  call dstrg( EventName(PltEvent(i,y,j,GrNum)) )
                else
                  EventName2= EventName(PltEvent(i,y,j,GrNum))//
     &                         char(PD(j,GrNum).FileNum(y)+ichar('0'))
                  call dstrg( EventName2 )
                end if
              end if                                          
            end do ! i
            NumFilesDone= NumFilesDone + 1
            FilesDone(NumFilesDone)= PD(j,GrNum).FileNum(y)
          end if ! skip if file events already plotted     
        end do ! j
        call textang(0.0)                          
      end if
c                                
c     Draw Outline of foot if requested...
c
      do side= rt, lf
        if ( GD(GrNum).ShowFtOutLine(side) ) then
          if ( GD(GrNum).FtPltNum(side) .le. 0 ) then
            call DrawFootXY(side,GD(GrNum).FtOutLineGCS,
     &                           GD(GrNum).FtFileNum(side),
     &                           side,chsize,GROPT(GrNum).UsePostPrint )
          else
            call DrawFootXY(side,GD(GrNum).FtOutLineGCS,
     &                           GD(GrNum).FtFileNum(side),    
     &                           GD(GrNum).FtPltNum(side),
     &                           chsize,GROPT(GrNum).UsePostPrint )
          end if                  
        end if
      end do
c                
c     Draw Outline of force plates if requested...
c
      if ( GD(GrNum).ShowFpOutLine ) 
     &  call DrawForcePlateXY( PD(1,GrNum).FileNum(x),GROPT(GrNum).UsePostPrint )
c                                
c                                                  
      DO I= 1, GD(GrNum).NumPlts
        if ( .not. GROPT(GrNum).UsePostPrint ) CALL COLOR(I)
        if ( GROPT(GrNum).SymFlg ) then
          call dlstyl(0)
          DO J= 1, PD(i,GrNum).NumPnts
            if ( PltDataOK(j,i,GrNum) ) 
     &        CALL dmark( PltData(j,x,i,GrNum),PltData(j,y,i,GrNum),
     &                    chsize(x)/2.0,chsize(y)/2.0,i )
          END DO                               
        end if
        if ( GROPT(GrNum).EventOn .and. (.not. GROPT(GrNum).PctCycleLn) ) then
          call dlstyl(0)
          if ( .not. GROPT(GrNum).UsePostPrint ) call color(6)
          call djust(1,2)
          call textsize( 0.75*chsize(x),0.75*chsize(y) )
          do j= 1, PD(i,GrNum).NumPnts  
            if ( (PltEvent(j,y,i,GrNum) .ne. 0) .and. 
     &            PltDataOK(j,i,GrNum)                ) then
              call dmark( PltData(j,x,i,GrNum),PltData(j,y,i,GrNum),
     &                    chsize(x)/2.0,chsize(y)/2.0,i )
              call move2( PltData(j,x,i,GrNum) + 0.5*chsize(x),
     &                    PltData(j,y,i,GrNum) + 0.5*chsize(y)  )
              if ( GD(GrNum).SameFile .or.
     &              GROPT(GrNum).FirstGaitEvent ) then           
                call dstrg( EventName(PltEvent(j,y,i,GrNum)) )
              else
                EventName2= EventName(PltEvent(j,y,i,GrNum))//
     &                       char(PD(i,GrNum).FileNum(y)+ichar('0'))
                call dstrg( EventName2 )
              end if
            end if                                   
          end do     
        end if                                                   
        if ( GROPT(GrNum).LnFlg ) then
          k= 1
          do while ( (.not. PltDataOK(k,i,GrNum)) .and.
     &               (k .lt. PD(i,GrNum).NumPnts)      )
            k= k + 1
          end do
          CALL MOVE2( PltData(k,x,i,GrNum),PltData(k,y,i,GrNum) )
          CALL DLSTYL(I-1)
          if ( .not. GROPT(GrNum).UsePostPrint ) CALL COLOR(I)
          DO j= k, PD(i,GrNum).NumPnts
            if ( PltDataOK(j,i,GrNum) ) then
              CALL DRAW2( PltData(j,x,i,GrNum),PltData(j,y,i,GrNum) )
            else
              if ( j .lt. PD(i,GrNum).NumPnts )
     &          CALL MOVE2( PltData(j+1,x,i,GrNum),PltData(j+1,y,i,GrNum) )
            end if
          END DO
        end if
      END DO ! i
      RETURN   
      END
c                                       
c   Copyright (c) 1990 by Dwight Meglan
c
      subroutine Dmark( x,y,xsize,ysize,n )
      implicit none

      include 'vogle.fi'

      real*4    x,y,xsize,ysize
      integer*4 n

      integer*4 MrkNum

      MrkNum= n
      if ( (MrkNum .lt. 1) .or. (MrkNum .gt. 10) ) MrkNum= 1
      if ( MrkNum .eq. 1 ) then ! plus sign
        call move2(x-xsize/2.0,y)   
        call rdraw2(xsize,0.0)
        call move2(x,y-ysize/2.0)
        call rdraw2(0.0,ysize)
      else if ( MrkNum .eq. 2 ) then ! x 
        call move2(x-xsize/2.0,y-ysize/2.0)
        call rdraw2(xsize,ysize)
        call move2(x+xsize/2.0,y-ysize/2.0)
        call rdraw2(-xsize,ysize)
      else if ( MrkNum .eq. 3 ) then ! asterisk
        call move2(x-xsize/2.0,y)
        call rdraw2(xsize,0.0)
        call move2(x,y-ysize/2.0)
        call rdraw2(0.0,ysize)
        call move2(x-xsize/2.0,y-ysize/2.0)
        call rdraw2(xsize,ysize)
        call move2(x+xsize/2.0,y-ysize/2.0)
        call rdraw2(-xsize,ysize)
      else if ( MrkNum .eq. 4 ) then ! triangle
        call move2(x+0.5774*xsize,y-ysize/2.0)
        call rdraw2(-0.5774*xsize,ysize)
        call rdraw2(-0.5774*xsize,-ysize)
        call rdraw2( 1.1547*xsize,0.0)
      else if ( MrkNum .eq. 5 ) then ! square
        call move2(x-xsize/2.0,y-ysize/2.0)
        call rdraw2(xsize,0.0)
        call rdraw2(0.0,ysize)
        call rdraw2(-xsize,0.0)
        call rdraw2(0.0,-ysize)
      else if ( MrkNum .eq. 6 ) then ! diamond
        call move2(x,y-ysize/2.0)
        call rdraw2(xsize/2.0,ysize/2.0)
        call rdraw2(-xsize/2.0,ysize/2.0)
        call rdraw2(-xsize/2.0,-ysize/2.0)
        call rdraw2(xsize/2.0,-ysize/2.0)
      else if ( MrkNum .eq. 7 ) then ! square and plus
        call move2(x-xsize/2.0,y-ysize/2.0)
        call rdraw2(xsize,0.0)                          
        call rdraw2(0.0,ysize)
        call rdraw2(-xsize,0.0)
        call rdraw2(0.0,-ysize)
        call move2(x-xsize/2.0,y)
        call rdraw2(xsize,0.0)
        call move2(x,y-ysize/2.0)
        call rdraw2(0.0,ysize)
      else if ( MrkNum .eq. 8 ) then ! diamond and plus
        call move2(x,y-ysize/2.0)
        call rdraw2(xsize/2.0,ysize/2.0)
        call rdraw2(-xsize/2.0,ysize/2.0)
        call rdraw2(-xsize/2.0,-ysize/2.0)
        call rdraw2(xsize/2.0,-ysize/2.0)
        call move2(x-xsize/2.0,y)
        call rdraw2(xsize,0.0)
        call move2(x,y-ysize/2.0)
        call rdraw2(0.0,ysize)
      else if ( MrkNum .eq. 9 ) then ! triangle and plus sign
        call move2(x+0.5774*xsize,y-ysize/2.0)
        call rdraw2(-0.5774*xsize,ysize)
        call rdraw2(-0.5774*xsize,-ysize)
        call rdraw2( 1.1547*xsize,0.0)
        call move2(x-xsize/2.0,y)
        call rdraw2(xsize,0.0)
        call move2(x,y-ysize/2.0)
        call rdraw2(0.0,ysize)
      else ! square and asterisk
        call move2(x-xsize/2.0,y-ysize/2.0)
        call rdraw2(xsize,0.0)
        call rdraw2(0.0,ysize)
        call rdraw2(-xsize,0.0)
        call rdraw2(0.0,-ysize)
        call move2(x-xsize/2.0,y)
        call rdraw2(xsize,0.0)
        call move2(x,y-ysize/2.0)
        call rdraw2(0.0,ysize)
        call move2(x-xsize/2.0,y-ysize/2.0)
        call rdraw2(xsize,ysize)
        call move2(x+xsize/2.0,y-ysize/2.0)
        call rdraw2(-xsize,ysize)
      end if
      return
      end
c             
c   Copyright (c) 1990 by Dwight Meglan                  
c
      subroutine ScaleData( Min,Max,NumDiv )
      implicit none

      integer*4 NumDiv
      real*4    Min,Max

      integer*4 i,order,MaxIter,Iter
      real*4    rinc,NewMin,NewMax,del,limit
      logical*4 odd 

c
c     Find limits of data such that the limits of the graph and the
c     increments for the labels are asthetically pleasing.  There will be
c     NumDiv increments on each axis and hence the limits must be evenly
c     divisble by num_div to make a nice looking set of axis labels
c
      MaxIter= 100
      del= Max-Min
      if ( (abs(del) .gt. 1.0) .and. (abs(del) .lt. 10.0) ) then ! special case
        NewMin= nint(Min)
        NewMax= nint(Max)
        order= 0.0
      else    
        order= int(alog10(abs(del))) ! logarithmic order of data
        if ( abs(order) .lt. 1.0e-5 ) order= -1.0
        NewMin= (nint( Min*10.0**(-order) ))*10.0**order
        NewMax= (nint( Max*10.0**(-order) ))*10.0**order
      end if
      do while ( NewMin .gt. Min ) 
        NewMin= NewMin - 10.0**(order-1)
      end do
      do while ( NewMax .lt. Max ) 
        NewMax= NewMax + 10.0**(order-1)
      end do
c      rinc= nint( (NewMax-NewMin)/float(numdiv) )
      odd= .true.
      Iter= 1 
      limit= 10.0**(order-2)
      do while ( (amod( abs(NewMax-NewMin),float(NumDiv) ) .gt. limit) .and.
     &           (Iter .lt. MaxIter) )          
        if ( odd ) then                  
          NewMin= NewMin - 10.0**(order-1)
          odd= .false.
         else
          NewMax= NewMax + 10.0**(order-1)
          odd= .true.
        end if 
        Iter= Iter + 1
      end do ! while
      Min= NewMin !*10.0**order
      Max= NewMax !*10.0**order
      if ( abs(Max-Min) .lt. 1.0e-5 ) then
        Min= Min - 0.1
        Max= Max + 0.1                    
      end if
c
c     Trap for special case of percent cycle which always comes out
c     to min= -30.0 and max= 120.0
c          
      if ( (abs(min+30.0)  .lt. 1.0e-5) .and. 
     &     (abs(max-120.0) .lt. 1.0e-5)      ) then
        min= 0.0
        max= 100.0
      end if
      return                  
      end
c             
c   Copyright (c) 1990 by Dwight Meglan                  
c
      subroutine SimpleScaleData( Min,Max,NumDiv )
      implicit none

      integer*4 NumDiv
      real*4    Min,Max

      real*4    del

c
c     Find limits of data such that the limits of the graph are 10% greater
c     than the max,min data
c
      del= Max-Min
      Max= Max + 0.1*del
      Min= Min - 0.1*del
      return                  
      end
C
C   Copyright (c) 1990 by Dwight Meglan                       
C
      SUBROUTINE NAMELNGTH(NAME,NUMCHAR,charsize,LENGTH)
      implicit none
      
      CHARACTER*(*) NAME
      integer*4    numchar,k
      REAL*4       LENGTH,charsize
      
      K= NUMCHAR
      DO WHILE ( (K .GT. 1) .AND. (name(k:k) .eq. ' ') )
        K= K-1
      END DO
      LENGTH= K*charsize
      RETURN
      END         
c                 
c                
c      
c
c     Copyright by Dwight Meglan 1990
c                
      real*4 function VecLth( point1, point2 )
      implicit none
c
c  Function Description:
c    Calculate distance between two points        
c
c  Data passed into subroutine
c   - point1 - first point
c   - point2 - second point
c
c  Data returned from subroutine
c   - distance between points
      
      real*4    point1(3),point2(3)
      
      integer*4 i
      
      VecLth= 0.0
      do i= 1, 3                               
        VecLth= VecLth + (point1(i)-point2(i))**2
      end do
      VecLth= sqrt(VecLth)
      return             
      end                  
c                          
c                          
c       
      subroutine DrawFootXY( side,inGCS,FileNum,PltSym,chsize,NoClrFlg )
      implicit none
                   
      include 'tel_cons.inc'
      include 'tel_strc.inc'
      include 'tel_grph.inc'
      include 'tel_file.inc'
      include 'tel_names.inc'
                                                                    
      integer*4 FileNum,side,PltSym
      real*4    chsize(2)
      logical*4 inGCS,NoClrFlg

      integer*4 i,j,k,l,nout,FtPntOrder(2,4)
      real*4    FtPntLoc(3,4,2)
          
      data FtPntOrder / 1,2, 2,3, 3,4, 4,1 /                    
        
c                                                                
c     Draw the outline on the graph...
c
      if ( inGCS ) then
        if ( .not. FD(FileNum).FtOutLineGcsOK(side) ) then
          return
        else
          nout= 2
          l= 1
          do k= side, side+2, 2 
            do i= 1, 4
              do j= 1, 2
                FtPntLoc(j,i,l)= FD(FileNum).FtOutLineGCS(j,i,k)
              end do
            end do
            l= l + 1
          end do
        end if
      else
        if ( .not. FD(FileNum).FtOutLineLcsOK(side) ) then
          return
        else
          nout= 1
          do i= 1, 4
            do j= 1, 2
              FtPntLoc(j,i,1)= FD(FileNum).FtOutLineLCS(j,i,side)
            end do
          end do
        end if
      end if ! GCS or LCS
      do k= 1, nout
        call dlstyl(0)
        do i= 1, 4
          call dmark( FtPntLoc(x,i,k),FtPntLoc(y,i,k),
     &                chsize(x)/2.0,chsize(y)/2.0,PltSym )
        end do                                               
        call dlstyl(PltSym-1)
        if ( .not. NoClrFlg ) call color(PltSym)
        call move2(FtPntLoc(x,1,k),FtPntLoc(y,1,k))
        do i= 2, 4
          call draw2(FtPntLoc(x,i,k),FtPntLoc(y,i,k))
        end do              
        call draw2(FtPntLoc(x,1,k),FtPntLoc(y,1,k))
      end do
      return
      end                            
c                          
c                          
c
      subroutine DrawForcePlateXY( FileNum,NoClrFlg )
      implicit none
                   
      include 'tel_cons.inc'
      include 'tel_strc.inc'
      include 'tel_grph.inc'
      include 'tel_file.inc'
      include 'tel_names.inc'
                                                   
      include 'vogle.fi'

      integer*4 FileNum
      logical*4 NoClrFlg

      integer*4 i,j,plt,wide,lgth
      real*4    FpPntLCS(3,4),FpPntGCS(3,4)

      data wide,lgth / 1,2 /
c                                                                
c     Draw the force plate outline on the graph...
c                              
      call dlstyl(0)
      if ( .not. NoClrFlg ) call color(1)
      do plt= 1, FD(FileNum).FP.num_plt
        FpPntLCS(x,1)=  FD(FileNum).FP.plt_size(lgth,plt)/2.0
        FpPntLCS(y,1)=  FD(FileNum).FP.plt_size(wide,plt)/2.0
        FpPntLCS(x,2)= -FD(FileNum).FP.plt_size(lgth,plt)/2.0
        FpPntLCS(y,2)=  FD(FileNum).FP.plt_size(wide,plt)/2.0
        FpPntLCS(x,3)= -FD(FileNum).FP.plt_size(lgth,plt)/2.0
        FpPntLCS(y,3)= -FD(FileNum).FP.plt_size(wide,plt)/2.0
        FpPntLCS(x,4)=  FD(FileNum).FP.plt_size(lgth,plt)/2.0
        FpPntLCS(y,4)= -FD(FileNum).FP.plt_size(wide,plt)/2.0
c
c       IF the force plates are turned such that they are not aligned with
c       their long axes in the lab x direction these shapes will not be 
c       correct...
c
        do i= 1, 4
c          FpPntLCS(z,i)= 0.0
c          call PntChangeCS( FD(FileNum).FP.plt_loc(plt).LCS,
c     &                      FpPntLCS(x,i),FpPntGCS(x,i) )
          do j= 1, 2
            FpPntGCS(j,i)= FpPntLCS(j,i) + FD(FileNum).FP.plt_loc(plt).LCS(j,4)
          end do
        end do
        call move2( FpPntGCS(x,1),FpPntGCS(y,1) )
        do i= 2, 4
          call draw2( FpPntGCS(x,i),FpPntGCS(y,i) )
        end do
        call draw2( FpPntGCS(x,1),FpPntGCS(y,1) )
      end do
      return               
      end                            
c                                            
c                          
c                                              
c
c     Copyright by Dwight Meglan 1990
c
      subroutine PntChangeCS( trans_matrix, pnt_old_cs, pnt_new_cs )
      implicit none
      
      real*4    trans_matrix(3,4), pnt_old_cs(3), pnt_new_cs(3)
      
      real*4    sum
      integer*4 new_axis,old_axis,x,z,cntr
      data x,z,cntr / 1,3,4 /
                 
      do new_axis= x, z
        sum= 0.0
        do old_axis= x, z
          sum= sum + trans_matrix(new_axis,old_axis)*pnt_old_cs(old_axis)
        end do ! old_axis
        pnt_new_cs(new_axis)= sum + trans_matrix(new_axis,cntr)
      end do ! new_axis                                      
      return
      end                                                                  
c
c
c
c     Copyright by Dwight Meglan 1990
c
c     This routine is based upon p.62 of Graphics Gems by A. Glassner
c 
      subroutine LooseLabel( min,max,nticks,d,nfrac )
      implicit none

      integer*4 nticks,nfrac
      real*4    min,max,d

      real*4    graphmin,graphmax,range,NiceNum,Floor,Ceiling

      range= NiceNum( max-min,.false. )
      d = NiceNum( range/(nticks-1),.true. ) ! increment
      graphmin= floor(min/d)*d
      graphmax= ceiling(max/d)*d
      nfrac= -floor(alog10(d))      ! number of decimal places
      if ( nfrac .lt. 0 ) nfrac= 0
      min= graphmin
      max= graphmax
      return
      end
c
c
c
c     Copyright by Dwight Meglan 1990
c
c     This routine is based upon p.62 of Graphics Gems by A. Glassner
c 
      real*4 function NiceNum( x,round )
      implicit none

      real*4    x
      logical*4 round

      integer*4 exp
      real*4    f,nf,floor

      exp= floor(alog10(x))
      f= x/(10.0**exp)
      if ( round ) then
        if ( f .lt. 1.5 ) then
          nf= 1.0
        else if ( f .lt. 3.0 ) then
          nf= 2.0
        else if ( f .lt. 7.0 ) then
          nf= 5.0
        else
          nf= 10.0
        end if
      else
        if ( f .le. 1.0 ) then
          nf= 1.0
        else if ( f .le. 2.0 ) then
          nf= 2.0
        else if ( f .le. 5.0 ) then
          nf= 5.0
        else
          nf= 10.0
        end if
      end if
      NiceNum= nf*(10.0**exp)
      return
      end
c
c
c
      real*4 function floor( r )
      implicit none

      real*4   r

      if ( r .eq. int(r) ) then
        floor= r
      else if ( r .gt. 0.0 ) then
        floor= int(r)
      else
        floor= -(int(-r)+1.0)
      end if
      return
      end
c
c
c
      real*4 function ceiling( r )
      implicit none   

      real*4   r

      if ( r .eq. int(r) ) then
        ceiling= r
      else if ( r .gt. 0.0 ) then
        ceiling= 1.0 + int(r)
      else
        ceiling= -(int(-r))
      end if
      return
      end
c         
c                 
c
      subroutine DisplayBlankText( GrNum,VpXmin,VpXmax,VpYmin,VpYmax,ratio )
      implicit none
                   
      include 'tel_cons.inc'
      include 'tel_strc.inc'
      include 'tel_file.inc'           
      include 'tel_grph.inc'

      include 'vogle.fi'

      integer*4 GrNum
      real*4    VpXmin,VpXmax,VpYmin,VpYmax,ratio

      integer*4 numchar,FileNum,rt,lf,i
      real*4    length,chsize(2),ratio2,row(18),col(4),feet
      character filename*40,datetext*9,patname*40,patcomment*80

      data rt,lf,feet /1,2,3.2808/
c
c     Setup vuport and window
c      
      call dviewport( VpXmin,VpXmax,VpYmin,VpYmax )
      ratio2= abs(VpYmax-VpYmin)/abs(VpXmax-VpXmin)
      call ortho2(0.0,1.0,0.0,ratio2)
      call clipping(.true.)
C
C     draw graph title and subtitle if applicable
C
      chsize(1)= 0.01875
      chsize(2)= 0.01875
      row(1)= 0.8*ratio2
      row(2)= row(1) - 3.0*chsize(2)*ratio2
      row(3)= row(2) - 3.0*chsize(2)*ratio2
      do i= 4, 7
        row(i)= row(i-1) - 1.75*chsize(2)*ratio2
      end do
      row(8)= row(7) - 3.0*chsize(2)*ratio2           
      row(9)= row(7) - 1.75*chsize(2)*ratio2
      row(10)= row(9) - 3.0*chsize(2)*ratio2
      do i= 11, 14
        row(i)= row(i-1) - 1.75*chsize(2)*ratio2
      end do
      row(15)= row(14) - 3.0*chsize(2)*ratio2
      row(16)= row(15) - 1.75*chsize(2)*ratio2
      row(17)= row(16) - 1.75*chsize(2)*ratio2
      row(18)= row(17) - 1.75*chsize(2)*ratio2
      col(1)= 0.1
      col(2)= col(1) + 16.0*chsize(1)
      col(3)= col(2) + 11.0*chsize(1)
      col(4)= col(3) + 11.0*chsize(1)
      CALL DFONT(GROPT(GrNum).Font)
      call textsize(chsize(1),chsize(2))
      call leftjustify
      call bottomjustify
      if ( GD(GrNum).ShowBlankTitle ) then
        CALL MOVE2(col(1),0.953*ratio2)
        CALL DSTRG(GD(GrNum).Title)
      end if                            
      if ( GD(GrNum).ShowBlankSubtitle ) then
        CALL MOVE2(col(1),0.90*ratio2)
        CALL DSTRG(GD(GrNum).SubTitle)
      end if                                                    
      if ( GD(GrNum).ShowBlankName ) then
        patname= FD(GD(GrNum).ShowBlankFileNum).GP.name
        CALL MOVE2(col(1),row(15))
        CALL DSTRG(patname)
        patcomment= FD(GD(GrNum).ShowBlankFileNum).GP.comment
        CALL MOVE2(col(1),row(16))
        CALL DSTRG(patcomment)
      end if               
      if ( GD(GrNum).ShowBlankDate ) then
        datetext= FD(GD(GrNum).ShowBlankFileNum).GP.last_updated
        CALL MOVE2(col(1),row(18))
        CALL DSTRG(datetext)
      end if
      if ( GD(GrNum).ShowBlankFileName ) then
        filename= FD(GD(GrNum).ShowBlankFileNum).name
        CALL MOVE2(col(1),row(17))
        CALL DSTRG(filename)
      end if
c
c     Display time distance information is applicable...
c
      if ( GD(GrNum).ShowBlankTD1 ) then
        FileNum= GD(GrNum).ShowBlankTD1Fn
        call move2(col(1),row(1))
        call djust(1,1)
        call dstrg('Gait Distance/Time Parameters')
        call djust(3,1)
        call move2(col(2),row(2))
        call dstrg('Meas.(ft)')
        call move2(col(3),row(2))
        call dstrg('Normal(ft)')
        call move2(col(4),row(2))
        call dstrg('% Normal')
        call djust(1,1)
        call move2(col(1),row(3))
        call dstrg('Velocity')
        call move2(col(1),row(4))
        call dstrg('Stride')
        call move2(col(1),row(5))
        call dstrg('Rt Step')
        call move2(col(1),row(6))                        
        call dstrg('Lf Step')
        call move2(col(1),row(7))     
        call dstrg('Step Width')
        call move2(col(1),row(8))
        call dstrg('Cadence')
        call DrawTDTriples( row(3),col(2),
     &                      FD(FileNum).CP.velocity*feet,
     &                      FD(FileNum).CP.NormVelocity*feet,
     &                      FD(FileNum).CP.PctNormVelocity )
        call DrawTDTriples( row(4),col(2),
     &                      FD(FileNum).CP.stride_length*feet,
     &                      FD(FileNum).CP.NormStrideLength*feet,
     &                      FD(FileNum).CP.PctNormStrideLength )
        call DrawTDTriples( row(5),col(2),
     &                      FD(FileNum).CP.step_length(rt)*feet,
     &                      FD(FileNum).CP.NormStepLength(rt)*feet,
     &                      FD(FileNum).CP.PctNormStepLength(rt) )
        call DrawTDTriples( row(6),col(2),
     &                      FD(FileNum).CP.step_length(lf)*feet,
     &                      FD(FileNum).CP.NormStepLength(lf)*feet,
     &                      FD(FileNum).CP.PctNormStepLength(lf) )
        call DrawTDTriples( row(7),col(2),
     &                      FD(FileNum).CP.step_width*feet,
     &                      FD(FileNum).CP.NormStepWidth*feet,
     &                      FD(FileNum).CP.PctNormStepWidth )
        call DrawTDTriples( row(8),col(2),
     &                      FD(FileNum).CP.cadence,
     &                      FD(FileNum).CP.NormCadence,
     &                      FD(FileNum).CP.PctNormCadence )
      end if
      if ( GD(GrNum).ShowBlankTD2 ) then
        FileNum= GD(GrNum).ShowBlankTD2Fn
        call move2(col(1),row(1))                           
        call djust(1,1)
        call dstrg('Gait Timing Parameters')
        call djust(3,1)
        call move2(col(2),row(2))
        call dstrg('Time(s)')
        call move2(col(3),row(2))
        call dstrg('Cycle(%)')
        call move2(col(4),row(2))
        call dstrg('Normal')
        call djust(1,1)
        call move2(col(1),row(3))
        call dstrg('Rt TLST')
        call move2(col(1),row(4))
        call dstrg('Lf TLST')
        call move2(col(1),row(5))
        call dstrg('Rt SLST')
        call move2(col(1),row(6))        
        call dstrg('Lf SLST')
        call move2(col(1),row(7))     
        call dstrg('Rt DLS')
        call move2(col(1),row(9))
        call dstrg('LF DLS')
        call DrawTDTriples( row(3),col(2),
     &                      FD(FileNum).CP.total_time(rt),
     &                      FD(FileNum).CP.total_percent(rt),
     &                      FD(FileNum).CP.NormTotalPct(rt) )
        call DrawTDTriples( row(4),col(2),
     &                      FD(FileNum).CP.total_time(lf),
     &                      FD(FileNum).CP.total_percent(lf),
     &                      FD(FileNum).CP.NormTotalPct(lf) )
        call DrawTDTriples( row(5),col(2),
     &                      FD(FileNum).CP.sgl_time(rt),
     &                      FD(FileNum).CP.sgl_percent(rt),
     &                      FD(FileNum).CP.NormSglPct(rt) )
        call DrawTDTriples( row(6),col(2),
     &                      FD(FileNum).CP.sgl_time(lf),
     &                      FD(FileNum).CP.sgl_percent(lf),
     &                      FD(FileNum).CP.NormSglPct(lf) )
        call DrawTDTriples( row(7),col(2),
     &                      FD(FileNum).CP.dbl_time(rt),
     &                      FD(FileNum).CP.dbl_percent(rt),
     &                      FD(FileNum).CP.NormDblPct(rt) )
        call DrawTDTriples( row(9),col(2),
     &                      FD(FileNum).CP.dbl_time(lf),
     &                      FD(FileNum).CP.dbl_percent(lf),
     &                      FD(FileNum).CP.NormDblPct(lf) )
        if ( FD(FileNum).CP.first_side .eq. rt ) then
          call move2(col(1),row(10))
          call dstrg('RHS')
          call move2(col(1),row(11))
          call dstrg('LTO')
          call move2(col(1),row(12))
          call dstrg('LHS')
          call move2(col(1),row(13))
          call dstrg('RTO')
          call move2(col(1),row(14))     
          call dstrg('RHS')
        else
          call move2(col(1),row(10))
          call dstrg('LHS')
          call move2(col(1),row(11))
          call dstrg('RTO')
          call move2(col(1),row(12))
          call dstrg('RHS')
          call move2(col(1),row(13))
          call dstrg('LTO')
          call move2(col(1),row(14))     
          call dstrg('LHS')
        end if
        call DrawTDTriples( row(10),col(2),
     &                      -999.0,
     &                      FD(FileNum).CP.HS_percent(1),
     &                      FD(FileNum).CP.NormHSPct(1) )
        call DrawTDTriples( row(11),col(2),
     &                      -999.0,
     &                      FD(FileNum).CP.TO_percent(1),
     &                      FD(FileNum).CP.NormToPct(1) )
        call DrawTDTriples( row(12),col(2),
     &                      -999.0,
     &                      FD(FileNum).CP.HS_percent(2),
     &                      FD(FileNum).CP.NormHSPct(2) )
        call DrawTDTriples( row(13),col(2),
     &                      -999.0,
     &                      FD(FileNum).CP.TO_percent(2),
     &                      FD(FileNum).CP.NormToPct(2) )
        call DrawTDTriples( row(14),col(2),
     &                      -999.0,
     &                      FD(FileNum).CP.HS_percent(3),
     &                      FD(FileNum).CP.NormHSPct(3) )
      end if
      return              
      end                 
c                                       
c
c                        
      subroutine DrawTDTriples(row,col,value1,value2,value3)
      implicit none

      include 'vogle.fi'

      real*4    row,col(3),value1,value2,value3             

      integer*4 i    
      real*4    valb(3)
      character anum*8                     

      valb(1)= value1
      valb(2)= value2
      valb(3)= value3
      call djust(3,1)     
      do i= 1, 3
        if ( abs(valb(i)+999.0) .gt. 1.0e-5 ) then
          write(anum,100) valb(i)
100       format(f8.3)
          call move2(col(i),row)
          call dstrg(anum)
        end if
      end do                                     
      call djust(1,1)
      return
      end
