/*
   files.c - This is Foundation's file io manager...

   Marc Wolfgram, 11May91 (Happy Birthday, Megan!)
   ----------------------------------------------------------------
 */

#pragma noroot
#pragma keep "o/files"

#include "Shell.h"
#include <stdio.h>
#include <stdfile.h>
#include <stdlib.h>
#include <string.h>
#include <usrlib.h>
#include <qdaux.h>
#include <list.h>
#include <foundation.h>

fMemberHndl     allocRootList(fMemberHndl, nameHndl, word);
fMemberHndl     allocTypeList(fMemberHndl, nameSubHndl, word);
void            GetNextWinLoc(word);
word            openWorkFile(word);
word            setupWorkFile(void);
int 			compareMembers(char *a, char *b);
void 			listInsert(char *, char, long, fMemberPtr, word);

word            rCopy1(GSString255Ptr, GSString255Ptr);
word            rCopy2(GSString255Ptr, word);

extern word fResID, pResID, vMode, c320;
extern void DrawProc(), PrefProc();
extern void SFNoResProc;
extern void SFResProc;
extern GrafPortPtr  SysWPtr;
extern WindColorPtr WColors[];
extern char *AlertArray[];
extern EventRecord   miscTaskRec;
extern char tempName[];
extern prefDataHndl prefDataH;
extern master       MasterRace[];
extern long	strings[];

int  SFGetH[]    = { 30, 120 };
/* SFGetV = 43 for 640 & 320 */

int  SFPutH[]    = { 25, 160 };
int  SFPutV[]    = { 36,  40 };

SFReplyRec2 SFreply = { FALSE, 0, 0L, 3, 0L, 3, 0L };
OpenRecGS f13OpenPB = { 12, 0, (GSString255Ptr) 0L, 1, 0 };
IORecGS   f13ReadPB;

workFileRec workList[5];	/* added scrapfile @ index 4 */
word        workIndex;

Point           winLoc[4];

/*--------------------------------------
    NewFile

    Marc Wolfgram
*/
word NewFile(void)
{
word wfd, j;
char n, s, *p;

    wfd = setupWorkFile();
    if (wfd == -1)
        return wfd;

    for (j = 0; j < 4; j++)             /* set new file as current... */
        workList[j].wFlag &= 0x7fff;
    workList[wfd].wFlag = 0xb000;           /* current, new, busy */

    n = (char) wfd + '1';
    s = (char) wfd + 'a';  /* set this up based on untitled available later */

    sprintf(workList[wfd].rootName, (char *) strings[14], s, n);
    workList[wfd].rootName[0] = (char) strlen(&workList[wfd].rootName[1]);

    workList[wfd].pathFile = NewHandle(12L, fMemID, 0x0018, 0L);
    PtrToHand(nullFile.text, workList[wfd].pathFile, 12L);
    (Pointer) p = deref(workList[wfd].pathFile);
    p[0] = 10;
    p[1] = 0;
    HUnlock(workList[wfd].pathFile);

    workList[wfd].pathName = NewHandle(14L, fMemID, 0x0018, 0L);
    PtrToHand(&nullFile, workList[wfd].pathName, 14L);

    return openWorkFile(wfd);
}

/*--------------------------------------
    OpenFile

    Marc Wolfgram
*/
word OpenFile(prefDataHndl prefH)
{
word wfd, i, j, err;
char n, *p;
Handle h;
GrafPortPtr winP;

    if (prefH) {
        SFreply.nameRef = (**prefH).fileRef;
        SFreply.pathRef = (**prefH).pathRef;
    }
    else {
    	SetPort(SysWPtr);
        SFGetFile2(SFGetH[vMode], 43, 2, 0x3001L, &SFResProc, 0L, &SFreply);

        if (SFreply.good == FALSE)
            return 0;
    }
    WaitCursor();

    wfd = setupWorkFile();
    if (wfd == -1)
        return wfd;

    h = (Handle) SFreply.nameRef;
    (Pointer) p = deref(h);
    p[3] = p[2];
    sprintf(tempName, (char *) strings[24], &p[3]);
    p[3] = 0x00;
    winP = NoteWindow(tempName);
    p += 2;
    p[0] += 2;
    pstrcpy(workList[wfd].rootName, p);
    workList[wfd].rootName[1] = ' ';
    sprintf(&workList[wfd].rootName[workList[wfd].rootName[0]], " (%u) ", wfd + 1);
    workList[wfd].rootName[0] += 4;
    p[0] -= 2;
    c1cvt(*h);
    workList[wfd].pathFile = (Handle) h;
    HUnlock(h);

    h = (Handle) SFreply.pathRef;
    (Pointer) p = deref(h);
    c1cvt(p);
    workList[wfd].pathName = (Handle) h;

    err = rCopy1((GSString255Ptr) &workFile, (GSString255Ptr) *workList[wfd].pathName);
    HUnlock(h);

    if (err) {
        CloseWindow(winP);
        InitCursor();
        AlertArray[0] = &workList[wfd].rootName[1];
        i = AlertWindow(0x0034, AlertArray, 8L);
        if (!prefH) {
            DisposeHandle(workList[wfd].pathFile);
            DisposeHandle(workList[wfd].pathName);
        }
        workList[wfd].wFlag = 0;
        return err;
    }

    for (j = 0; j < 4; j++)             /* set new file as current... */
        workList[j].wFlag &= 0x7fff;
    workList[wfd].wFlag = 0x9000;           /* current, busy */

    err = openWorkFile(wfd);
    CloseWindow(winP);
    return err;
}

