'===========================================================================
' Subject: FAST TEXT VIEWER                   Date: 08/22/93 (00:00)       
'  Author: John Woodgate                      Code: QB, PDS                
'  Origin: FAST,TEXT,VIEWER                 Packet: TEXT.ABC
'===========================================================================
DEFINT A-Z  
   
' $INCLUDE: 'QB.BI'

DECLARE SUB CRTShutDown ()
DECLARE SUB DrawBox (TOPROW%, LFTCOL%, BOTROW%, RTCOL%, BORDER%)
DECLARE SUB CloseBox (TOPROW%, LFTCOL%, BOTROW%, RTCOL%)
DECLARE SUB PokeChar (row%, col1, col2, segmnt)
DECLARE SUB Initalize ()
DECLARE SUB Main ()
DECLARE FUNCTION Exist% (FIL$)
DECLARE FUNCTION CRT% ()
DECLARE SUB DrawScreen ()
DECLARE SUB CTRShutDown ()
DECLARE SUB ScrollScreen (Direction%, NumLines%, ULROW%, ULCOL%, LRROW%, LRCOL%)

DIM SHARED inregs AS RegType, outregs AS RegType
DIM SHARED chars%(1 TO 3000), box%, lastchar%
DIM SHARED boxes%(1 TO 30), ends%(1 TO 30), colors%(1 TO 3000)
DIM SHARED boxstart%, FG%, BG%, fl$, buffer$(1 TO 22)
DIM SHARED seekpos&(1 TO 10000), SaverDelay!

RANDOMIZE TIMER
CLS
PRINT "VIEWIT - Ver 2.0"
PRINT "Written by John Woodgate 1993..."
PRINT

IF COMMAND$ <> "" THEN
 fl$ = COMMAND$
ELSE
 LINE INPUT "Enter file to view :", fl$
END IF
IF Exist%(fl$) = 0 THEN
 PRINT "File not found....."
 END
END IF
IF CRT% = 0 THEN     ' 0 = Monochrome  -1 = Color
 FG% = 15: BG% = 0   ' Monochrome Color Set
ELSE
 FG% = 15: BG% = 0
END IF
SaverDelay! = 120   ' Screen Saver Delay in Seconds

CALL DrawScreen
CALL Main

SUB CloseBox (TOPROW%, LFTCOL%, BOTROW%, RTCOL%)

IF box% = 0 THEN EXIT SUB
z = boxes%(box%)
FOR a = TOPROW% TO BOTROW%
  row% = a: col1% = LFTCOL%: col2% = RTCOL%
  segmnt% = z
  CALL PokeChar(row%, col1%, col2%, segmnt%)
  z = z + (RTCOL% - LFTCOL% + 1)
NEXT a

box% = box% - 1
IF box% = 0 THEN
  lastchar% = 0
  boxstart% = 0
ELSE
  boxstart% = boxes%(box%)
  lastchar% = ends%(box%)
END IF


END SUB

FUNCTION CRT%

DEF SEG = 0
IF PEEK(&H463) = &HB4 THEN
  CRT% = 0
ELSE
  CRT% = -1
END IF
END FUNCTION

SUB CRTShutDown  
   
IF CRT% = 0 THEN
 DEF SEG = &HB000
ELSE
 DEF SEG = &HB800
END IF
BSAVE "VIEWIT.TMP", 0, 4000
COLOR 15, 0: CLS

DO
 rw% = INT(RND * 24) + 1
 cl% = INT(RND * 42) + 1
 LOCATE rw%, cl%
 PRINT "ViewIt Screen Saver, Press any key to Restore.."
 FOR Delay& = 1 TO 20000: NEXT Delay&
 CLS
LOOP WHILE INKEY$ = ""
BLOAD "VIEWIT.TMP", 0
KILL "VIEWIT.TMP"

END SUB

SUB DrawBox (TOPROW%, LFTCOL%, BOTROW%, RTCOL%, BORDER%)

z = lastchar%
IF z >= 3900 THEN
  EXIT SUB
END IF

' Save the Screen
boxstart% = z + 1
box% = box% + 1
boxes%(box%) = lastchar% + 1
FOR a = TOPROW% TO BOTROW%
   FOR b = LFTCOL% TO RTCOL%
      z = z + 1
      chars%(z) = SCREEN(a, b, 0)
      colors%(z) = SCREEN(a, b, 1)
   NEXT b
