C COPYRIGHT (C) 1983 GLENN EVERHART
C PERMISSION IS GIVEN TO ANYONE TO USE, DISTRIBUTE, OR COPY THIS
C PROGRAM FREELY BUT NOT TO SELL IT COMMERICALLY.
C	PCC GRAF
C  NOTE: REQUIRES LUN 4 FOR TERMINAL OUTPUT AND LUN 5 FOR
C  TERMINAL INPUT.
C (GHASP USES 6 FOR LP:)
C 
C GRAPHICS INTERFACE AND OUTPUT FROM PCC SPREADSHEET
C
C  GLENN EVERHART, 23-JAN-83
C
C SYNTAX AND USAGE:
C
C  This program is designed to allow an interactive user to enter
C a single command line to the program which it will parse (using
C the special version of VARSCN in GVARSCN) and allow graphic output
C from PortaCalc saved spread sheets. The assumption made is that
C the sheet has been saved with the PPN or PDN command. The filename
C must appear in the command line and variables in the file (named as
C though the cursor had been in cell A1 when the PPN / PDN was done)
C may be histogrammed or scatterplotted against each other.
C
C The GHASP routine (a FORTRAN plot package for ordinary printers)
C will be used for this version.
C
C Input syntax:
C  NN or LL filename.ext V1:V2 [c] V3:V4 +switches
C
C  where
C
C  an L in columns 1 or 2 takes log of 1st or 2nd range numbers (base 10),
C
C  filename appears at the start of the command line after a space
C  and with a space following it and is a valid RSX or VMS file spec.
C
C  V1:V2 and V3:V4 are ranges. V3:V4 is optional and its presence implies
C  a scatter plot. These ranges must be either a row or a column or part
C  of them. If only range V1:V2 is present, a histogram will be done using
C  the Scale option of GHASP to fit the plot onto a page. The plot will be
C  set up for 100 bins horizontal, 50 vertical.
C    If the V3:V4 range exists, the character Q in the [c] position (the []
C  are required) will result in a "density" plot in which the program will
C  attempt to print darker in filled bins. This is crude and the default is
C  to use a 2 digit number. Again, plot size will be scaled to 50 by 50
C  bins.
C
	LOGICAL*1 LINE(128),KLET,LLET
	INTEGER*4 NDLTY,NPLTS,MA(1000)
	INTEGER*4 NDIM,TITLE(19)
	LOGICAL*1 LTITL(76)
	LOGICAL*1 LLA,LLB
	EQUIVALENCE(TITLE(1),LTITL(1))
	INTEGER*2 IXTR
	COMMON/IXTR/IXTR
	INTEGER*4 NBINX,NBINY
	REAL*4 XMIN,YMIN,DX,DY
	INTEGER*2 KK,LS1,LS2,LQ
	LOGICAL*1 IONM(50)
	LOGICAL*1 IONM1(52)
	EQUIVALENCE(IONM(1),IONM1(1))
	REAL*4 VEC1(300),VEC2(300)
	COMMON/EXTRA/NDLTY,NPLTS,MA
	COMMON/PLOTS/NDIM,XMIN,YMIN,DX,DY,NBINX,NBINY,TITLE
	DATA RS/4H   S/
	DATA RV/4H   V/
	DATA RQ/4H   Q/
	DATA RH/4H   H/
	IXTR=0
	CALL ASSIGN(4,'TI:')
	CALL ASSIGN(5,'TI:')
100	NDLTY=1000
	NPLTS=1
c	CALL ASSIGN(6,'LP:')
	ITTFG=0
	WRITE(4,8000)
8000	FORMAT('$Give output dataset name>')
	READ(5,2)IDL,IONM
	IONM(IDL+1)=0
	CALL ASSIGN(6,IONM)
C SEE IF HE USED A TERMINAL NAME. IF SO FLAG SMALL IMAGES.
	IF((IONM(1).EQ.'T'.OR.IONM(1).EQ.'t').AND.
     1  IONM(3).EQ.':')ITTFG=1
	IF(ITTFG.EQ.1)IXTR=1
	WRITE(4,1)
1	FORMAT('$Enter plot command>')
	READ(5,2)LQ,LINE
2	FORMAT(Q,128A1)
	LOGF1=0
	LOGF2=0
	NBFG1=0
	IF(LINE(1).EQ.'P')NBFG1=1