/*--------------------------------------
    SaveFile - handles all the things required for Save & Save As

    Marc Wolfgram,  9/21/91 12:57:37
*/
word SaveFile(word wfd, word mode)
{
word retVal;
char n, *p;
Handle h;
GrafPortPtr winP;

    retVal = 0;

    if (mode) {  /* save as... */
	    SetPort(SysWPtr);
        SFPutFile2(SFPutH[vMode], 43, 2, 0x3004L, 1, workList[wfd].pathFile, &SFreply);

        if (SFreply.good == FALSE)
            return 1;

        WaitCursor();

        h = (Handle) SFreply.nameRef;
        (Pointer) p = deref(h);

        p += 2;
        p[0] += 2;
        pstrcpy(workList[wfd].rootName, p);
        workList[wfd].rootName[1] = ' ';
        sprintf(&workList[wfd].rootName[workList[wfd].rootName[0]], " (%u) ", wfd + 1);
        workList[wfd].rootName[0] += 4;
        SetWTitle(workList[wfd].rootName, workList[wfd].rootWinP);
        p[0] -= 2;
        c1cvt(*h);
        workList[wfd].pathFile = (Handle) h;
        HUnlock(h);

        h = (Handle) SFreply.pathRef;
        (Pointer) p = deref(h);
        c1cvt(p);
        workList[wfd].pathName = (Handle) h;
        n = (char) wfd + '1';
        HUnlock(h);

        sprintf(workList[wfd].editName, (char *) strings[19], n);
        strncat(workList[wfd].editName, &workList[wfd].rootName[1], (int) workList[wfd].rootName[0] - 5);
        workList[wfd].editName[0] = (char) strlen(&workList[wfd].editName[1]);

        SetMItemName(&workList[wfd].editName[0], (word) EditFile1Item + wfd);
        CalcMenuSize(0,0,3);

        sprintf(workList[wfd].fileName, (char *) strings[18]);
        strncat(workList[wfd].fileName, &workList[wfd].rootName[1], (int) workList[wfd].rootName[0] - 5);
        workList[wfd].fileName[0] = (char) strlen(&workList[wfd].fileName[1]);

        sprintf(workList[wfd].packName, (char *) strings[20]);
        strncat(workList[wfd].packName, &workList[wfd].rootName[1], (int) workList[wfd].rootName[0] - 5);
        workList[wfd].packName[0] = (char) strlen(&workList[wfd].packName[1]);

        SetMItemName(&workList[wfd].fileName[0], (word) CloseFileItem);
        SetMItemName(&workList[wfd].packName[0], (word) OptimizeItem);
        CalcMenuSize(0,0,2);
    }
    MoonCursor();

    p = deref(workList[wfd].pathFile);
    p[1] = p[0];
    sprintf(tempName, (char *) strings[26], &p[1]);
    p[1] = 0x00;
    winP = NoteWindow(tempName);
    HUnlock(workList[wfd].pathFile);

    flushWorkFile(wfd);
    saveNames(wfd);

    HLock(workList[wfd].pathName);
    CreateResourceFile(1L, 0x5e, 0xc3, *workList[wfd].pathName);
    retVal = rCopy2((GSString255Ptr) *workList[wfd].pathName, workList[wfd].resFileID);
    HUnlock (workList[wfd].pathName);

    workList[wfd].wFlag = 0x9000;           /* current, busy */

    CloseWindow(winP);
    InitCursor();

    return retVal;
}

/*--------------------------------------
    setupWorkFile finds the first free workfile, returning an index to the
    workFile array.  This enables/disables file menu items as appropriate.

    Marc Wolfgram,  5/28/91 16:57:01
*/
word setupWorkFile(void)
{
word wfd, j;
NameRecGS KillPB;

    for (wfd = 0; wfd < 4; wfd++) {
        if ((workList[wfd].wFlag & 0x1000) == 0) {
            nullFile_s = workFile_s = (char) wfd + 'a';
            KillPB.pCount = 1;
            KillPB.pathname = &workFile;
            DestroyGS(&KillPB);
            CreateResourceFile(1L, 0x5e, 0xc3, &workFile);
            workList[wfd].wFlag = 0x1000;
            return wfd;
        }
    }
    return -1;
}