NEXT a
lastchar% = z
ends%(box%) = z

IF BORDER% = 0 THEN
  FOR a = TOPROW% TO BOTROW%
     LOCATE a, LFTCOL%
     PRINT SPACE$(RTCOL% - LFTCOL% + 1);
  NEXT a
  EXIT SUB
END IF

IF BORDER% = 1 THEN
   LOCATE TOPROW%, LFTCOL%
   st$ = CHR$(218) + STRING$(RTCOL% - LFTCOL% - 1, CHR$(196))  +CHR$(191)
   PRINT st$
   st$ = CHR$(179) + SPACE$(RTCOL% - LFTCOL% - 1) + CHR$(179)
   FOR a = TOPROW% + 1 TO BOTROW% - 1
      LOCATE a, LFTCOL%
      PRINT st$
   NEXT a
   LOCATE BOTROW%, LFTCOL%
   st$ = CHR$(192) + STRING$(RTCOL% - LFTCOL% - 1, CHR$(196)) + CHR$(217)
   PRINT st$
   EXIT SUB
END IF
IF BORDER% = 2 THEN
  LOCATE TOPROW%, LFTCOL%
  st$ = CHR$(201) + STRING$(RTCOL% - LFTCOL% - 1, CHR$(205)) + CHR$(187)
  PRINT st$
  st$ = CHR$(186) + SPACE$(RTCOL% - LFTCOL% - 1) + CHR$(186)
  FOR a = TOPROW% + 1 TO BOTROW% - 1
     LOCATE a, LFTCOL%
     PRINT st$
  NEXT a
  st$ = CHR$(200) + STRING$(RTCOL% - LFTCOL% - 1, CHR$(205)) + CHR$(188)
  LOCATE BOTROW%, LFTCOL%
  PRINT st$
  EXIT SUB
END IF
IF BORDER% = 3 THEN
  st$ = CHR$(213) + STRING$(RTCOL% - LFTCOL% - 1, CHR$(205)) + CHR$(184)
  LOCATE TOPROW%, LFTCOL%   
  PRINT st$
  st$ = CHR$(179) + SPACE$(RTCOL% - LFTCOL% - 1) + CHR$(179)
  FOR a = TOPROW% + 1 TO BOTROW% - 1
     LOCATE a, LFTCOL%
     PRINT st$
  NEXT a
  st$ = CHR$(212) + STRING$(RTCOL% - LFTCOL% - 1, CHR$(205)) + CHR$(190)
  LOCATE BOTROW%, LFTCOL%
  PRINT st$
  EXIT SUB
END IF
IF BORDER% = 4 THEN
  st$ = CHR$(214) + STRING$(RTCOL% - LFTCOL% - 1, CHR$(196)) + CHR$(183)
  LOCATE TOPROW%, LFTCOL%
  PRINT st$
  st$ = CHR$(186) + SPACE$(RTCOL% - LFTCOL% - 1) + CHR$(186)
  FOR a = TOPROW% + 1 TO BOTROW% - 1
     LOCATE a, LFTCOL%
     PRINT st$
  NEXT a
  st$ = CHR$(211) + STRING$(RTCOL% - LFTCOL% - 1, CHR$(196)) + CHR$(189)
  LOCATE BOTROW%, LFTCOL%
  PRINT st$
  EXIT SUB
END IF

END SUB

SUB DrawScreen

LOCATE , , 0: COLOR FG%, BG%: CLS
LOCATE 1, 1
PRINT SPACE$(80);
LOCATE 2, 1
PRINT CHR$(213); STRING$(78, CHR$(205)); CHR$(184);
FOR a = 3 TO 24
  LOCATE a, 1
  PRINT CHR$(179); SPACE$(78); CHR$(176);
NEXT a
LOCATE 25, 1
PRINT CHR$(212); STRING$(78, CHR$(205)); CHR$(190);
LOCATE 25, 66
PRINT CHR$(181); SPACE$(11); CHR$(198);
LOCATE 25, 68
PRINT "F1 - Help";
END SUB

FUNCTION Exist% (FIL$)

IF FIL$ = "" THEN
 Exist% = 0
 EXIT FUNCTION
END IF

OPEN FIL$ FOR BINARY AS #1
IF LOF(1) = 0 THEN
 Exist% = 0
 CLOSE #1
 KILL FIL$
