SET TTHRU OFF				; Make 1st to allow typeahead
; ----- List a file, with paging
;
;	This script lists a file to the screen, allowing paging back and
;	forth with PgUp, PgDn.	EOF may be searched, and the EOF search
;	may be interrupted (by any keypress).
;
;	The script's FSAVE stack is limited to 20 positions - so PgUp only
;	goes back through the last 20 pages viewed.
; ------------------------------------------------------------------------
;	This script may be FCALLED (S0 passes the file name)
; ------------------------------------------------------------------------
;	R.McG, commenced 9/88
;	       Version 2 to use SCREEN command commenced 2/90
; ----- Usages -----------------
;	S0 ------> File name being displayed
;	S2 ------> Text being searched (if Flag(1) set)
;	N0 ------> Display size in lines
;	N1 ------> Display current row #
;	N2 ------> # non-blank lines on page
;	N3 ------> Current page #
;	N4 ------> Read rtn length
;	N5 ------> Screen attribute
;	FLAG(0) -> If true, searching EOF
;	FLAG(1) -> If true, searching for text in S2
; ------------------------------
;	Initialization
;
;* TRACE ON
   LEGEND "Lister ver 2.0"
   SSIZE N0			; # lines
   SAVE 0,0 N0,79		; Save current screen
   CLEAR
   N5 = "_TEXT"			; Set text attribute (numeric result)
;
;	If file name not passed, query for one.
;
   IF NOT NULL S0 GOTO Testfile
   S1 = "File to be displayed?"
   GOSUB Ask_File		; Ask for an output file
   IF NOT SUCCESS GOTO EXIT	; If ESC'd then stop
   UPPER S0
;
;	Test for file name presence
;
Testfile:
   FOPENI S0 text
   IF NOT SUCCESS
      S0 = S0& " can't be opened"
      GOSUB Error
      GOTO EXIT
      ENDIF
;
;	Set-up for display
;
   N0 = N0-2			; # lines display
   N3 = 0			; Set page #

   LEGEND S0&": Enter PgUp, PgDn, Home, End, Esc: "
   ON ESCAPE GOSUB Exit
   SET FLAG(0) OFF		; EOF search
   SET FLAG(1) OFF		; Text search
   GOTO Page
;
;	Terminate script
;
Exit:
   RESTORE			; Restore previous screen
   IF FCALLED FRET		; If called by another
   EXIT				; else stop
;
;	Initialize for a page
;
Page:
   CLEAR
   N1 = 0			; Current disp line
   N2 = 0			; # non-blank lines
   N3 = N3+1			; Increment page #
;
;	Update the legend accordingly
;
   IF NOT FLAG(0)		; If not searching EOF
      IF NOT FLAG(1)		; If not searchin for text
	 LEGEND S0&": Enter PgUp, PgDn, Home, End, Esc, F)ind;	Page "*N3
      ELSE
	 LEGEND S0&": Searching for text; any keypress to stop;	 Page "*N3
	 ENDIF
   ELSE
      LEGEND S0&": Searching for EOF; any keypress to stop;  Page "*N3
      ENDIF
;
;	Save the position of the start of this page
;
   FSAVEI
   IF NOT SUCCESS
      FSAVEI SHIFT		; Save last 20 pos'ns
      FSAVEI
      ENDIF
;
;	Display a page's worth
;
Loop:
     FOR N1 = 0,N0,1
       READ S1 80 N4		; N4 = # chars read
       IF EOF GOTO EndFile	; Go no farther

       IF NOT NULL S1		; Skip empty lines
	  IF FIND S1 "^L"	; Top of form
	     IF NOT ZERO N2	; Current page is empty
		GOTO Wait	; Go no farther
	     ELSE
		GOTO Loop	; Don't display empty pages
		ENDIF
	     ENDIF

	  N2 = N2+1		; Count non-blank lines

	  IF NOT FLAG(0)	; If not searching EOF
	     IF NOT FLAG(1)	; If not searching text
		PRESERVE S1	; Preserve c/rs etc
		ATSAY N1,0 N5 S1; Display what was read
	     ELSE		; Searching text
		IF FIND S1 S2 GOTO Endfile ; Stop on match; Look for S2 in S1
		IF HITKEY GOTO Hitkey	   ; And searching EOF
		ENDIF
	  ELSE
	     IF HITKEY GOTO Hitkey
	     ENDIF
	  ENDIF			; End not null line
       ENDFOR
   GOTO Wait
;
;	Keypress during loop
;
Hitkey:
   KFLUSH			; Flush the keypress
;
;	End of file - reposition to last page, and then wait
;
EndFile:
   FRESTI			; Restore position to top of current page
   IF NOT FLAG(0) AND NOT FLAG(1) GOTO Wait ; If not searching for EOF or text
