/************************************************************************/
/*                                                                      */
/*  Program:        SadCat.rexx                                         */
/*                                                                      */
/*  Author:         Mike Fuller                                         */
/*                                                                      */
/*  Date:           Mar 13 1993   Freeware                              */
/*                                                                      */
/*  Description:    An ARexx disk catalogue program that uses the       */
/*                  rx_intui and requester libraries, along with many   */
/*                  AmigaDOS commands, to provide an intuitive          */
/*                  interface and easy operation.                       */
/*                  A window opens on the Workbench screen with Project */
/*                  and Option menus, and Start and Finish gadgets.     */
/*                  The user selects a new or old catalogue file, using */
/*                  a file requester, and is prompted to insert disks   */
/*                  into the selected drive for cataloging. These disks */
/*                  are listed automatically in a temporary ram: file.  */
/*                  When Finish or the Save menu is selected, the file  */
/*                  is sorted, duplicate lines are removed and it is    */
/*                  saved onto disk. Multiple catalogues can be saved.  */
/*                  The program can be used via keyboard or mouse.      */
/*                  Options include the disk drive, the type of listing */
/*                  (all, files, dirs or files+dirs), and whether .info */
/*                  files are included. These options are saved to the  */
/*                  catalogue file and are used automatically if the    */
/*                  catalogue is reloaded for additions.                */
/*                  The catalogue includes the file or directory name,  */
/*                  its size (or dir) and the path including the disk.  */
/*                                                                      */
/*  Files Required: Libraries:  rx_intui.library                        */
/*                              requester.library                       */
/*                              rexxsupport.library                     */
/*                  AmigaDOS:   list                                    */
/*                              copy                                    */
/*                              sort                                    */
/*                              delete                                  */
/*                              iconx                                   */
/*                  ARexx running on the system                         */
/*                                                                      */
/*  Program Note:   To aid readability, I have used the following case  */
/*                  conventions for program functions and variables:    */
/*                                                                      */
/*                  Standard ARexx functions are in uppercase eg. CALL  */
/*                  My program functions are capitalised eg. Savefile   */
/*                  Rx_intui functions are mixed case eg. GetFIO        */
/*                  Program variables are lowercase eg. listopt         */
/*                                                                      */
/*  Acknowledgement: The rx_intui.library and requester.library are     */
/*                  copyright © by Jeff Glatt.                          */
/*                  ARexx and the rexxsupport.library are copyright ©   */
/*                  by William Hawes.                                   */
/*                  AmigaDOS and its associated commands are copyright  */
/*                  © by Commodore-Amiga Inc.                           */
/*                                                                      */
/************************************************************************/

/***  Open the required ARexx libraries ***/

IF ~SHOW('L',"rexxsupport.library") THEN
    CALL ADDLIB("rexxsupport.library",0,-30,0)
IF ~SHOW('L',"rx_intui.library") THEN
    CALL ADDLIB("rx_intui.library",0,-30,0)

/***  Set up defaults ***/

drive = 'DF0:'                  /* Floppy drive */
dupfile = 'dupfile'             /* ARexx file handle for duplicate file */
orig = 'origfile'               /* ARexx file handle for original file */
file = ''                       /* Catalogue file to save */

listopt = ' LFORMAT "%-25N %6L   %F"' /* List lformat option */
catopt = ' FILES ALL'           /* List files option */
infoopt = ' PAT ~(#?.info)'     /* List no .info option */

False = 0                       /* Boolean variables */
True = 1

start = False                   /* Program flags */
finish = False
info = False
readdisk = False

/*** Get a FileIO structure - needed for file requester ***/

fileio = GetFIO()
IF fileio == '' | fileio == 0 THEN DO
    SAY 'FileIO allocation error'
    EXIT
END

/***  Open the window on the WB screen ***/

wind = GetWindow('SADCAT by Mike Fuller',,120,30,400,160,,8+32+64+256+512+32768+65536,2+4+8+4096)
IF wind == '' | wind == 0 THEN DO
    SAY 'Window cannot be opened!'
    EXIT
END

/***  Add the menu and menu items ***/

menu=AddMenu(wind,'Project',0,)         /* Project Menu */
IF menu == '' | menu == 0 THEN DO
    err = MsgOne(wind,'Unable to open menu!')
    EXIT
END

item=AddItem(menu,'Open',4,,,'O',wind)
item=AddItem(menu,'Save',4,,,'S',wind)
item=AddItem(menu,'Quit',4,,,'Q',wind)

menu=AddMenu(wind,'Options',,)          /* Options Menu */
IF menu == '' | menu == 0 THEN DO
    err = MsgOne(wind,'Unable to open menu!')
    EXIT
END

item=AddItem(menu,'Disk Drive',,,,,wind)

sub=AddSub(item,'DF0:',1+256+8+4,14,,'0',wind)
sub=AddSub(item,'DF1:',1+8+4,13,,'1',wind)
sub=AddSub(item,'DF2:',1+8+4,11,,'2',wind)
sub=AddSub(item,'DF3:',1+8+4,7,,'3',wind)