ELSE
 CLOSE #1
 Exist% = -1
END IF
END FUNCTION

SUB Main

LOCATE 2, 39 - (LEN(fl$) + 2) \ 2
PRINT CHR$(181); " "; UCASE$(fl$); " "; CHR$(198);
OPEN fl$ FOR INPUT AS #1
COLOR FG%, BG%
CALL DrawBox(9, 20, 13, 60, 1)

DO
 LINE INPUT #1, dummy$
 Maxlines& = Maxlines& + 1
 IF Maxlines& < 23 THEN buffer$(Maxlines&) = dummy$
 LOCATE 11, 29: PRINT "Reading Line # "; LTRIM$(STR$(Maxlines&))
 IF Maxlines& >= 10000 THEN
  LOCATE 11, 22
  PRINT "File Exceeds 10,000 Line Limit..          "
  LOCATE 13, 33  
  PRINT " Press any key ";   
  SLEEP 0
  CALL CloseBox(9, 20, 13, 60)
  COLOR 15, 0: CLS
  END
 END IF
 seekpos&(Maxlines&) = SEEK(1) - LEN(dummy$) - 2
LOOP UNTIL EOF(1)
CLOSE #1

FOR a = 1 TO 22
 IF INSTR(buffer$(a), CHR$(12)) > 0 THEN MID$(buffer$(a),INSTR(buffer$(a), CHR$(12)), 1) = " "
NEXT a
OPEN fl$ FOR INPUT AS #1 LEN = 3072
CALL CloseBox(9, 20, 13, 60)
currline& = 1
FOR a = 3 TO 24
  LOCATE a, 2
  IF LEN(buffer$(currline&)) >= 77 THEN
   prnt$ = LEFT$(buffer$(currline&), 77)
  ELSE
   prnt$ = buffer$(currline&)
  END IF
  PRINT prnt$;
  currline& = currline& + 1
NEXT a
currline& = 1
curr% = 3 + (currline& / Maxlines&) * 21
LOCATE curr%, 80: PRINT CHR$(178);


   WHILE NOT finished
   GOSUB GetKbd
   SELECT CASE Kbd$
    CASE CHR$(0) + "G"
     GOSUB HomeKey
    CASE CHR$(0) + "O"
     GOSUB EndKey
    CASE CHR$(0) + "H"
     GOSUB ScrollUp
    CASE CHR$(0) + "P"
     GOSUB ScrollDown
    CASE CHR$(0) + "D"
     GOSUB ExitIt
    CASE CHR$(0) + ";"
     GOSUB PrintHelp
    CASE CHR$(0) + "Q"
     GOSUB PageDown
    CASE CHR$(0) + "I"
     GOSUB PageUp
    CASE CHR$(0) + "="
     GOSUB PrintIt
   END SELECT
   WEND

EXIT SUB

GetKbd:
Kbd$ = ""
start! = TIMER
GOSUB PrintBar
DO
 Kbd$ = INKEY$
 IF TIMER - start! >= SaverDelay! THEN
  CALL CRTShutDown
  start! = TIMER
 END IF
LOOP WHILE Kbd$ = ""
RETURN

ScrollUp:
IF currline& > 1 THEN
 currline& = currline& - 1
 SEEK #1, seekpos&(currline&)
 LINE INPUT #1, buffer$(1)
 IF INSTR(buffer$(1), CHR$(12)) > 0 THEN MID$(buffer$(1),INSTR(buffer$(1), CHR$(12)), 1) = " "
 CALL ScrollScreen(1, 1, 3, 2, 24, 79)
 IF LEN(buffer$(1)) >= 78 THEN
  prnt$ = LEFT$(buffer$(1), 78)
 ELSE
  prnt$ = buffer$(1)  
  prnt$ = prnt$ + SPACE$(78 - LEN(prnt$))   
 END IF
 LOCATE 3, 2
 PRINT prnt$;
END IF
RETURN