/*--------------------------------------
    openWorkFile

    Marc Wolfgram
*/
word openWorkFile(word wfd)
{
word i, resFileID, sysFileID, retVal;
char n;
Handle			winH;
fWindowRecPtr   refP;
fWindowRecHndl  refH;
fMemberHndl     memberH;
GrafPortPtr     winP;
fListCtlRecHndl listCtlH;

    sysFileID = OpenResourceFile(0x8001, 0L, &sResFile);
    resFileID = OpenResourceFile(0x8003, 0L, &workFile);
    retVal = toolerror();
    SetCurResourceFile(fResID);
    if (retVal) {
        InitCursor();
        AlertArray[0] = &workList[wfd].rootName[1];
        i = AlertWindow(0x0034, AlertArray, 9L);
        DisposeHandle(workList[wfd].pathFile);
        DisposeHandle(workList[wfd].pathName);
        workList[wfd].wFlag = 0;
        CloseResourceFile(sysFileID);
        return retVal;
    }

    refH = (fWindowRecHndl) NewHandle(20L, fMemID, 0x0018, 0L);

	winH = remLoadSpecial(0x800e, Root_Window);
    remTwiddleSpecial(0x800e, winH, 0);

    (Pointer) refP = deref((Handle) refH);
    refP->Signature     = REM_signature + REM_fileroot + wfd;
    refP->resType       = 0;
    refP->resID         = 0L;
    refP->resFileID     = resFileID;
    refP->remTaskMask   = 0x001f7fffL;
    refP->remSignature  = 1;
    refP->resPrivate    = winH;
    HUnlock(refH);

    winP = NewWindow2(&workList[wfd].rootName, refH, &DrawProc, 0L, 1, winH, 0x800e);

    winLoc[wfd].v = 28;
    winLoc[wfd].h = (wfd * 100) + 8;
    if (!vMode)
        winLoc[wfd].h /= 2;
    MoveWindow(winLoc[wfd], winP);
    winLoc[wfd].h += (10 + (10 * vMode));
    GetNextWinLoc(wfd);

    workList[wfd].resFileID = resFileID;
    workList[wfd].sysFileID = sysFileID;
    workList[wfd].rootWinP = winP;

    SetFrameColor(WColors[wfd + c320], winP);

    retVal = loadNames(wfd);
    if (retVal) {
        disposeWorkData(wfd);
        CloseWindow(winP);
        CloseResourceFile(workList[wfd].resFileID);
        CloseResourceFile(workList[wfd].sysFileID);
        retVal = AlertWindow(0x0034, 0L, OpenFailure_Alert);
    }
    else {
        (long) memberH = 0L;
        memberH = allocRootList(memberH, workList[wfd].resNameHndl, workList[wfd].count);
        (CtlRecHndl) listCtlH = GetCtlHandleFromID(winP, 2L);
        (**listCtlH).ctlListSize = workList[wfd].count;
        (**listCtlH).ctlMemSize = 9;
        (**listCtlH).ctlListRef = memberH;
        (**listCtlH).ctlMoreFlags = 0x1401;
        NewList2(0L, 1, memberH, 1, workList[wfd].count, listCtlH);
        DrawOneCtl(listCtlH);
        ShowWindow(winP);

        n = (char) wfd + '1';

        sprintf(workList[wfd].editName, (char *) strings[19], n);
        strncat(workList[wfd].editName, &workList[wfd].rootName[1], (int) workList[wfd].rootName[0] - 5);
        workList[wfd].editName[0] = (char) strlen(&workList[wfd].editName[1]);
        SetMItemName(&workList[wfd].editName[0], (word) EditFile1Item + wfd);
        EnableMItem((word) EditFile1Item + wfd);
        CalcMenuSize(0,0,3);

        sprintf(workList[wfd].fileName, (char *) strings[18]);
        strncat(workList[wfd].fileName, &workList[wfd].rootName[1], (int) workList[wfd].rootName[0] - 5);
        workList[wfd].fileName[0] = (char) strlen(&workList[wfd].fileName[1]);

        sprintf(workList[wfd].packName, (char *) strings[20]);
        strncat(workList[wfd].packName, &workList[wfd].rootName[1], (int) workList[wfd].rootName[0] - 5);
        workList[wfd].packName[0] = (char) strlen(&workList[wfd].packName[1]);

        SetMItemName(&workList[wfd].fileName[0], (word) CloseFileItem);
        SetMItemName(&workList[wfd].packName[0], (word) OptimizeItem);
        CalcMenuSize(0,0,2);

        SetMenuFlag(0xff7f, 4);
        DrawMenuBar();

        SetupMenu(0x4280);
     	if (countFiles() == 4)
            SetupMenu(0x0040);
    }

    SetCurResourceFile(fResID);
    InitCursor();
    return(retVal);
}

