' VIDEO.BAS
' This is a simple database program that tracks a home video collection
'   with a sequential file and a number of general purpose subprograms.

DECLARE SUB DisplayHeader ()            ' declare subprograms
DECLARE SUB GetMenuSelection (choice%)
DECLARE SUB AddRecords ()
DECLARE SUB ViewRecords ()
DECLARE SUB PrintRecords ()
DECLARE SUB Search ()
DECLARE SUB ChangeFilename ()

COMMON SHARED filename$, tmp$           ' declare global variables
filename$ = "VIDEO.DB"                  ' default database filename
OPEN filename$ FOR APPEND AS #1: CLOSE #1  ' ensure that file exists
tmp$ = "Year:    ####        Type:  \         \ Medium:  \           \"

DisplayHeader                           ' call sub to set up screen

DO
    GetMenuSelection choice%            ' call sub to get menu choice

    SELECT CASE choice%                 ' process menu choice
        CASE 1                             ' "1" means add to database
            LOCATE 3, 47: PRINT "ADD   "   '   change mode to ADD
            AddRecords                     '   call sub to add items
        CASE 2                             ' "2" means view database
            LOCATE 3, 47: PRINT "VIEW  "   '   change mode to VIEW
            ViewRecords                    '   call sub to view items
        CASE 3                             ' "3" means print database
            LOCATE 3, 47: PRINT "PRINT "   '   change mode to PRINT
            PrintRecords                   '   call sub to print
        CASE 4                             ' "4" means search database
            LOCATE 3, 47: PRINT "SEARCH"   '   change mode to SEARCH
            Search                         '   call sub to search
        CASE 5                             ' "5" means change filename
            LOCATE 3, 47: PRINT "CHANGE"   '   change mode to CHANGE
            ChangeFilename                 '   call sub to change it
        CASE 6                             ' "6" means exit to DOS
            CLS                            '   clear screen
            SHELL                          '   exit to DOS shell
            DisplayHeader                  '   set up screen on return
        CASE 7                             ' "7" means quit program
            LOCATE 3, 47: PRINT "QUIT  "   '   change mode to QUIT
    END SELECT

LOOP UNTIL (choice% = 7)                ' repeat loop until QUIT chosen

END

SUB AddRecords

' The AddRecords subprogram adds new video items to the database.

LOCATE 25, 1                        ' print message on status line
PRINT "Enter video data.  Type END for title to quit...";
VIEW PRINT 5 TO 23                  ' enable viewport (lines 5-23)
PRINT                               ' prompt for data
PRINT "Enter new video information (without commas)"
PRINT

OPEN filename$ FOR APPEND AS #1     ' open database in append mode

' get records for file until user enters END for title

WHILE (UCASE$(title$) <> "END")
    INPUT "Item title:  ", title$   ' get item title

    IF (UCASE$(title$) <> "END") THEN   ' ...and other video info
        INPUT "   Significant actors/contributors:  ", actor$
        INPUT "   Year released:  ", year%
        INPUT "   Type of video:  ", type$
        INPUT "   Item medium type:  ", medium$
        PRINT
                                   ' write record to database file
        WRITE #1, title$, actor$, year%, type$, medium$
    END IF
WEND

CLOSE #1                            ' close file when finished

END SUB

SUB ChangeFilename

' The ChangeFilename subprogram changes the name of the current
'   database file. If the new file does not exist, it is created.
'   If no filename is specified, the default value of VIDEO.DB is
'   assumed.  Note:  This subprogram does only minimal checking
'   for a valid DOS filename -- if an invalid name is entered the
'   program will terminate.

LOCATE 25, 1: PRINT "Specify new video database filename...";
VIEW PRINT 5 TO 23                ' print message on status line

PRINT                             ' prompt for a new filename
PRINT "Use this option create a new video database file or open";
PRINT " an existing one."
PRINT
PRINT "The current directory contains the following files:"
PRINT
FILES "*.*"                       ' display all files in the current
PRINT                             '   directory to help user
PRINT "What video collection data file would you like to work with?"
PRINT "(Press Enter for default database file VIDEO.DB)"
PRINT
INPUT "Filename:  ", filename$    ' assign input to global variable