C NBFG1 MAKES YMIN=0. THUS IF CMD STARTS WITH PP PLOT IS POSITIVE
C DITTO NBFG2
	NBFG2=0
	IF(LINE(2).EQ.'P')NBFG2=1
	IF(LINE(1).EQ.'L')LOGF1=1
	IF(LINE(2).EQ.'L')LOGF2=1
	LLA=LINE(1)
	LLB=LINE(2)
C 1ST 2 CHARS SAY LOG OR LOGLOG (IF 2DIM GRAPH)
C LOGF1 WILL TAKE LOG OF VEC1 AND LOGF2 WILL TAKE LOG OF VEC2
C IF SET.
C NOTE THAT THIS ALSO TAKES ABS OF NUMBER.
	LQ=LQ+1
	LQ=MIN0(128,LQ)
	LINE(127)=0
	LINE(128)=0
	LINE(LQ)=0
c
c process switches.
c switches are after trailing + sign
c
c +hnnn = set height
c +wnnn = set width
	nhov=0
	nwov=0
	KK=INDEX(LINE,'+')
	IF(KK.GT.50)GOTO 6000
C SKIP THIS AREA IF NO SWITCHES ARE FLAGGED
	LINE(KK)=0
C SKIP SWITCHES IN LATER PROCESSING.
c since we look for a number, first try to decode the number as a
c 3 digit one...
	kkk=kk+2
	lend1=kkk+30
	call gn(kkk,lend1,num1,line)
c num1 can be h or w depending on line(kk+1)
	if(line(kk+1).eq.'h'.or.line(kk+1).eq.'H')nhov=num1
	if(line(kk+1).eq.'w'.or.line(kk+1).eq.'W')nwov=num1
C GN RETURNS ITS LAST CHAR AFTER THE # IN ITS 1ST ARG.
	IKK=INDEX(LINE(KK+1),'+')
	IF(IKK.GT.30)GOTO 6000
	KKK=IKK+KK
c 2nd + sign flags 2nd switch...
	kk=kkk+2
	lend1=kk+30
	call gn(kk,lend1,num1,line)
	if(line(kkk+1).eq.'h'.or.line(kkk+1).eq.'H')nhov=num1
	if(line(kkk+1).eq.'w'.or.line(kkk+1).eq.'W')nwov=num1
c that should do it...
6000	CONTINUE
	LS1=INDEX(LINE,32)
C CALL OUR PORTACALC INDEX FCN
	KK=LS1+1
	LS2=INDEX(LINE(KK),32)
	IF(LS1.GT.40.OR.LS2.GT.40)WRITE(4,25)LS1,LS2,LQ
25	FORMAT(' Spaces not seen. Find spaces at ',3I6,
     1  /,' Usage: PCG file V1:V2 [C] V3:V4[+hnnnwnnn] ')
	IF (LS1.GT.40.OR.LS2.GT.40)GOTO 100
	LINE(LS2+LS1)=0
	CALL ASSIGN(1,LINE(LS1+1))
C SET UP FILE 1 TO READ SAVED FILE FROM SHEET
	LINE(LS2+LS1)=32
	LX=LS1+LS2+1
C SCAN THE REST STARTING AT LX
C GRAB OFF OUR ARGUMENTS FIRST, THEN GET ON WITH THE PLOTS.
	CALL PLOT(0.,0.,-1,0)
C HOWEVER INITIALIZE PLOT ARRAY EARLY ON.
	K1=LX
	K2=110
	CALL GVSCAN(LINE,K1,K2,LSTCHR,ID1,ID2,IVLD)
	IF (IVLD.NE.0)GOTO 150
	WRITE(4,3)
3	FORMAT(' First variable invalid. Try again.')
	GOTO 100
150	CONTINUE
	IF(LINE(LSTCHR).EQ.':')GOTO 160
	WRITE(4,4)
4	FORMAT(' Colon missing in first range.')
	GOTO 100
160	CONTINUE
	K1=LSTCHR+1
	K2=110
	CALL GVSCAN(LINE,K1,K2,LSTCR,ID1B,ID2B,IVLD)
	IF (IVLD.NE.0)GOTO 164
	WRITE(4,5)
5	FORMAT(' 2nd variable in 1st range invalid.')
	GOTO 100
164	CONTINUE
	IF(ID1.NE.ID1B.AND.ID2.NE.ID2B)GOTO 166
	GOTO 167