/*--------------------------------------
    openTypeWindow

    Marc Wolfgram
*/
word openTypeWindow(word wfd, word type)
{
word i, retVal;
Handle			winH;
CtlRecHndl		menuBarH;
fOpenRec        openPB;
fWindowRecPtr   refP;
fWindowRecHndl  refH;
nameHndl        nameH;
namePtr         nameP;
fMemberHndl     memberH;
GrafPortPtr     winP;
fListCtlRecHndl listCtlH;
remTypeLinkPtr  remP;


    WaitCursor();

    remP = getTypeLinkRef(type);
    nameP = getNameRec(wfd, type);
    memberH = allocTypeList((long) 0L, nameP->itemHndl, nameP->count);

    if (((**prefDataH).pFlag & 0x8000) == 0 && (remP->rFlag & 0x4000)) {
        openPB.resType      = type;
        openPB.resID        = 0L;
        openPB.fFlag        = 0x0600; /* selector with data */
        openPB.Data         = (Handle) memberH;
        openPB.wColorPtr    = (Pointer) WColors[wfd + c320];
        callREM(_OPEN, (Pointer) &openPB);
    }
    else {
        refH = (fWindowRecHndl) NewHandle(20L, fMemID, 0x0018, 0L);

    	winH = remLoadSpecial(0x800e, Type_Window);
    	remTwiddleSpecial(0x800e, winH, 0);

        (Pointer) refP = deref((Handle) refH);
        refP->Signature     = REM_signature + REM_tselector + wfd;
        refP->resType       = type;
        refP->resID         = 0L;
        refP->remTaskMask   = 0x001f7fffL;
        refP->resFileID     = workList[wfd].resFileID;
        refP->resPrivate    = winH;
        HUnlock(refH);

        winP = NewWindow2(&nameP->winT, refH, &DrawProc, 0L, 1, winH, 0x800e);
        MoveWindow(winLoc[wfd], winP);
        GetNextWinLoc(wfd);
        SetFrameColor(WColors[wfd + c320], winP);

		(**refH).remSignature = SetupTypeMenu(type, winP);

        (CtlRecHndl) listCtlH = GetCtlHandleFromID(winP, 2L);
        (**listCtlH).ctlListSize = nameP->count;
        (**listCtlH).ctlMemSize = 9;
        (**listCtlH).ctlListRef = memberH;
        (**listCtlH).ctlMoreFlags = 0x1401;
        NewList2(0L, 1, memberH, 1, nameP->count, listCtlH);
        DrawOneCtl(listCtlH);
        ShowWindow(winP);
    }
    InitCursor();
}

char plural[] = { "s " };
char sizeStr[12], countStr[6], avgStr[12];

/*--------------------------------------
    showTypeInfo

    Marc Wolfgram,  9/ 8/91 22:11:42
*/
void showTypeInfo(word wfd, word type)
{
int         i, j, count, curFile;
long        size;
namePtr     nameP;

    WaitCursor();

    nameP = getNameRec(wfd, type);
    count = nameP->count;
    size = 0L;

    curFile = GetCurResourceFile();
    SetCurResourceFile(workList[wfd].resFileID);

    for (j = count; j > 0; j--)
        size += GetResourceSize(type, GetIndResource(type, (long) j));

    SetCurResourceFile(curFile);

    sprintf(countStr, "%u", count);
    sprintf(sizeStr, "%lu", size);
    sprintf(avgStr, "%lu", size/(long) count);

    AlertArray[0] = &nameP->name[1];
    AlertArray[1] = &workList[wfd].rootName[2];
    AlertArray[2] = countStr;
    AlertArray[3] = AlertArray[4] = plural;
    AlertArray[5] = sizeStr;
    AlertArray[6] = avgStr;

    if (count == 1)
        AlertArray[3]++;     /* "1 item exists " */
    else
        AlertArray[4]++;     /* "n items exist " */

    InitCursor();

    i = AlertWindow(0x0034, AlertArray, 5L);

    return;
}

/*--------------------------------------
    flushWorkFile

    Marc Wolfgram,  9/21/91 13:37:05
*/
word flushWorkFile(word wfd)
{
fCloseRec       closePB;
fWindowRecHndl  refH;
fWindowRecPtr   refP;
GrafPortPtr     winP;

    winP = GetFirstWindow();
    while(winP) {
        if (!GetSysWFlag(winP)) {
            refH = (fWindowRecHndl) GetWRefCon(winP);
            (Pointer) refP = deref((Handle) refH);
            if (refP->Signature < (REM_signature + REM_fileroot) && (refP->Signature & 0x0003) == wfd) {
                closePB.resType = refP->resType;
                closePB.resID = refP->resID;
                closePB.windowPtr = (Pointer) winP;
                switch (refP->Signature & 0x0070) {
                case 0x0010:
                    closePB.fFlag = 0x0400;
                    break;
                case 0x0040:
                    closePB.fFlag = 0x1000;
                    break;
                case 0x0060:
                    closePB.fFlag = 0x0800;
                    break;
                default:
                    closePB.fFlag = 0;
                    break;
                }
                callREM(_WRITE, (Pointer) &closePB);
            }
        }
        winP = GetNextWindow(winP);
    }
    return 0;
}