ScrollDown:
IF currline& + 21 < Maxlines& THEN
 currline& = currline& + 1
 SEEK #1, seekpos&(currline& + 21)
 LINE INPUT #1, buffer$(1)
 IF INSTR(buffer$(1), CHR$(12)) > 0 THEN MID$(buffer$(1),INSTR(buffer$(1), CHR$(12)), 1) = " "
 CALL ScrollScreen(0, 1, 3, 2, 24, 79)
 IF LEN(buffer$(1)) >= 78 THEN
  prnt$ = LEFT$(buffer$(1), 78)
 ELSE
  prnt$ = buffer$(1)
  prnt$ = prnt$ + SPACE$(78 - LEN(prnt$))
 END IF
 LOCATE 24, 2
 PRINT prnt$;
END IF
RETURN

PageUp:
IF currline& - 22 > 0 THEN
 SEEK #1, seekpos&(currline& - 22)
 currline& = currline& - 22: crln& = 1
 FOR a = 1 TO 22
   LINE INPUT #1, buffer$(a)
   IF INSTR(buffer$(a), CHR$(12)) > 0 THEN MID$(buffer$(a),INSTR(buffer$(a), CHR$(12)), 1) = " "
 NEXT a
 FOR a = 3 TO 24
   IF LEN(buffer$(crln&)) >= 78 THEN
    prnt$ = LEFT$(buffer$(crln&), 78)
   ELSE
    prnt$ = buffer$(crln&)
    prnt$ = prnt$ + SPACE$(78 - LEN(prnt$))
   END IF
   LOCATE a, 2
   PRINT prnt$;
   crln& = crln& + 1
 NEXT a
END IF
RETURN


PageDown:
IF (currline& + 21) + 21 < Maxlines& THEN
 SEEK #1, seekpos&(currline& + 22)
 currline& = currline& + 22: crln& = 1
 FOR a = 1 TO 22
   LINE INPUT #1, buffer$(a)
   IF INSTR(buffer$(a), CHR$(12)) > 0 THEN MID$(buffer$(a),INSTR(buffer$(a), CHR$(12)), 1) = " "
 NEXT a
 FOR a = 3 TO 24
   IF LEN(buffer$(crln&)) >= 78 THEN
    prnt$ = LEFT$(buffer$(crln&), 78)
   ELSE
    prnt$ = buffer$(crln&)
    prnt$ = prnt$ + SPACE$(78 - LEN(prnt$))
   END IF
   LOCATE a, 2
   PRINT prnt$;
   crln& = crln& + 1
 NEXT a
END IF
RETURN


ExitIt:
CALL DrawBox(9, 15, 13, 65, 3)
LOCATE 11, 18, 1
PRINT "(E)xit (S)hell or (R)eturn to Program :";
DO
 GOSUB GetKbd
LOOP UNTIL Kbd$ = "e" OR Kbd$ = "s" OR Kbd$ = "r"
LOCATE , , 0  
IF Kbd$ = "e" THEN   
 COLOR 15, 0
 CLS
 PRINT "If you have amy problems just contact me over"
 PRINT "FIDONet in the QuickBASIC programmers ECHO..."
 END
ELSEIF Kbd$ = "r" THEN
 CALL CloseBox(9, 15, 13, 65)
 RETURN
ELSE
 CALL CloseBox(9, 15, 13, 65)
 IF CRT% THEN
  DEF SEG = &HB800
 ELSE
  DEF SEG = &HB000
 END IF
 BSAVE "VIEWIT.TMP", 0, 4000
 COLOR 15, 0
 CLS
 PRINT "Type EXIT to Return to ViewIt..."
 SHELL
 BLOAD "VIEWIT.TMP", 0
 KILL "VIEWIT.TMP"
 RETURN
END IF

PrintHelp:
CALL DrawBox(4, 10, 20, 70, 3)
LOCATE 4, 29
PRINT CHR$(181); " Keyboard Commands "; CHR$(198);
LOCATE 6, 12
PRINT "Arrow Keys:  Up --- Scroll up one line"
LOCATE 7, 12
PRINT "             Down - Scroll down one line"
LOCATE 8, 12
PRINT "             PgDn - Scroll down one page"
LOCATE 9, 12
PRINT "             PgUp - Scroll up one page"
LOCATE 10, 12
PRINT "             Home - Move to the top of the Document"
LOCATE 11, 12
PRINT "             End -- Move to the end of the Document"
LOCATE 14, 12
PRINT "Function Keys:  F3 --- Print file"
LOCATE 15, 12
PRINT "                F10 -- Exit ViewIt"
LOCATE 20, 31
PRINT " Press any key ";
SLEEP 0
CALL CloseBox(4, 10, 20, 70)
RETURN