166	WRITE(4,6)
6	FORMAT(' Variable pair not in a row or column together')
	GOTO 100
167	CONTINUE
	KCR=1
	IF(LINE(LSTCR).EQ.'[')GOTO 170
	LSTCR=LSTCR+1
	IF(LINE(LSTCR).EQ.'[')GOTO 170
169	WRITE(4,7)KCR
7	FORMAT(' Invalid format of [c] character ',I5)
	GOTO 100
170	LSTCR=LSTCR+1
	KCR=2
	IF(LINE(LSTCR).EQ.']')GOTO 169
	KLET=LINE(LSTCR)
	LSTCR=LSTCR+1
C SCAN OVER NEXT ']' NOW
	KCR=3
	IF(LINE(LSTCR).NE.']')GOTO 169
	LSTCR=LSTCR+1
C IF WE PICK UP A VALID VARIABLE HERE, ALL'S WELL. OTHERWISE WE HAVE
C A HISTOGRAM AND WE'RE DONE (FOR THIS VERSION ANYHOW)
	K1=LSTCR
	K2=110
	NDIM=1
	CALL GVSCAN(LINE,K1,K2,LSTT,ID1C,ID2C,IVLD)
	IF(IVLD.EQ.0)GOTO 200
C IF HERE, THERE HAS TO BE 1 MORE VARIABLE DECODED AND TESTED.
	IF(LINE(LSTT).EQ.':')GOTO 175
	WRITE(4,8)
8	FORMAT(' Invalid second variable range.')
	GOTO 100
175	CONTINUE
	K1=LSTT+1
	K2=110
	CALL GVSCAN(LINE,K1,K2,LSTCC,ID1D,ID2D,IVLD)
	IF(IVLD.NE.0)GOTO 180
	WRITE(4,9)
9	FORMAT(' Invalid 2nd variable of 2nd range')
	GOTO 100
180	CONTINUE
C NOW ALL DECODED.
	NDIM=2
C NOW WE HAVE SET UP THE DIMENSION OF OUR PLOT.
200	CONTINUE
C NOW IT'S POSSIBLE TO READ IN THE FILE ONCE TO NORMALIZE IT, THEN
C REWIND AND READ AGAIN TO PLOT IT.
	XMIN=99.E10
	YMIN=99.E10
	IF(NBFG1.NE.0)YMIN=0.
	IF(NBFG2.NE.0)XMIN=0.