/*--------------------------------------
    disposeWorkData

    Marc Wolfgram,  7/ 2/91 23:54:38
*/
void disposeWorkData(word wfd)
{
char    *p;
word     i, count;
nameHndl refH;
namePtr  refP;

    workList[wfd].wFlag = 0;
    refH = workList[wfd].resNameHndl;
    (Pointer) refP = deref((Handle) refH);
    count = workList[wfd].count;
    for (i = 0; i < count; i++) {
		if (refP[i].nFlag & 0x4000) {
            count++;
            continue;
		}
        DisposeHandle((Handle) refP[i].itemHndl);
	}
    DisposeHandle((Handle) refH);
    DisposeHandle(workList[wfd].pathName);
    DisposeHandle((Handle) GetWRefCon(workList[wfd].rootWinP));
    CloseResourceFile(workList[wfd].resFileID);
    CloseResourceFile(workList[wfd].sysFileID);
}

word iSort;

/*--------------------------------------
	compareMember (was sortMemberProc)

    Marc Wolfgram,  9/25/91  1:11:26
	     Optimized  1/23/92  0:17:25
*/
int compareMember(char *a, char *b)
{
    int retVal, subVal;

 	retVal = CompareStrings(0, a, b);

    if (iSort) {
        if (a[0] > iSort) {
            if (b[0] > iSort) {
            	a[iSort] = a[0] - iSort;
                b[iSort] = b[0] - iSort;
                subVal = CompareStrings(0, &a[iSort], &b[iSort]);
            	a[iSort] = b[iSort] = ' ';
                if (subVal)
                	retVal = subVal;
            }
            else
                retVal = 1;
        }
        else if (b[0] > iSort)
            retVal = -1;
    }
    return retVal;
}

/*--------------------------------------
	listInsert replaces qsort (slow but nice to the stack)

	Marc Wolfgram,  1/23/92 21:02:48
*/
void listInsert(char *name, char flag, long nref, fMemberPtr listP, word lCnt)
{
word i;

    for (i = 0; i < lCnt; i++) {
        MoonCursor();
        if (compareMember(listP[i].text, name) == 1) {
			BlockMove(&listP[i], &listP[i+1], (long) ((lCnt - i + 1) * 9));
			break;
		}
	}
    listP[i].text = name;
    listP[i].flag = flag;
    listP[i].nref = nref;
}

/*--------------------------------------
    allocRootList

    Marc Wolfgram,  7/ 6/91 18:23:23
*/
fMemberHndl allocRootList(fMemberHndl listH, nameHndl nameH, word count)
{
char flag;
word i, j, members, selected;
namePtr     nameP;
fMemberPtr  listP;

    iSort = ((**prefDataH).pFlag & 0x0100) ? 5 : 0;
    selected = 0;

    if (count) {
        if (listH) {
            (Pointer) listP = deref((Handle) listH);
            members = (word) GetHandleSize((Handle) listH) / 9L;
            for (i = 0; i < members; i++) {
                if (listP[i].flag & 0x80) {
                    selected = (word) listP[i].nref;
                    break;
                }
            }
            DisposeHandle((Handle) listH);
        }

        (Pointer) nameP = deref((Handle) nameH);
        members = (word) GetHandleSize((Handle) nameH) / nameSize;

        listH = (fMemberHndl) NewHandle((long) count * 9L, fMemID, 0xc018, 0L);
        if (!toolerror()) {
            (Pointer) listP = deref((Handle) listH);

            for (i = 0, j = members - 1; i < count; j--) {
                if (nameP[j].nFlag & 0x4000)
                    continue;
				if (selected == nameP[j].type)
					flag = 0x80;
                else if (nameP[j].type == rResName)
                    flag = 0x60;
                else
                	flag = 0x00;
				listInsert(nameP[j].name, flag, (long) nameP[j].type, listP, i++);
            }

            if (!selected && count) {
            	i = (listP[0].nref == 0x00008014L) ? 1 : 0;
            	if (count > i)
		            listP[i].flag = 0x80;
            }
            return listH;
        }
    }
    return (fMemberHndl) 0L;
}

