' SORTLIST.BAS
' This program gets names and addresses from the user, sorts
'   them alphabetically by last name, and stores them in the
'   sequential file NAMES.TXT.

DECLARE SUB AddNamesToFile ()       ' declare procedures
DECLARE FUNCTION NumberOfNamesInFile% ()
DECLARE SUB CopyFileToArrays (names$(), addresses$(), numOfItems%)
DECLARE SUB ShellSort (names$(), addresses$(), numOfElements%)
DECLARE SUB CopyArraysToFile (names$(), addresses$(), numOfItems%)
DECLARE SUB DisplayNewFile ()

OPTION BASE 1                       ' set base of arrays to 1

CLS                                 ' clear screen
                                         
AddNamesToFile                      ' call sub to get input from user
numOfNames% = NumberOfNamesInFile%  ' call function to get num of names

DIM names$(numOfNames%)             ' dimension array to hold names
DIM addresses$(numOfNames%)         ' dimension array to hold addresses

' copy names and addresses in file to arrays in preparation for sorting
CopyFileToArrays names$(), addresses$(), numOfNames%

' sort names$ and addresses$ arrays alphabetically by last name
ShellSort names$(), addresses$(), numOfNames%

' copy sorted arrays back to file
CopyArraysToFile names$(), addresses$(), numOfNames%

' display new file on screen
DisplayNewFile

END

SUB AddNamesToFile

OPEN "NAMES.TXT" FOR APPEND AS #1   ' open for append so we don't lose
                                    '   any existing names and addresses
PRINT "This program adds names and addresses to the file NAMES.TXT"
PRINT "and then sorts the file alphabetically."
PRINT
PRINT "Enter names in Lastname, Firstname format.  Type END to quit."
PRINT

DO WHILE (fullName$ <> "END")       ' get names until user enters END
    LINE INPUT "  Name (Last, First):  "; fullName$
    IF (fullName$ <> "END") THEN    ' use LINE INPUT to allow commas
        PRINT #1, fullName$         ' write data to file
        LINE INPUT "  Address:  "; address$
        PRINT #1, address$
    END IF
    PRINT
LOOP

CLOSE #1

END SUB

SUB CopyArraysToFile (names$(), addresses$(), numOfItems%)

OPEN "NAMES.TXT" FOR OUTPUT AS #1   ' open for output to overwrite
                                    '   out-of-order entries
FOR i% = 1 TO numOfItems%
    PRINT #1, names$(i%)            ' write array contents to file
    PRINT #1, addresses$(i%)
NEXT i%

CLOSE #1

END SUB

SUB CopyFileToArrays (names$(), addresses$(), numOfItems%)

OPEN "NAMES.TXT" FOR INPUT AS #1   ' open for input to get file data

FOR i% = 1 TO numOfItems%
    LINE INPUT #1, names$(i%)      ' read file contents
    LINE INPUT #1, addresses$(i%)
NEXT i%

CLOSE #1

END SUB

SUB DisplayNewFile

INPUT "Press Enter to view NAMES.TXT.  ", dummy$
PRINT

OPEN "NAMES.TXT" FOR INPUT AS #1    ' open for input to get file data

DO WHILE (NOT EOF(1))               ' until end of file is reached,
    LINE INPUT #1, fullName$              ' read file data
    LINE INPUT #1, address$
    PRINT fullName$; " -- "; address$     ' and display on screen
LOOP

CLOSE #1

END SUB

FUNCTION NumberOfNamesInFile%

OPEN "NAMES.TXT" FOR INPUT AS #1   ' open for input to read file data

count% = 0                         ' counter tracks number of name-and-
                                   '   address items
DO WHILE (NOT EOF(1))              ' until end of file is reached,
    LINE INPUT #1, fullName$       '   read name and address
    LINE INPUT #1, address$
    count% = count% + 1            ' increment item counter
LOOP

CLOSE #1

NumberOfNamesInFile% = count%      ' return item count to main program

END FUNCTION

SUB ShellSort (names$(), addresses$(), numOfElements%)

' A discussion of the Shell Sort can be found in Chapter 9.
' Note that this version sorts two arrays based on the contents
'   of names$().

span% = numOfElements% \ 2

DO WHILE (span% > 0)
    FOR i% = span% TO numOfElements% - 1
        j% = i% - span% + 1
        FOR j% = (i% - span% + 1) TO 1 STEP -span%
            IF names$(j%) <= names$(j% + span%) THEN EXIT FOR

            ' swap array elements that are out of order
            SWAP names$(j%), names$(j% + span%)
            SWAP addresses$(j%), addresses$(j% + span%)
        NEXT j%
    NEXT i%

    span% = span% \ 2
LOOP

END SUB