item=AddItem(menu,'Catalogue',,,,,wind)

sub=AddSub(item,'All Files ',1+256+4,14,,'F',wind)
sub=AddSub(item,'All Dirs  ',1+4,13,,'D',wind)
sub=AddSub(item,'Dirs+Files',1+4,11,,'+',wind)
sub=AddSub(item,'All       ',1+4,7,,'A',wind)
sub=AddSub(item,'No .info  ',1+256+8+4,,,'I',wind)


/***  Add the gadgets ***/

err=SetDraw(wind,1,2,1)                 /* Colours for the gadgets */

startgad=AddGadg(wind,1,' Start ',50,130,68,14,1,1,0,)  /* Start gadget */
If startgad == '' | startgad == 0 THEN DO
    err = MsgOne(wind,'Unable to open gadget!')
    EXIT
END

fingad=AddGadg(wind,1,' Finish ',274,130,76,14,1,2,0,)  /* Finish gadget */
If fingad == '' | fingad == 0 THEN DO
    err = MsgOne(wind,'Unable to open gadget!')
    EXIT
END


/***  Print some introductory text ***/

fontptr=OpFont(,,)                      /* Needed for SetFont */

title = 'SADCAT - The Simple Arexx Disk CATaloguer'
err=SetDraw(wind,1,0,0)                 /* This double title gives */
err=Text(title,wind,30,25)              /* a shadow effect         */
err=SetDraw(wind,2,0,0)
err=Text(title,wind,29,24)

err=SetDraw(wind,1,,1)

x=10
y=40
err=Text('Select your drive and catalogue options from',wind,x,y)
y=y+10
err=Text('the Options menu, then select Open from the',wind,x,y)
y=y+10
err=Text('Project menu or click on the ',wind,x,y)
err=SetFont(wind,2,fontptr)
err=Text('Start ',wind,,)
err=SetFont(wind,0,fontptr)
err=Text('gadget to',wind,,)
y=y+10
err=Text('open a catalogue file.',wind,x,y)
y=y+20
err=Text('Follow the instructions to catalogue your disks.',wind,x,y)
y=y+20
err=Text('Click on the ',wind,x,y)
err=SetFont(wind,2,fontptr)
err=Text('Finish ',wind,,)
err=SetFont(wind,0,fontptr)
err=Text('gadget or select the Save',wind,,)
y=y+10
err=Text('menu item to save the sorted catalogue file.',wind,x,y)


/***  IDCMP loop - perform until closewindow or Quit menu selected ***/

DO WHILE finish == False
    spec=WaitMsg(wind)
    PARSE var spec class field1 field2 field3   /* Message fields */

    IF class == 0 THEN                  /*** CloseWindow selected ***/
        CALL Checkquit()

    ELSE IF class == 1 THEN             /*** Gadget selected ***/
        IF field1 == 1 THEN DO          /* Start gadget */
            IF start == False THEN      /* Fresh start */
                IF file == '' THEN      /* No file selected */
                    file=Openfile()

            ELSE DO                     /* Still on previous catalogue */
                                        /* so we confirm action from user */
                ans=MsgThree(wind,'Discard the current catalogue?',,)
                IF ans == 1 THEN
                    file=Openfile()      /* Open the files */
            END
        END

        ELSE DO                         /* Finish gadget */
            IF start == False THEN
                err=MsgOne(wind,'You haven''t even started yet!')
            ELSE DO
                CALL Savefile()         /* Sort and save the catalogue file */
                CALL Prompt('All finished.  Select quit or restart.')
            END
        END

    ELSE IF class == 2 THEN DO          /*** Menu selected ***/

        IF field1 == 0 THEN DO          /* Project menu */
            IF field2 == 0 THEN         /* Open menu item */
                file=Openfile()         /* User to select catalogue file */
            ELSE IF field2 == 1 THEN DO /* Save menu item */
                IF start == False THEN
                    err=MsgOne(wind,'You haven''t even started yet!')
                ELSE DO
                    CALL Savefile()     /* Sort and save the catalogue file */
                    CALL Prompt('All finished...quit or restart.')
                END
            END
            ELSE IF field2 == 2 THEN    /* Quit menu item */
                CALL Checkquit()
        END

        ELSE IF field1 == 1 THEN        /* Options menu */
            IF field2 == 0 THEN         /* Drive item */
                SELECT
                    WHEN field3 = 0 THEN drive = 'DF0:'
                    WHEN field3 = 1 THEN drive = 'DF1:'
                    WHEN field3 = 2 THEN drive = 'DF2:'
                    WHEN field3 = 3 THEN drive = 'DF3:'
                    OTHERWISE
                END
            ELSE IF field2 == 1 THEN    /* Catalogue item */
                SELECT
                    WHEN field3 = 0 THEN catopt = 'FILES ALL'
                    WHEN field3 = 1 THEN catopt = 'DIRS ALL'
                    WHEN field3 = 2 THEN catopt = ' '
                    WHEN field3 = 3 THEN catopt = 'ALL'
                    WHEN field3 = 4 THEN DO
                        info = ~info
                        IF info THEN
                            infoopt = ' '               /* .info wanted */
                        ELSE
                            infoopt = ' PAT ~(#?.info)' /* .info not wanted */
                    END
                    OTHERWISE
                END

    END

    ELSE IF class == 8 THEN DO          /*** Disk inserted or removed ***/

        IF field1 == 0 THEN             /* Disk inserted */
            IF readdisk THEN DO         /* Ready to read the disk */
                err=SetDraw(wind,1,0,1)
                CALL Prompt('Reading disk in drive 'drive)
                err=RedrawWind(wind,2)  /* Busy pointer */