/*--------------------------------------
    allocTypeList

    Marc Wolfgram,  7/ 6/91 18:42:47
*/
fMemberHndl allocTypeList(fMemberHndl listH, nameSubHndl nameH, word count)
{
char flag;
word i, j, members;
long selected;
nameSubPtr  nameP;
fMemberPtr  listP;

    iSort = ((**prefDataH).pFlag & 0x0200) ? 9 : 0;
    selected = 0L;

    if (count) {
        if (listH) {
            (Pointer) listP = deref((Handle) listH);
            members = (word) GetHandleSize((Handle) listH) / 9L;
	 		for (i = 0; i < members; i++) {
                if (listP[i].flag & 0x80) {
                    selected = listP[i].nref;
                    break;
                }
            }
            DisposeHandle((Handle) listH);
        }

        (Pointer) nameP = deref((Handle) nameH);
       	members = (word) GetHandleSize((Handle) nameH) / nameSubSize;

        listH = (fMemberHndl) NewHandle((long) count * 9L, fMemID, 0xc018, 0L);
        if (!toolerror()) {
            (Pointer) listP = deref((Handle) listH);

            for (i = 0, j = members - 1; i < count; j--) {
                if (nameP[j].nFlag & 0x4000)
                    continue;
				if (selected == nameP[j].id)
					flag = 0x80;
                else if (nameP[j].id == 0L)
                    flag = 0x60;
                else
                	flag = 0x00;
				listInsert(nameP[j].name, flag, nameP[j].id, listP, i++);
            }

            if (!selected && count) {
            	i = (listP[0].nref == 0L) ? 1 : 0;
            	if (count > i)
		            listP[i].flag = 0x80;
            }

            return (fMemberHndl) listH;
        }
    }
    return 0L;
}

/*--------------------------------------
    checkListStatus

    Marc Wolfgram, 10/13/91 19:42:47
*/
void checkListStatus(void)
{
word i, count;
namePtr         nameP;
fMemberHndl     memberH;
GrafPortPtr     winP, oldP;
fListCtlRecHndl listCtlH;

    oldP = GetPort();
    if (workList[workIndex].wFlag & 0x0002) {
        winP = findSignature(REM_signature + REM_fileroot + workIndex, 0, 0, 0L);
        SetPort(winP);
        (CtlRecHndl) listCtlH = GetCtlHandleFromID(winP, 2L);
        memberH = (**listCtlH).ctlListRef;
        memberH = allocRootList(memberH, workList[workIndex].resNameHndl, workList[workIndex].count);
        NewList2(0L, 1, memberH, 1, workList[workIndex].count, listCtlH);
		InitCursor();
    }
    if (workList[workIndex].wFlag & 0x0001) {
        nameP = (namePtr) *workList[workIndex].resNameHndl;
        count = workList[workIndex].count;
        for (i = 0; i < count; i++) {
			if (nameP[i].nFlag & 0x4000) {
				count++;
				continue;
			}
            if (nameP[i].nFlag & 0x0001) {
                winP = findSignature(REM_signature + REM_tselector + workIndex, 0, nameP[i].type, 0L);
                if (winP) {
                    SetPort(winP);
                    (CtlRecHndl) listCtlH = GetCtlHandleFromID(winP, 2L);
                    memberH = (**listCtlH).ctlListRef;
                    memberH = allocTypeList(memberH, nameP[i].itemHndl, nameP[i].count);
                    NewList2(0L, 1, memberH, 1, nameP[i].count, listCtlH);
					InitCursor();
                }
            }
            nameP[i].nFlag &= 0xfffe;
        }
    }
    workList[workIndex].wFlag &= 0xfffc;
    SetPort(oldP);
}

/*--------------------------------------
    GetNextWinLoc - handles window staggering

    Marc Wolfgram & Mark Collins,  9/20/91 23:14:31
*/
void GetNextWinLoc(word wfd)
{

    winLoc[wfd].v += 12;
    if (vMode) {
        if (winLoc[wfd].v > 90) {
            winLoc[wfd].v = 40;
            winLoc[wfd].h += 20;
                if (winLoc[wfd].h > ((wfd * 100) + 78))
                    winLoc[wfd].h -= 60;
        }
    }
    else {
        if (winLoc[wfd].v > 90) {
            winLoc[wfd].v = 40;
            winLoc[wfd].h += 10;
                if (winLoc[wfd].h > ((wfd * 50) + 39))
                    winLoc[wfd].h -= 30;
        }
    }
}


/*--------------------------------------
    countFiles

    Marc Wolfgram, 10/30/91 21:34:44
*/
word countFiles()
{
word i, j;

    for (i = 4, j = 0; j < 4; j++)   /* is another open? */
        if ((workList[j].wFlag & 0x1000) == 0)
            i--;
    return i;
}