IF (filename$ = "") THEN          ' if no filename entered then
    filename$ = "VIDEO.DB"        '   set filename to VIDEO.DB
ELSE                              ' otherwise trim blank spaces off
    filename$ = LTRIM$(RTRIM$(UCASE$(filename$)))
END IF                            '   both ends of file and change to
                                  '   uppercase
OPEN filename$ FOR APPEND AS #1   ' open and close file to ensure it
CLOSE #1                          '   exists on disk (this avoids file
                                  '   error when opening in INPUT mode)
END SUB

SUB DisplayHeader

' The DisplayHeader subprogram displays the status information on the
'   first three lines of the screen and the two dividing lines that set
'   off program information window.

CLS                                      ' clear screen

COLOR 9                                  ' set color to light blue

PRINT "                         V I D E O  C O L L E C T I O N"
PRINT
PRINT "Current file:                  "; ' display status fields
PRINT "Current mode:                ";
PRINT "Current time:"

PRINT STRING$(80, "-")                   ' print dividing lines
LOCATE 24, 1: PRINT STRING$(80, "-");    '   on lines 4 and 24

COLOR 7                                  ' set color to default white

END SUB

SUB GetMenuSelection (choice%)

' The GetMenuSelection subprogram gets a menu choice from the user
'   and returns it to the main program in the choice% variable.
'   The VIEW PRINT statement is used to enable and disable the
'   viewport area (lines 5-23). The information displayed here does
'   not disturb the data in lines 1 through 4 and 24 through 25.

choice% = 0                ' initialize choice% to zero

VIEW PRINT                 ' disable viewport to update lines 3 and 25
LOCATE 3, 16: PRINT "                ": LOCATE 3, 16: PRINT filename$
LOCATE 3, 47: PRINT "SELECT"          ' set current mode to select
LOCATE 3, 76: PRINT LEFT$(TIME$, 5)   ' update current time
LOCATE 25, 1: PRINT "Type a number between 1 and 7 and press Enter...";
VIEW PRINT 5 TO 23         ' enable viewport (lines 5-23)
CLS 2                      ' clear viewport for choice prompts

PRINT                      ' prompt user for choice
PRINT "SELECT an option:"
PRINT
PRINT "  1) ADD entries to video database and save on disk"
PRINT "  2) VIEW contents of video database on screen"
PRINT "  3) PRINT video database on system printer"
PRINT "  4) SEARCH for a specific entry in video database"
PRINT "  5) CHANGE video database filename"
PRINT "  6) EXIT temporarily to DOS (type 'exit' to return)"
PRINT "  7) QUIT video database program"
PRINT
                           ' choice must be integer between 1 and 7
DO WHILE (choice% < 1) OR (choice% > 7)
    INPUT "Choice (1-7):  ", choice%
LOOP
   
CLS 2                      ' clear viewport for upcoming choice
VIEW PRINT                 ' disable viewport to clear status line
LOCATE 25, 1: PRINT STRING$(80, " ");  ' print a blank line

END SUB

SUB PrintRecords

' The PrintRecords subprogram sends the entire contents of the current
'   database file to the printer.

VIEW PRINT 5 TO 23                   ' enable viewport (lines 5-23)
PRINT                                ' display introductory message
PRINT "This option sends the contents of "; filename$;
PRINT " to your printer."

VIEW PRINT                           ' disable viewport so status
LOCATE 25, 1                         '   line can be updated
INPUT ; "Type P to print or R to return to main menu:  ", reply$
VIEW PRINT 5 TO 23                   ' enable viewport (lines 5-23)
                                     ' if user wants to print (P or p)