;
;	We were searching - display current page
;
   SET FLAG(0) OFF		; Done w/ eof search
   SET FLAG(1) OFF		; Done w/ eof search
   N3 = N3-1			; Reset Page # for redisplay
   GOTO Page			; Display last page
;
;	End of a page - wait for a keypress
;
Wait:
   IF FLAG(0) GOTO Page		; EOF search - no wait
   IF FLAG(1) GOTO Page		; Text search - no wait
;
;	Read the key and interpret
;
   KEYGET S1
   SWITCH S1
     CASE "4900"		; Pgup
       GOTO PgUp
       ENDCASE
     CASE "5100"		; PgDn
       GOTO PgDn
       ENDCASE
     CASE "4700"		; Home
       GOTO Home
       ENDCASE
     CASE "4F00"		; End
       GOTO End
       ENDCASE
     CASE "0D"			; C/r
       GOTO PgDn
       ENDCASE
     CASE "F"			; Find
       GOTO Find
       ENDCASE
     ENDSWITCH
   SOUND 100,100
   GOTO Wait
;
;	Page up (go backwards)
;
PgUp:
      FRESTOREI			; Backup current pg
      N3 = N3-1			; Reset Page # for redisplay
      FRESTOREI			; Backup one more
      IF NOT SUCCESS
	 SOUND 200,100
	 GOTO Page
	 ENDIF
      N3 = N3-1			; Reset Page # for redisplay
      GOTO Page
;
;	Page down (go forwards)
;
PgDn:
    GOTO Page
;
;	Home (rewind the file)
;
Home:
    N3 = 0			; Reset Page # for redisplay
    REWIND
    GOTO Page
;
;	End (Search EOF)
;
End:
   SET FLAG(0) ON		; Flag searching
   GOTO Page
;
;	SUBROUTINE: Find a line
;	This subroutine modifies S2 and S19
;
Find:
   S19 = "_ONESCAPE"		; Save label previously set
   ON ESCAPE GOSUB Find_Esc	; Escape out of pop-up
   SAVE	 20,10 23,70
   BOX	 20,10 23,70 (default)
   ATSAY 20,12 (default) " Find subcommand "
   ATSAY 21,12 (default) "Enter the search string (case not signifigant):"
;
;	Read a response
;
   ATGET 22,12 (default) 56 S2	; Box is 60 wide
   IF NULL S2 GOTO Find_Exit	; Skip if nothing entered
;
;	Set-up for text search
;
   SET FLAG (1) ON		; Set searching flag
   ON ESCAPE GOSUB S19		; Reset original ON ESCAPE label
   RESTORE			; Clear pop-up
   GOTO Page			; Start search from this page
;
;	Null search string
;
Find_Exit:
   ON ESCAPE GOSUB S19		; Reset original ON ESCAPE label
   RESTORE			; Clear pop-up
   GOTO Wait			; Wait for another key
;
;	Subroutine: Escape entered, or null search string
;	.. This subroutine is entered upon ESCAPE at the ATGET instruction
;	.. above.  Upon return from this subroutine, the instruction after
;	.. ATGET will be executed.  The string S2 is set to a null value to
;	.. imitate no entry, and therefore abort of the pop-up.
;
Find_Esc:
   S2 = ""			; Make a null string
   RETURN			; Return to instruction after ATGET
;
; ----- Subroutine: Ask for a script file name
;	S1 passes the prompt used
;	SUCCESS returns fact script file successfully opened
;	S0 returns the fname
;
Ask_File:
   WOPEN 10 10 13 70 (default) ASK_ESC
   ATSAY 10 12 (default) " Lister Fname "
   ATSAY 11 12 (default) S1(0:56)
   ATSAY 13 30 (default) " Press ESC to cancel "

   ATGET 12 12 (default) 54 S0; Read new fname
   WCLOSE
   ;
   ;	   Attempt to execute the entry
   ;
   LJ S0			; Left justify
   S0 = S0 &""			; Trim spaces
   UPPER S0			; Make pretty
   IF NOT NULL S0		; If nothing entered
      SET SUCCESS ON
   ELSE
      SET SUCCESS OFF
      ENDIF
   RETURN			; And done
;
; ----- Escape during a subwindow
;	.. S0 is returned null
;
Ask_Esc:
   S0 = ""			; Make a null return
   RETURN
;
; ----- Subroutine: Fatal error.  Open a window, and display a message
;	S0 passes the error message(s)
;
Error:
   WOPEN 10,10,12,70 (default) Err_Esc
   ATSAY 10,12 (default) " Lister Error "
   ATSAY 11,12 (default) S0(0:55); Max msg width 55 chars
   ATSAY 12,26 (default) " Press any key to continue "
   ;
   ;	Wait a keypress
   ;
   KEYGET S0			   ; Wait for any key
   WCLOSE
   RETURN
   ;
   ;	Escape during this screen
   ;
Err_Esc:
   RETURN