/*--------------------------------------
    getPrefs loads the preferences data

    Marc Wolfgram, 11/ 2/91 14:21:40
*/
prefDataHndl getPrefs(void)
{
char *defFile;
word resFile, curFile, invalid;
prefDataPtr  prefP;
prefDataHndl prefH;

    curFile = GetCurResourceFile();
    pResID = OpenResourceFile(3, 0L, &prefFile);
    invalid = toolerror();
    if (!invalid) {
        (Handle) prefH = LoadResource(0x7ffc, 1L);
        (Pointer) prefP = deref((Handle) prefH);
        if (prefP->version == 1) {
            if (prefP->fileRef) {
                prefP->fileRef = (long) LoadResource(rC1OutputString, 1L);
                DetachResource(rC1OutputString, 1L);
                prefP->pathRef = (long) LoadResource(rC1OutputString, 2L);
                DetachResource(rC1OutputString, 2L);
                if (prefP->pFlag & 0x0400) {
                    if (OpenFile(prefH)) {
                        RemoveResource(rC1OutputString, 1L);
                        RemoveResource(rC1OutputString, 2L);
                        prefP->pFlag &= 0xfbff;
                        prefP->fileRef = prefP->pathRef = 0L;
                    }
                }
            }
        }
        else {
            invalid = 1;
            RemoveResource(0x7ffc, 1L);
            CloseResourceFile(resFile);
        }
    }

    if (invalid) {
        (Handle) prefH = NewHandle(12L, fMemID, 0x8018, 0L);
        (Pointer) prefP = deref((Handle) prefH);
        prefP->version = 1;
        prefP->pFlag = 0;
        prefP->fileRef = prefP->pathRef = 0L;
        CreateResourceFile(1L, 0x5e, 0xc3, &prefFile);
        resFile = OpenResourceFile(3, 0L, &prefFile);
        AddResource(prefH, 0, 0x7ffc, 1L);
        UpdateResourceFile(resFile);
        (Handle) prefH = LoadResource(0x7ffc, 1L);
    }
    HUnlock(prefH);
    SetCurResourceFile(curFile);
    return prefH;
}