PrintIt:
CALL DrawBox(9, 15, 14, 65, 1)
LOCATE 11, 25
PRINT "Printing, press ESC to Cancel"
curseek& = SEEK(1)
SEEK #1, 1
total& = LOF(1)

DO
 LINE INPUT #1, X$
 printed& = printed& + LEN(X$) + 2
 LPRINT X$
 IF INKEY$ = CHR$(27) THEN
  CALL CloseBox(9, 15, 14, 65)
  LPRINT CHR$(27); "@";
  RETURN
 END IF
 FOR Delay% = 1 TO 5000: NEXT Delay%   ' Give the printer a chance to catch up
 Percent& = printed& / total& * 100
 LOCATE 13, 31
 PRINT USING "###% Complete..."; Percent&
LOOP UNTIL EOF(1)
LPRINT CHR$(12);
FOR Delay% = 1 TO 10000: NEXT Delay%
LPRINT CHR$(27); "@";
CALL CloseBox(9, 15, 14, 65)
RETURN

PrintBar:  
IF 3 + (currline& / Maxlines&) * 21 <> curr% THEN   
 LOCATE curr%, 80
 PRINT CHR$(176);
 LOCATE 3 + (currline& / Maxlines&) * 21, 80
 PRINT CHR$(178);
 curr% = 3 + (currline& / Maxlines&) * 21
END IF
RETURN

HomeKey:
IF currline& = 1 THEN RETURN
SEEK #1, seekpos&(1)
currline& = 1: crln& = 1
FOR a = 1 TO 22
 LINE INPUT #1, buffer$(a)
 IF INSTR(buffer$(a), CHR$(12)) > 0 THEN MID$(buffer$(a),INSTR(buffer$(a), CHR$(12)), 1) = " "
NEXT a
FOR a = 3 TO 24
   LOCATE a, 2: PRINT SPACE$(78);
   IF LEN(buffer$(crln&)) >= 78 THEN
    prnt$ = LEFT$(buffer$(crln&), 78)
   ELSE
    prnt$ = buffer$(crln&)
   END IF
   LOCATE a, 2
   PRINT prnt$;
   crln& = crln& + 1
NEXT a
RETURN


EndKey:
IF currline& = Maxlines& - 21 THEN RETURN
SEEK #1, seekpos&(Maxlines& - 21)
currline& = Maxlines& - 21: crln& = 1
FOR a = 1 TO 22
 LINE INPUT #1, buffer$(a)
 IF INSTR(buffer$(a), CHR$(12)) > 0 THEN MID$(buffer$(a),INSTR(buffer$(a), CHR$(12)), 1) = " "
NEXT a
FOR a = 3 TO 24
   LOCATE a, 2: PRINT SPACE$(78);
   IF LEN(buffer$(crln&)) >= 78 THEN
    prnt$ = LEFT$(buffer$(crln&), 78)
   ELSE
    prnt$ = buffer$(crln&)
   END IF
   LOCATE a, 2
   PRINT prnt$;
   crln& = crln& + 1
NEXT a
RETURN
END SUB

SUB PokeChar (row%, col1%, col2%, segmnt%)

DEF SEG = 0
segment = 0
IF PEEK(&H463) = &HB4 THEN
  DEF SEG = &HB000
ELSE
  DEF SEG = &HB800
END IF
segment = row% * 160 - 160
segment = segment + col1% * 2 - 2
colorseg% = segment + 1
FOR c = segmnt% TO segmnt% + (col2% - col1%)
  POKE segment, chars%(c)
  POKE colorseg, colors%(c)
  segment = segment + 2
  colorseg = colorseg + 2
NEXT c
DEF SEG
END SUB

SUB ScrollScreen (Direction%, NumLines, ULROW, ULCOL, LRROW, LRCOL)

' Uses the BIOS Video Interrupt
' to scroll the screen
'
IF Direction% = 0 THEN
 inregs.ax = NumLines + (6 * 256)  
ELSE   
 inregs.ax = NumLines + (7 * 256)
END IF
inregs.bx = BG% * 256
inregs.cx = (ULCOL - 1) + (256 * (ULROW - 1))
inregs.dx = (LRCOL - 1) + (256 * (LRROW - 1))
CALL INTERRUPT(&H10, inregs, outregs)
END SUB