C SET TERRIBLY LARGE X,Y MINS UNLESS POSITIVE PLOT, THEN START AT 0.
C (WE'LL FIX THEM UP!)
	XMAX=-99.E10
	YMAX=-99.E10
C SET UP MAXIMA ALSO IN BOGUS WAY. THIS ENSURES WHATEVER WE GET
C WILL BE BETTER THAN OUR "FIRST GUESS".
C  INSERT TITLE AS OUR COMMAND LINE, FOR INTERNAL DOCUMENTATION.
C (LX THRU END)
	DO 11 N=1,78
11	LTITL(N)=32
	LX=LS1
C INCLUDE FILENAME TOO.
	DO 12 N=1,50
	LTITL(N)=LINE(LX)
	IF(LX.GT.76)GOTO 13
12	LX=LX+1
C FLAG LOG SCALE FLAGS IN TITLE
	IF (LLA.EQ.'L')TITLE(18)='LOGX'
	IF (LLB.EQ.'L')TITLE(19)='LOGY'
13	READ(1,10)LINE
10	FORMAT(128A1)
	IF(NDIM.EQ.2)GOTO 17
	XMIN=0.
	XMIN2=0.
	ICNT=0
17	CONTINUE
C IGNORE TITLE, JUST READ IT IN, THEN FORGET IT.
	IV1=1
	IV2=1
220	CONTINUE
C NOTE WE READ IN THE NUMBER IN NUMERIC FORMAT. EASIER THAT WAY.
	IRRW=0
	ICCL=0
	READ(1,14,END=250,ERR=224)LET1,IRRW,ICCL,XYVAL
14	FORMAT(A1,I5,X,I5,X,E50.35)
224	READ(1,15,END=250,ERR=225)LFVLD,(LINE(IV),IV=120,128),KKTYP
15	FORMAT(I3,X,9A1,X,I5)
225	CONTINUE
C READS IN AN ENTRY OF SAVED SHEET. TEST IF IN OUR RANGE.
	IF(IRRW.GE.ID1.AND.IRRW.LE.ID1B.AND.ICCL.GE.ID2.AND.ICCL
     1  .LE.ID2B)GOTO 221
	IF(NDIM.NE.2)GOTO 223
	IF(IRRW.GE.ID1C.AND.IRRW.LE.ID1D.AND.ICCL.GE.ID2C
     1  .AND.ICCL.LE.ID2D)GOTO 222
	GOTO 223
221	CONTINUE
C NUMBER IS IN FIRST RANGE TO PLOT. FIGURE IT OUT.
	IF(LOGF1.NE.0.AND.XYVAL.NE.0)XYVAL=ALOG10(ABS(XYVAL))
	VEC1(IV1)=XYVAL
	IV1=IV1+1
	IF(NDIM.EQ.1)ICNT=ICNT+1
	IF(NDIM.EQ.1)XMAX=ICNT
	IF(NDIM.EQ.1)GOTO 18
	IF(XYVAL.LT.XMIN)XMIN=XYVAL
	IF(XYVAL.GT.XMAX)XMAX=XYVAL
	GOTO 223
18	CONTINUE
	IF(XYVAL.LT.YMIN)YMIN=XYVAL
	IF(XYVAL.GT.YMAX)YMAX=XYVAL
	VEC2(IV2)=FLOAT(ICNT)
	IV2=IV2+1
	GOTO 223
222	CONTINUE
	IF(NDIM.EQ.1)GOTO 223
	IF(LOGF2.NE.0.AND.XYVAL.NE.0)XYVAL=ALOG10(ABS(XYVAL))
C NUMBER IS IN SECOND RANGE SELECTED.
C KNOW IT'S A Y COORD HERE.
	VEC2(IV2)=XYVAL
	IV2=IV2+1
	IF(XYVAL.LT.YMIN)YMIN=XYVAL
	IF(XYVAL.GT.YMAX)YMAX=XYVAL
223	CONTINUE
	GOTO 220
250	CONTINUE
C NOW MINIMA,MAXIMA ALL SET UP.
	IF(XMIN.GE.XMAX.OR.YMIN.GE.YMAX)CALL EXIT
C EXIT IF NOTHING IS THERE TO GRAPH.
	XRANGE=XMAX-XMIN
	YRANGE=YMAX-YMIN
C
	AMXRG=100.
	AMYRG=50.
	IF(ITTFG.EQ.1)AMXRG=60.
	IF(ITTFG.EQ.1)AMYRG=20.
	XNUM=AMXRG
	IF(NDIM.EQ.1.AND.(XRANGE.LT.AMXRG))XNUM=XRANGE
	YNUM=AMYRG
	IF(NDIM.EQ.2)XNUM=AMYRG
C HANDLE SWITCHES THAT OVERRIDE HEIGHT AND WIDTH TO USE.
	IF(NHOV.NE.0)YNUM=NHOV
	IF(NWOV.NE.0)XNUM=NWOV
	DX=XRANGE/XNUM
	DY=YRANGE/YNUM
	IF(.NOT.(NDIM.EQ.1.AND.DX.LT.1))GOTO 19
C DX RESET OVER-RIDDEN BY +W SWITCH.
	IF(NWOV.EQ.0)DX=1.
19	CONTINUE
	NBINX=XNUM
	NBINY=YNUM
	CALL PLOT(RV,0.,0,1)
C INITIALIZE PLOT
C NDIM, MINIMA, MAXIMA ALL SET UP NOW.
C
C WE SAVED VALUES IN VEC1,VEC2 AND PLOT THAT WAY.
C  ALSO NOTE BOTH ALWAYS EXIST.
C
	LENGTH=MIN0(IV1,IV2)
C SAME IF NDIM=1
	DO 20 N=1,LENGTH
	IF(NDIM.EQ.1)CALL PLOT(VEC2(N),VEC1(N),1,1)
	IF(NDIM.NE.1)CALL PLOT(VEC1(N),VEC2(N),1,1)
20	CONTINUE
C PLOT IT OUT NOW
C CHOOSE OPTION FOR FORMAT (SCALE, VARY HEIGHT, SHADE)
	X=RS
	IF(KLET.EQ.'V')X=RV
	IF(KLET.EQ.'Q')X=RQ
	IF(KLET.EQ.'H')X=RH
	CALL PLOT(X,0,2,1)
	CALL EXIT
	END