/*--------------------------------------
    editPrefs

    Marc Wolfgram, 11/11/91 22:31:49
*/
prefDataHndl editPrefs(prefDataHndl prefH)
{
char *defFile;
word i, curFile, pFlag, done, task, defNew, defOld;
Rect dRect;
GrafPortPtr winP, oldP;
prefDataPtr prefP;

    miscTaskRec.wmTaskMask = 0x1B2006L;
    (Pointer) prefP = deref((Handle) prefH);
    pFlag = prefP->pFlag;
    SFreply.good = FALSE;

    oldP = GetPort();
    winP = NewWindow2(0L, 0L, &PrefProc, 0L, 2, Pref_Window, 0x800e);
    SetPort(winP);

/*
 * Set the popups to the cooresponding pFlag bits
 */

    SetCtlValue((pFlag & 0x0100) ? 2 : 1, GetCtlHandleFromID(winP, 1L));
    SetCtlValue((pFlag & 0x0200) ? 3 : 1, GetCtlHandleFromID(winP, 2L));
    defOld = (pFlag & 0x0400) ? 5 : 4;
    SetCtlValue(defOld , GetCtlHandleFromID(winP, 3L));
    SetCtlValue((pFlag & 0x000f) + 8, GetCtlHandleFromID(winP, 4L));

/*
 * Check the appropriate boxes
 */

    SetCtlValue((pFlag & 0x8000) ? 1 : 0, GetCtlHandleFromID(winP, 5L));
    SetCtlValue((pFlag & 0x4000) ? 1 : 0, GetCtlHandleFromID(winP, 6L));

/*
 * Check to see if there's a default file handle and set it in tempName
 */

    if (prefP->fileRef) {
        (Pointer) defFile = deref((Handle) prefP->fileRef);
        i = (defFile[2] > ' ') ? 1 : 3; /* Mark's hack B-)  needed to handle */
        defFile[i] = defFile[i-1];      /* entrance with c1in or c1out types */
        sprintf(&tempName[128], "%p", &defFile[i]);
        defFile[i] = 0x00;
        HUnlock(prefP->fileRef);
    }
    else
        sprintf(&tempName[128], (char *) strings[12]);
    sprintf(tempName, "%s", &tempName[128]);

/*
 * Now do me an event loop....
 */

    done = 0;

    do {
        task = TaskMaster(0xffff, &miscTaskRec);
        if (task == wInControl) {
            switch (miscTaskRec.wmTaskData4) {
            case 1L:    /* root sort */
                if (GetCtlValue(GetCtlHandleFromID(winP, 1L)) == 1)
                    pFlag &= 0xfeff;
                else
                    pFlag |= 0x0100;
                break;

            case 2L:    /* type sort */
                if (GetCtlValue(GetCtlHandleFromID(winP, 2L)) == 1)
                    pFlag &= 0xfdff;
                else
                    pFlag |= 0x0200;
                break;

            case 3L:    /* file 1: */
                defNew = GetCtlValue(GetCtlHandleFromID(winP, 3L));
                if (defNew == 4)
                    pFlag &= 0xfbff;
                else if (defNew == 5) {
                    if (SFreply.good || prefP->fileRef)
                        pFlag |= 0x0400;
                    else {
                        pFlag &= 0xfbff;
                        SetCtlValue(4, GetCtlHandleFromID(winP, 3L));
                    }
                }
                else {
                    if (SFreply.good) {
                        DisposeHandle(SFreply.nameRef);
                        DisposeHandle(SFreply.pathRef);
                        (long) SFreply.nameRef = (long) SFreply.pathRef = 0L;
                    }
				    SetPort(SysWPtr);
                    SFGetFile2(120, 43, 2, 0x3000L, &SFResProc, 0L, &SFreply);
				    SetPort(winP);
                    if (SFreply.good) {
                        SetCtlValue(5, GetCtlHandleFromID(winP, 3L));
                        (Pointer) defFile = deref((Handle) SFreply.nameRef);
                        defFile[3] = defFile[2];
                        sprintf(tempName, "%p", &defFile[3]);
                        defFile[3] = 0x00;
                        HUnlock(prefP->fileRef);
                    }
                    else {
                        SetCtlValue(defOld, GetCtlHandleFromID(winP, 3L));
                        sprintf(tempName, "%s", &tempName[128]);
                    }
                    dRect.v1 = 88;    /* blast the filename space */
                    dRect.h1 = 150;
                    dRect.v2 = 98;
                    dRect.h2 = 390;
                    EraseRect(&dRect);
                    InvalRect(&dRect);
                }
                break;

            case 4L:    /* format choice */
                pFlag &= 0xfff0;
                pFlag |= (GetCtlValue(GetCtlHandleFromID(winP, 4L)) - 8);
                break;

            case 5L:    /* type selector */
                if (GetCtlValue(GetCtlHandleFromID(winP, 5L)))
                    pFlag |= 0x8000;
                else
                    pFlag &= 0x7fff;
                break;

            case 6L:    /*  delete limit */
                if (GetCtlValue(GetCtlHandleFromID(winP, 6L)))
                    pFlag |= 0x4000;
                else
                    pFlag &= 0xbfff;
                break;

            case 7L:    /* OK */
                curFile = GetCurResourceFile();
                SetCurResourceFile(pResID);
                prefP->pFlag = pFlag;
                if (prefP->fileRef) {
                    DisposeHandle(prefP->fileRef);
                    prefP->fileRef = 1L;
                    DisposeHandle(prefP->pathRef);
                    prefP->pathRef = 2L;
                }
                if (SFreply.good) {
                    RemoveResource(rC1OutputString, 1L);
                    AddResource(SFreply.nameRef, 0, rC1OutputString, 1L);
                    prefP->fileRef = 1L;

                    RemoveResource(rC1OutputString, 2L);
                    AddResource(SFreply.pathRef, 0, rC1OutputString, 2L);
                    prefP->pathRef = 2L;
                }

                MarkResourceChange(1, 0x7ffc, 1L);
                UpdateResourceFile(pResID);

                if (prefP->fileRef == 1L) {
                    prefP->fileRef = (long) LoadResource(rC1OutputString, 1L);
                    DetachResource(rC1OutputString, 1L);

                    prefP->pathRef = (long) LoadResource(rC1OutputString, 2L);
                    DetachResource(rC1OutputString, 2L);
                }
                SetCurResourceFile(curFile);

            case 8L:    /* Cancel */
                HUnlock(prefH);
                done++;
                break;

            default:
                break;
            }
        }
    } while(!done);

    CloseWindow(winP);
    SetPort(oldP);

    return prefH;
}

/*--------------------------------------
	NoteWindow

	Marc Wolfgram
*/
GrafPortPtr NoteWindow(char *note)
{
GrafPortPtr winP, oldP;

    oldP = GetPort();
    winP = NewWindow2(0L, 0L, 0L, 0L, 2, Note_Window, 0x800e);
    SetPort(winP);
    MoveTo(10,12);
    DrawCString(note);
    SetPort(oldP);
    return winP;
}

Rect NoteRect = { 10, 12, 20, 300 };

/*--------------------------------------
	ChangeNoteWindow - serendipity made me do this

	Marc Wolfgram,  3/12/92  0:00:01
*/
void ChangeNoteWindow(GrafPortPtr winP, char *note)
{
GrafPortPtr oldP;

    oldP = GetPort();
    SetPort(winP);
	EraseRect(&NoteRect);
    MoveTo(10,12);
    DrawCString(note);
    SetPort(oldP);
    return;
}


/*--------------------------------------
	OptimizeFile

	Marc Wolfgram,  1/ 5/92 10:53:57
*/
word OptimizeFile(void)
{
word retVal;

    retVal = 0;
    flushWorkFile(workIndex);
/*	closeTypes(workIndex); */

    CloseWindow(workList[workIndex].rootWinP);

    return retVal;
}