/*  This next line is the one that does most of the work! */
/*  The rest is just window dressing.                     */

                ADDRESS COMMAND 'list >>ram:tempfile '||drive||listopt||catopt||infoopt

                err=RedrawWind(wind,1)  /* Remove busy pointer */
                err=SetDraw(wind,2,0,1)
                CALL Prompt('Insert the next disk in drive 'drive)
            END

    END

END                             /* End of IDCMP loop */

err=EndWindow(wind)             /* Close the window */

EXIT                            /* And return */


/***  Program functions ***/

Prompt:         /*** Prompts or informs the user ***/

    DO y = 40 TO 120 BY 10
        err=Erase(48,wind,x,y)  /* Erase any existing text */
    END
    err=Text(arg(1),wind,50,60)
RETURN



Openfile:       /*** Allows the user to select the catalogue file and ***/
                /*** opens a temporary file in the RAM: directory     ***/

/*  Use file requester to select catalogue file */
                
    file = FionW(fileio,'   Select a catalogue file',128+2,,'ram:',,,wind,57,11)

/*  Read the options from old file or write them to a new file */

    choice = Peek(fileIO,2,0)
    IF choice > 0 THEN DO           /* File selected */
        size = Peek(fileIO,240,2)
        IF size == 0 THEN           /* New file, so we create it */
           CALL Newfile()
        ELSE                        /* Old file, so we read options */
            IF OPEN(orig,file,'r') THEN DO
                line = READLN(orig)
                CALL CLOSE(orig)
                PARSE VAR line sadcat "+" dv "+" cat "+" inf
                IF sadcat == '  SadCat Options ' THEN DO
                    drive = dv
                    catopt = cat
                    infoopt = inf
                END
                ELSE DO
                    ans = MsgThree(wind,'Not a SadCat catalogue File.','Shall I overwrite?',)
                    IF ans THEN
                        CALL Newfile()
                END
            END

/*  Copy original or created file to temporary file in ram: */

        ADDRESS COMMAND 'copy >NIL: '||file||' ram:tempfile'
        err=SetDraw(wind,2,0,1)
        CALL Prompt('Insert a disk into drive 'drive)
        readdisk = True
        start = True
    END
RETURN file



Checkquit:      /*** Checks and confirms quit action ***/

    IF start == False THEN
        finish = True       /* Can close window and exit */
    ELSE DO
        ans=MsgThree(wind,'Really quit?',,)
        IF ans == 1 THEN DO
            ans=MsgThree(wind,'Save current catalogue?',,)
            IF ans == 1 THEN
                CALL Savefile()     /* Save catalogue */
        finish = True
        END
    END
RETURN



Savefile:       /*** Sorts and saves the catalogue file ***/

/*  Sort the temporary catalogue file */

    err=SetDraw(wind,1,0,1)
    CALL Prompt('Sorting catalogue...')
    err=RedrawWind(wind,2)
    ADDRESS COMMAND 'sort RAM:tempfile RAM:temp2file'

/*  Copy back to original catalogue file, discarding duplicate lines */

    CALL Prompt('Removing duplicate lines')
    checkline = ''
    IF OPEN(dupfile,'RAM:temp2file','r') THEN DO
        IF OPEN(orig,file,'w') THEN DO
            DO WHILE ~EOF(dupfile)
                line = READLN(dupfile)
                IF line ~= checkline & ~EOF(dupfile) THEN DO
                    CALL WRITELN(orig,line)
                    checkline = line
                END
            END
            CALL CLOSE(orig)
        END
        ELSE DO
            err = MsgOne('Could not open 'file)
            finish = True
        END
        CALL CLOSE(dupfile)
    END
    ELSE DO
        err = MsgOne('Could not open temporary file')
        finish = True
    END

/*  Delete temporary files in ram: */

    CALL Prompt('Removing temporary files.')
    address command 'delete >NIL: RAM:tempfile RAM:temp2file'
    err=RedrawWind(wind,1)
    start = False
    file = ''
RETURN


Newfile:        /*** Opens a new SadCat file, including writing options ***/

    IF OPEN(orig,file,'w') THEN DO
        CALL WRITELN(orig,'  SadCat Options +'||drive||'+'||catopt||'+'infoopt)
        CALL CLOSE(orig)
    END
    ELSE
        err = MsgOne(wind,'Could not open 'file)
RETURN