IF (reply$ = "P") OR (reply$ = "p") THEN
    OPEN filename$ FOR INPUT AS #1   ' open the video database file
                                     ' send header to printer
    LPRINT "------------------- Video Collection -------------------"
    LPRINT
    LPRINT "Date printed:  "; DATE$  ' print current date
    LPRINT "Filename:      "; filename$  ' print current filename
    LPRINT
    LPRINT "Collection contents:"
    LPRINT
                                     ' until file contents exhausted
    DO WHILE (NOT EOF(1))            '   read a record from file
        INPUT #1, title$, actor$, year%, type$, medium$
   
        LPRINT "Title:   "; title$   '  print each field of the record
        LPRINT "Actors:  "; actor$
        LPRINT "Year:   "; year%
        LPRINT "Type:   "; type$
        LPRINT "Medium:  "; medium$
        LPRINT
    LOOP

    LPRINT CHR$(12)               ' send formfeed character to printer
    CLOSE #1                      ' close file
END IF

END SUB

SUB Search

' The Search subprogram searches the entire database file for records
'   matching a search string entered by the user.  Search currently
'   supports searches for title and actor fields--additional topics
'   can be included by adding extra CASE statements.

num% = 0                              ' initialize catagory variable
found% = 0                            ' initialize "record found" flag

LOCATE 25, 1                          ' update status line
PRINT "Enter search category and content...";
VIEW PRINT 5 TO 23                    ' enable viewport (lines 5-23)

PRINT
PRINT "Select a search category:"     ' prompt for search topic
PRINT
PRINT "  1) Search for title"
PRINT "  2) Search for actors/contributors"
PRINT

DO WHILE (num% < 1) OR (num% > 2)     ' get number associated with
    INPUT "Category (1-2):  ", num%   '   search topic
LOOP

PRINT                                 ' get search string
INPUT "Enter string to be searched for:  ", searchStr$
PRINT
PRINT "Search results:"               ' display search results
PRINT

OPEN filename$ FOR INPUT AS #1        ' open database file

DO WHILE (NOT EOF(1))                 ' read records from file
    INPUT #1, title$, actor$, year%, type$, medium$

    SELECT CASE num% ' use num% to compare correct record field... 
    CASE 1   ' if num% = 1, determine if search string in title field
        IF INSTR(UCASE$(title$), UCASE$(searchStr$)) THEN
            found% = -1               ' if so, set found flag to true
            COLOR 2: PRINT "Title:   "; title$: COLOR 7
            PRINT "Actors:  "; actor$
            PRINT USING tmp$; year%; type$; medium$
            PRINT    ' display record fields with title field in green
         END IF
    CASE 2   ' if num% = 2, determine if search string in actor field
        IF INSTR(UCASE$(actor$), UCASE$(searchStr$)) THEN
            found% = -1               ' if so, set found flag to true
            PRINT "Title:   "; title$
            COLOR 2: PRINT "Actors:  "; actor$: COLOR 7
            PRINT USING tmp$; year%; type$; medium$
            PRINT    ' display record fields with title field in green
         END IF
    END SELECT
LOOP

CLOSE #1                              ' close file
IF (NOT found%) THEN                  ' if file not found display
    COLOR 2: PRINT searchStr$;        '   "not found" message
    COLOR 7: PRINT " not found in "; filename$; " database"
END IF

VIEW PRINT           ' disable viewport and update status line
LOCATE 25, 1: INPUT ; "Press Enter to return to main menu...", dummy$

END SUB

SUB ViewRecords
   
' The ViewRecords subprogram displays each record in the database on
'   the screen one at a time.

LOCATE 25, 1                           ' update status line
PRINT "Press Enter to continue...";

VIEW PRINT 5 TO 23                     ' enable viewport (lines 5-23)
PRINT                                  ' display opening message
PRINT "This option lets you view your video collection ";
PRINT "one record at at time."
PRINT

OPEN filename$ FOR INPUT AS #1         ' open database file

DO WHILE (NOT EOF(1))                  ' get record from file
    INPUT #1, title$, actor$, year%, type$, medium$
  
    PRINT "Title:   "; title$          ' display each field on screen
    PRINT "Actors:  "; actor$
    PRINT USING tmp$; year%; type$; medium$
   
    INPUT "", dummy$                   ' pause after each record
LOOP

CLOSE #1                               ' close file
PRINT "** End of file reached **"      ' display EOF message
INPUT "", dummy$                       ' pause before returning to
                                       '   to main program
END SUB

