/*
   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 <GSOS.h>
#include <qdaux.h>
#include <list.h>
#include <intmath.h>
#include <ctype.h>
#include <foundation.h>

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

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

extern word fResID, pResID, vMode, c320, qFlag;
extern void DrawProc(), PrefProc();
extern void SFNilProc;
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;

extern fResLinkRec  fBuildLinkPB;
extern fResDataRec  dataPB;
extern fResNameRec  namePB;

int  SFGetH[]    = { 30, 120 }; /* V = 43 for both 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;
GetRefNumRecGS  RefNumPB = { 4, &workFile, 0, 0, 1 };
RefNumRecGS     FileClosePB = { 1 };
workFileRec     workList[4];	/* added scrapfile @ index 4 */
word            workIndex;

Point           winLoc[4];

NameRecGS KillPB;
ChangePathRecGS renPB;

GetRefNumRecGS  GetRefNumPB = { 4, 0L, 0, 0, 1 };

CreateRecGS     refCreate = { 4, 0L, 0xc3, 0x04, 0L };
OpenRecGS       refOpen = { 3, 0, 0L, 3 };
IORecGS         refWritePB = { 4, 0, tempName};


CreateRecGS	    UserDirPB = { 3, &userPath, 0xc3, 0x0f };

/*--------------------------------------
    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);
    p = (char *) deref(workList[wfd].pathFile);
    p[0] = 10;
    p[1] = 0;
    HUnlock(workList[wfd].pathFile);

    workList[wfd].pathName = NewHandle(14L, fMemID, 0x0018, 0L);
    PtrToHand((Pointer) &nullFile, (Handle) 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;
    p = (char *) 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;
    p = (char *) 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, (Pointer) 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;

    HLock(workList[wfd].pathFile);
    GetRefNumPB.pathname = (GSString255Ptr) *workList[wfd].pathName;
    GetRefNumGS(&GetRefNumPB);
    if (!toolerror() && (GetRefNumPB.access & 2) == 0)
        mode = 1;
    HUnlock(workList[wfd].pathFile);

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

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

        WaitCursor();

        h = (Handle) SFreply.nameRef;
        p = (char *) 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;
        p = (char *) 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();

    if (retVal) {
        AlertArray[0] = &workList[wfd].rootName[1];
        mode = AlertWindow(0x0034, (Pointer) AlertArray, 29L);
    }
    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;

    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, (Pointer) &workFile);
            workList[wfd].wFlag = 0x1000;
            return wfd;
        }
    }
    return -1;
}

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

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

    alertID = 9L;
    sysResID = OpenResourceFile(0x8001, 0L, (Pointer) &sResFile);
    resFileID = OpenResourceFile(0x8003, 0L, (Pointer) &workFile);
    retVal = toolerror();
    if (retVal == 0)  {
        i = GetOpenFileRefNum(resFileID);
        retVal = toolerror();
        if (retVal) {
            alertID = 8L;
            GetRefNumGS(&RefNumPB);
            FileClosePB.refNum = RefNumPB.refNum;
            if (RefNumPB.refNum)
                CloseGS(&FileClosePB);
        }
    }
    SetCurResourceFile(fResID);
    if (retVal) {
        InitCursor();
        AlertArray[0] = &workList[wfd].rootName[1];
        i = AlertWindow(0x0034, (Pointer) AlertArray, alertID);
        DisposeHandle(workList[wfd].pathFile);
        DisposeHandle(workList[wfd].pathName);
        workList[wfd].wFlag = 0;
        CloseResourceFile(sysResID);
        return retVal;
    }

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

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

    refP = (fWindowRecPtr) 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((Handle) refH);

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

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

    workList[wfd].resFileID = resFileID;
    workList[wfd].sysResID = sysResID;
    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].sysResID);
        retVal = AlertWindow(0x0034, 0L, OpenFailure_Alert);
    }
    else {
        memberH = allocRootList(memberH, workList[wfd].resNameHndl, workList[wfd].count);
        listCtlH = (fListCtlRecHndl) GetCtlHandleFromID(winP, 2L);
        (**listCtlH).ctlListSize = workList[wfd].count;
        (**listCtlH).ctlMemSize = 9;
        (**listCtlH).ctlListRef = memberH;
        (**listCtlH).ctlMoreFlags = 0x3401;
        NewList2(0L, 1, (Ref) memberH, 1, workList[wfd].count, (Handle) listCtlH);
        DrawOneCtl((CtlRecHndl) listCtlH);
        SetPort(winP);
        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);
        HiliteMenu(0, 4);

        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);

        refP = (fWindowRecPtr) 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((Handle) refH);

        winP = NewWindow2((Pointer) &nameP->winT, (Long) refH, (VoidProcPtr) &DrawProc, 0L, 1, (Ref) winH, 0x800e);
        SetPort(winP);
        MoveWindow(winLoc[wfd].h, winLoc[wfd].v, winP);
        GetNextWinLoc(wfd);
        SetFrameColor(WColors[wfd + c320], winP);

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

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

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] = (count == 1) ? (char *) strings[59] : (char *) strings[60];
    AlertArray[4] = sizeStr;
    AlertArray[5] = avgStr;

    InitCursor();

    i = AlertWindow(0x0034, (Pointer) 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);
            if (refH) {
                refP = (fWindowRecPtr) 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;
    refP = (namePtr) 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((Handle) workList[wfd].pathName);
    DisposeHandle((Handle) GetWRefCon(workList[wfd].rootWinP));
    CloseResourceFile(workList[wfd].resFileID);
    CloseResourceFile(workList[wfd].sysResID);
}

/*--------------------------------------
    importRequested

    Marc Wolfgram and Mark Collins,  6/25/92  2:05:13 AM
*/
word importRequested (void)
{
char        *s;
word		i, retVal, done, task, resType;
long        curFile, resID;
Handle		h, fileData;
Pointer     oldPP;
GrafPortPtr winP, oldP;
GSString255Ptr p;

    retVal = 0;

	oldPP = GetCtlParamPtr();

    curFile = SetResFile2(fResID, -1);

    s = (char *) strings[70];

    SFGetFile2(SFGetH[vMode], 43, 2, 0x3002L, &SFNilProc, 0L, &SFreply);
 	if (SFreply.good) {
        p = (GSString255Ptr) deref((Handle) SFreply.nameRef);
        c1cvt((char *) p);
        strncpy(&tempName[97], p->text, p->length);
        tempName[96] = (char) p->length;
        AlertArray[0] = &tempName[96];
        AlertArray[1] = workList[workIndex].rootName;
        AlertArray[2] = &tempName[64];
        AlertArray[3] = &tempName[192];
        SetCtlParamPtr((Pointer) &AlertArray);
        oldP = GetPort();
        winP = NewWindow2(0L, 0L, (VoidProcPtr) &DrawProc, 0L, 2, 0xeffL, 0x800e);
        SetPort(winP);
        CenterWindow(winP);

        SetLETextByID(winP, 2L, (StringPtr) s);
        GetLETextByID(winP, 3L, (StringPtr) &tempName[74]);

	    ShowWindow(winP);

        done = 0;
        miscTaskRec.wmTaskMask = 0x1B2006L;

        do {
            task = TaskMaster(0xffff, &miscTaskRec);
            if (task == wInControl && miscTaskRec.wmTaskData4 == 1L) {
                GetLETextByID(winP, 2L, (StringPtr) &tempName[64]);
                resType = Hex2Int(&tempName[65], (word) tempName[64]);
                retVal = toolerror();
                if (!resType || resType == 0x8000 || retVal) {
                    i = AlertWindow(0x0035, 0L, 26L);
                    SetLETextByID(winP, 2L, (StringPtr) s);
                    continue;
                }

                for (i = 0; i < 6; i++)
                    s[i] = tempName[64 + i ];

                GetLETextByID(winP, 3L, (StringPtr) &tempName[64]);
                resID = Hex2Long(&tempName[65], (word) tempName[64]);
                if (!resID || resID & 0xf8000000L || retVal) {
                    i = AlertWindow(0x0035, (Pointer) AlertArray, 10L);
                    SetLETextByID(winP, 3L, (StringPtr) &tempName[74]);
                    continue;
                }
                if (resID > 0x07FEFFFFL) {
                    if (AlertWindow(0x0035, (Pointer) AlertArray, 27L)) {
                        SetLETextByID(winP, 3L, (StringPtr) &tempName[64]);
                        continue;
                    }
                }
                done++;
            }
        } while(!done);

        SetCtlParamPtr(oldPP);
        CloseWindow(winP);
        SetPort(oldP);

        p = (GSString255Ptr) deref((Handle) SFreply.pathRef);
        c1cvt((char *) p);

        f13OpenPB.pathname = (GSString255Ptr) p;

        OpenGS(&f13OpenPB);
        retVal = toolerror();
        if (!retVal) {

            fileData = NewHandle((long) f13OpenPB.eof, fMemID, 0x0008, 0L);
            retVal = toolerror();
            if (!retVal) {

                f13ReadPB.pCount = 4;
                f13ReadPB.refNum = f13OpenPB.refNum;
       	        f13ReadPB.dataBuffer = deref(fileData);
                f13ReadPB.requestCount = f13OpenPB.eof;
                ReadGS(&f13ReadPB);
                retVal = toolerror();

                f13ReadPB.pCount = 1;
                CloseGS(&f13ReadPB);

		        if (!retVal) {
                    HUnlock(fileData);
        	    	dataPB.pCount = 6;
                    dataPB.resType = resType;
		            dataPB.resID = resID;
		            dataPB.resData = fileData;
                    dataPB.special = 0;
                    dataPB.resFileID = 0;
                    dataPB.resName = &tempName[96];
 		            remAddResource(&dataPB);
                    retVal = toolerror();
	            }
                if (!retVal) {
                    tempName[64] = sprintf(&tempName[65], "%0.8lX", dataPB.resID);
                    namePB.pCount = 3;
                    namePB.resType = resType;
                    namePB.resName = &tempName[192];
                    remGetStdTypeName(&namePB);
                    AlertWindow(0x0035, (Pointer) AlertArray, 28L);

                }
            }
        }
        DisposeHandle((Handle) SFreply.pathRef);
        DisposeHandle((Handle) SFreply.nameRef);
    }

    SetResFile1(curFile);
	return retVal;
}

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((Pointer) &listP[i], (Pointer) &listP[i+1], (long) ((lCnt - i) * 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) {
            listP = (fMemberPtr) 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);
        }

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

        listH = (fMemberHndl) NewHandle((long) count * 9L, fMemID, 0xc018, 0L);
        if (!toolerror()) {
            listP = (fMemberPtr) 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
                	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) {
            listP = (fMemberPtr) 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);
        }

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

        listH = (fMemberHndl) NewHandle((long) count * 9L, fMemID, 0xc018, 0L);
        if (!toolerror()) {
            listP = (fMemberPtr) 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;
}

/*--------------------------------------
    allocItemList

    Marc Wolfgram,  7/ 6/91 18:42:47
*/
void allocItemList(GrafPortPtr winP, word type, long ID)
{
char flag;
word i, j, k, members, maxcount, count, depItems;
fWindowRecHndl  refH;
namePtr         nameP;
nameSubPtr      nameSubP;
fMemberHndl     listH;
fMemberPtr      listP;
resLinkRecHndl  linkH;
resLink        *linkP;
fListCtlRecHndl listCtlH;

    depItems = 0;

    listCtlH = (fListCtlRecHndl) GetCtlHandleFromID(winP, 2L);
    if ((**listCtlH).ctlListRef)
        DisposeHandle((handle) (**listCtlH).ctlListRef);

    refH = (fWindowRecHndl) GetWRefCon(winP);

    linkH = (resLinkRecHndl) (**refH).resPrivate;
    maxcount = (**linkH).count;
    HLock((Handle) linkH);
    linkP = (**linkH).ref;

    listH = (fMemberHndl) NewHandle((long) maxcount * 9, fMemID, 0x8018, 0L);
    listP = (fMemberPtr) deref((handle) listH);
    for (i = (word) linkP[0].hostHitTick, count = 0; i < maxcount; i++) {
        MoonCursor();
        if (count) {
            if (linkP[i].hostType != type)
                break;
            else if (linkP[i].hostID != ID)
                break;
        }
        if (linkP[i].hostType == type && linkP[i].hostID == ID) {
            nameP = getNameRec(workIndex, linkP[i].resType);
            if (nameP) {
                listP[count].text = nameP->name;
                listP[count].flag = 0x00;
            }
            else {
                listP[count].text = (char *) strings[67];
                listP[count].flag = 0x60;
            }
            listP[count].nref = (long) i;
            count++;
        }
    }
    HUnlock((Handle) listH);
    if (count) {
        SetHandleSize((long) count * 9L, listH);
        HLock((Handle) listH);
    }
    else {
        count = 1;
        SetHandleSize(9L, (Handle) listH);
        listP = (fMemberPtr) deref((Handle) listH);
        listP[0].text = (char *) strings[66];
        listP[0].flag = 0x60;
        listP[0].nref = 0;
    }

    (**refH).resType = type;
    (**refH).resID = ID;

    (**listCtlH).ctlListSize = count;
    (**listCtlH).ctlMemSize = 9;
    (**listCtlH).ctlListRef = listH;
    (**listCtlH).ctlMoreFlags = 0x3401;

    NewList2(0L, 1, (Ref) listH, 1, count, (Handle) listCtlH);

    return;
}

/*--------------------------------------
    buildItemLink

    Marc Wolfgram,  6/19/92  1:05:54 AM
*/
resLinkRecHndl buildItemLink(word resType, long resID)
{
word            i, hostType, count, retVal;
long			hostID;
resLinkRecHndl 	linkH;
resLink        *linkP;

    hostType = resType;
    hostID = resID;

	for (i = 0; MasterRace[i].rType; i++) {
        MoonCursor();
		if (MasterRace[i].rType == resType) {
			if (MasterRace[i].dType & 2) {
                WaitCursor();
                linkH = remFindOwner(resType, resID);
                while ((linkH) && (**linkH).count == 1) {
                    MoonCursor();
                    hostType = (**linkH).ref[0].hostType;
                    hostID = (**linkH).ref[0].hostID;
		            DisposeHandle((handle) linkH);
        	        linkH = remFindOwner(hostType, hostID);
		        }
		        if (linkH)
			        DisposeHandle((handle) linkH);
            }
			break;
		}
    }

    fBuildLinkPB.pCount = 4;
    fBuildLinkPB.index = 0;
    fBuildLinkPB.hostType = hostType;
    fBuildLinkPB.hostID = hostID;
    retVal = remBuildLinkHand(&fBuildLinkPB);   /* callback parameter blocks */
    linkH = (resLinkRecHndl) fBuildLinkPB.linkHand;

    if ((**linkH).count) {  /* insert record 0 */
        SetHandleSize((LongWord) (GetHandleSize((Handle) linkH) + 20L), (Handle) linkH);
        HLock((Handle) linkH);
        linkP = (**linkH).ref;
        BlockMove((Pointer) &linkP[0], (Pointer) &linkP[1], (long) (**linkH).count * 20);
        (**linkH).count++;
        linkP[0].resType = linkP[1].hostType;
        linkP[0].resID = linkP[1].hostID;
        linkP[0].hostType = 0;
        count = (**linkH).count;
        for (i = 0; i < count; i++) {
            if (linkP[i].resType == resType && linkP[i].resID == resID) {
                linkP[0].resHitTick = linkP[0].hostHitTick = i;
                break;
            }
        }
    }
    else {                                  /* extend to record 0 */
        SetHandleSize(24L, (Handle) linkH);
        (**linkH).count = 1;
        HLock((Handle) linkH);
        linkP = (**linkH).ref;
        linkP[0].resType = resType;
        linkP[0].resID = resID;
        linkP[0].hostType = 0;
        linkP[0].resHitTick = linkP[0].hostHitTick = 0L;
    }
    linkP[0].hostID = 4;
    HUnlock((Handle) linkH);
    return linkH;
}

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

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

    oldP = GetPort();
    flag = workList[workIndex].wFlag;
    if (flag & 0x0006) {
        winP = findSignature(REM_signature + REM_fileroot + workIndex, 0, 0, 0L);
        SetPort(winP);
        listCtlH = (fListCtlRecHndl) GetCtlHandleFromID(winP, 2L);
        memberH = (**listCtlH).ctlListRef;
        memberH = allocRootList(memberH, workList[workIndex].resNameHndl, workList[workIndex].count);
        NewList2(0L, 1, (Ref) memberH, 1, workList[workIndex].count, (Handle) listCtlH);
   /*     if (flag & 0x0004) {  */
            item = NextMember2(0, (Handle) listCtlH);
            SelectMember2(item ? item : 1, (Handle) listCtlH);
   /*     } */
        workList[workIndex].wFlag &= 0xfff9;
	    InitCursor();
    }
    if (flag & 0x0001) {
        nameP = (namePtr) *workList[workIndex].resNameHndl;
        count = workList[workIndex].count;
        for (i = 0; i < count; i++) {
            flag = nameP[i].nFlag;
			if (flag & 0x4000) {
                count++;
                continue;
			}
            if (flag & 0x0005) {
                winP = findSignature(REM_signature + REM_tselector + workIndex, 0, nameP[i].type, 0L);
                if (winP) {
                    SetPort(winP);
                    listCtlH = (fListCtlRecHndl) GetCtlHandleFromID(winP, 2L);
                    memberH = (**listCtlH).ctlListRef;
                    memberH = allocTypeList(memberH, nameP[i].itemHndl, nameP[i].count);
                    NewList2(0L, 1, (Ref) memberH, 1, nameP[i].count, (Handle) listCtlH);
            /*        if (flag & 0x0004) {  */
                        item = NextMember2(0, (Handle) listCtlH);
                        SelectMember2(item ? item : 1, (Handle) listCtlH);
            /*        }  */
                }
            }
            nameP[i].nFlag &= 0xfffe;
        }
        workList[workIndex].wFlag &= 0xfff8;
	    InitCursor();
    }
    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;
}

word WPDone;

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

    Marc Wolfgram, 11/ 2/91 14:21:40
        Simplified 11/ 3/92
  Handles WrtProtected disks more gently   5/9/92  MTC
*/
void getPrefs(void)
{
word curFile, retVal, i;
prefDataPtr  prefP;

    wpDone = 0;
    CreateGS(&UserDirPB);       /* make sure prefs has a home */
    retVal = toolerror();
    if (retVal == 0x2b) {
        i = AlertWindow(0x0034, 0L, 99L); /*  99 may need to be changed- made up */
        qFlag = TRUE;
        wpDone = TRUE;
    }
    curFile = GetCurResourceFile();

    pResID = OpenResourceFile(3, 0L, (Pointer) &prefFile);
    retVal = toolerror();
    if (retVal) {
        KillPB.pCount = 1;
        KillPB.pathname = &prefFile;
        DestroyGS(&KillPB);
        retVal = toolerror();
        if ((retVal == 0x2b) & !wpDone) {
            i = AlertWindow(0x0034, 0L, 99L); /*  99 may need to be changed- made up */
            qFlag = TRUE;
            wpDone = TRUE;
        }
        CreateResourceFile(1L, 0x5e, 0xc3, (Pointer) &prefFile);
        pResID = OpenResourceFile(3, 0L, (Pointer) &prefFile);
    }
    else {
        prefDataH = (prefDataHndl) LoadResource(0x7ffc, 1L);
        if ((**prefDataH).version == 1) {
            SetCurResourceFile(curFile);
            return;
        }
        RemoveResource(0x7ffc, 1L);
    }

    prefDataH = (prefDataHndl) NewHandle(12L, fMemID, 0x8018, 0L);
    prefP = (prefDataPtr) deref((Handle) prefDataH);
    prefP->version = 1;
    prefP->pFlag = 0;
    prefP->fileRef = prefP->pathRef = 0L;

    AddResource((Handle) prefDataH, 0, 0x7ffc, 1L);
    UpdateResourceFile(pResID);

    HUnlock((Handle) prefDataH);
    SetCurResourceFile(curFile);
}

/*--------------------------------------
    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;
    prefP = (prefDataPtr) deref((Handle) prefH);
    pFlag = prefP->pFlag;
    SFreply.good = FALSE;

    oldP = GetPort();
    winP = NewWindow2(0L, 0L, (VoidProcPtr) &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) {
        defFile = (char *) 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((Handle) 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((Handle) SFreply.nameRef);
                        DisposeHandle((Handle) SFreply.pathRef);
                        SFreply.nameRef = SFreply.pathRef = 0L;
                    }
				    SetPort(SysWPtr);
                    SFGetFile2(120, 43, 2, 0x3000L, &SFResProc, 0L, &SFreply);
				    SetPort(winP);
                    if (SFreply.good) {
                        pFlag |= 0x0400;
                        SetCtlValue(5, GetCtlHandleFromID(winP, 3L));
                        defFile = (char *) deref((Handle) SFreply.nameRef);
                        defFile[3] = defFile[2];
                        sprintf(tempName, "%p", &defFile[3]);
                        defFile[3] = 0x00;
                        HUnlock((Handle) 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((Handle) prefP->fileRef);
                    prefP->fileRef = 1L;
                    DisposeHandle((Handle) prefP->pathRef);
                    prefP->pathRef = 2L;
                }
                if (SFreply.good) {
                    RemoveResource(rC1OutputString, 1L);
                    AddResource((Handle) SFreply.nameRef, 0, rC1OutputString, 1L);
                    prefP->fileRef = 1L;

                    RemoveResource(rC1OutputString, 2L);
                    AddResource((Handle) 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((Handle) prefH);
                done++;
                break;

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

    CloseWindow(winP);
    SetPort(oldP);

    return prefH;
}

/*--------------------------------------
    openDefault calls the OpenFile code for a default File 1
        (was in getPrefs - and was a hell of a lot simpler!)

    Marc Wolfgram, 11/ 3/92 11:56:22
*/
void openDefault(void)
{
word        retVal;
long        curFile;
prefDataPtr prefP;

    SetResFile2(pResID, 1);
    prefP = (prefDataPtr) deref((handle) prefDataH);
    if (prefP->fileRef) {
        prefP->fileRef = (long) LoadResource(rC1OutputString, 1L);
        retVal = toolerror();
        if (retVal == 0) {
            DetachResource(rC1OutputString, 1L);
            prefP->pathRef = (long) LoadResource(rC1OutputString, 2L);
            DetachResource(rC1OutputString, 2L);
            if (prefP->pFlag & 0x0400) {
                SetCurResourceFile(fResID);
                retVal = OpenFile(prefDataH);
            }
        }
    }
    if (retVal) {
        DisposeHandle((Handle) prefP->fileRef);
        DisposeHandle((Handle) prefP->pathRef);
        prefP->pFlag &= 0xfbff;
        prefP->fileRef = prefP->pathRef = 0L;
        SetCurResourceFile(pResID);
        RemoveResource(rC1OutputString, 1L);
        RemoveResource(rC1OutputString, 2L);
    }
    HUnlock((Handle) prefDataH);
    SetResFile1(curFile);
}

segment "F_MISCCODE";

/*--------------------------------------
	CenterWindow - Busy work initiated by Matt

	Marc Wolfgram,  4/22/92 10:08:16 PM
*/
void CenterWindow(GrafPortPtr winP)
{
word	h;
Rect r;
GrafPortPtr oldP;

	h = vMode ? 320 :160;

	oldP = GetPort();
    SetPort(winP);

    GetPortRect(&r);

    LocalToGlobal((Point *) &r.v1);
    LocalToGlobal((Point *) &r.v2);

    if (GetWFrame(winP) & fRScroll)
    	r.h2 += vMode ? 24 : 12;

    h -= ((r.h2 - r.h1) / 2);
	MoveWindow(h, r.v1, winP);
    SetPort(oldP);   /* restore orig port*/

}

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

	Marc Wolfgram,  4/22/92  8:30:32 PM
*/
GrafPortPtr NoteWindow(char *note)
{
GrafPortPtr winP, oldP;

    oldP = GetPort();
    winP = NewWindow2(0L, 0L, 0L, 0L, 2, Note_Window, 0x800e);
	CenterWindow(winP);
	ShowWindow(winP);
    SetPort(winP);
    MoveTo(10,12);
    DrawCString(note);
    SetPort(oldP);
    return winP;
}
/*
Rect NoteRect = { 10, 12, 20, 300 };
 */
/*--------------------------------------
	ChangeNoteWindow - serendipity made me do this    COMMENTED OUT FOR 1.0

	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;
}
*/

/*--------------------------------------
	ThermoWindow

    Marc Wolfgram, 10/25/92 14:39:53
*/
/*GrafPortPtr ThermoWindow(word range, char *note)
{
GrafPortPtr winP, oldP;

    oldP = GetPort();
    winP = NewWindow2(0L, , 0L, 0L, 2, Thermo_Window, 0x800e);
	CenterWindow(winP);
	ShowWindow(winP);
    SetPort(winP);
    MoveTo(10,12);
    DrawCString(note);
    SetPort(oldP);
    return winP;
}
*/

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

	Marc Wolfgram,  1/ 5/92 10:53:57
*/

word OptimizeFile(void)
{
word i, j, typeCnt, resType, optFlag, nameFlag;
word retVal, curFile, curDepth, resAttr, srcFile, optFile, action, lastHit;
long resID, itemCnt, curFile2;
fResNameRec namePB;
GrafPortPtr winP, oldP;
Handle resData;
namePtr nameP;
nameSubPtr nameS;
Pointer oldPP;
RefNumRecGS flushRec;

    miscTaskRec.wmTaskMask = 0x1B2006L;

	oldPP = GetCtlParamPtr();
    SetCtlParamPtr((Pointer) &AlertArray);
    curFile = GetCurResourceFile();

    retVal = optFlag = nameFlag = 0;
    action = lastHit = 1;

    AlertArray[0] = &workList[workIndex].rootName[1];

    oldP = GetPort();
    winP = NewWindow2(0L, 0L, (VoidProcPtr) &DrawProc, 0L, 2, 0xef3L, 0x800e);
    SetPort(winP);
	CenterWindow(winP);
    SetCtlValue(lastHit, GetCtlHandleFromID(winP, 0x7039L));
	ShowWindow(winP);
	InitCursor();

    do {
        if (TaskMaster(0xffff, &miscTaskRec) == wInControl) {
            switch (miscTaskRec.wmTaskData4) {
            case 1L:    /* Optimize */
            case 2L:    /* Cancel */
                optFlag = miscTaskRec.wmTaskData4;
                break;

            case 3L:    /* Remove ResNames CheckBox */
                nameFlag = GetCtlValue(GetCtlHandleFromID(winP, 3L));

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

    CloseWindow(winP);
    SetPort(oldP);

    if (optFlag == 1) {

    	flushWorkFile(workIndex);
        closeREM(workIndex, 0);

   		KillPB.pCount = 1;
    	KillPB.pathname = &tempFile;
    	DestroyGS(&KillPB);

    	CreateResourceFile(1L, 0x5e, 0xc3, (Pointer) &tempFile);
    	optFile = OpenResourceFile(0x8003, 0L, (Pointer) &tempFile);

    	srcFile = workList[workIndex].resFileID;

        curDepth = SetResourceFileDepth(1);
        SetCurResourceFile(srcFile);

        nameP = (namePtr) *(workList[workIndex].resNameHndl);
        typeCnt = workList[workIndex].count;
        for (i = 0; i < typeCnt; i++) {
            if (nameP[i].nFlag & 0x4000) {
	            typeCnt++;
			    continue;
		    }
            resType = nameP[i].type;
            if (resType == 0x8014)
                continue;

            if (action & 0x0002) { /* process for type only */
                action &= 0x0080;
                action |= 0x0001;
            }

            nameS = (nameSubPtr) *(nameP[i].itemHndl);
		    itemCnt = nameP[i].count;
            for (j = 0; j < itemCnt; j++) {
			    MoonCursor();
        	    if (nameS[j].nFlag & 0x4000) {
	                itemCnt++;
			        continue;
		        }
                resID = nameS[j].id;

                if (resID > 0x07feffffL && resID < 0x8000000L) {
                    if (action & 0x0001) { /* process for item only */
                        SetCurResourceFile(fResID);
        			    resAttr = SetResourceFileDepth(-1);

    				    namePB.pCount = 3;
    				    namePB.resType = resType;
					    namePB.resName = &tempName[128];
    				    remGetStdTypeName(&namePB);
    				    sprintf(tempName, "%p - %0.8lX", &tempName[128], resID);
        			    AlertArray[0] = tempName;
                        SetCtlParamPtr(&AlertArray);

                        oldP = GetPort();
                        winP = NewWindow2(0L, 0L, (VoidProcPtr) &DrawProc, 0L, 2, 0xef6L, 0x800e);
                        SetPort(winP);
	                    CenterWindow(winP);
                        SetCtlValue(lastHit, GetCtlHandleFromID(winP, 0x7039L));
	                    ShowWindow(winP);
			            InitCursor();

                        for (;;) {
                            if (TaskMaster(0xffff, &miscTaskRec) == wInControl &&
                                            miscTaskRec.wmTaskData4 == 0x703aL)
                                 break;
                        }

                        action = lastHit = GetCtlValue(GetCtlHandleFromID(winP, 0x7039L));
                        CloseWindow(winP);
                        SetPort(oldP);
        	            resAttr = SetResourceFileDepth(1);
                        SetCurResourceFile(srcFile);

                    }
                    if (action & 0x0008) {
						deleteItem(workIndex, resType, resID);
                    	continue;
	           		}
                }
				resAttr = GetResourceAttr(resType, resID);
                SetResourceAttr(0, resType, resID);
                resData = LoadResource(resType, resID);
				DetachResource(resType, resID);

                SetCurResourceFile(optFile);
				AddResource(resData, 0, resType, resID);
				WriteResource(resType, resID);
                SetResourceAttr(resAttr, resType, resID);
                ReleaseResource(-1, resType, resID);

                SetCurResourceFile(srcFile);
	    	}
		}

        InitCursor();   /* the last 1.0.1 bug - James Smith found and
                           reported same about 3 hours before the show */
        if (nameFlag) {
            curFile2 = SetResFile2(fResID, -1);
            nameFlag = AlertWindow(0x0034, 0L, 25L);
            SetResFile1(curFile2);
        }
        if (nameFlag) /* remove resource names */
            killNames(workIndex);

        else {
		    resAttr = GetResourceAttr(rResName, 0x18014L);
            if (!toolerror()) {
                resData = LoadResource(rResName, 0x18014L);
		        DetachResource(rResName, 0x18014L);

                SetCurResourceFile(optFile);
		        AddResource(resData, resAttr, rResName, 0x18014L);
		        WriteResource(rResName, 0x18014L);
            }
        }
		CloseResourceFile(workList[workIndex].sysResID);
		CloseResourceFile(srcFile);

        workFile_s = (char) workIndex + 'a';

   		KillPB.pCount = 1;
    	KillPB.pathname = &workFile;
    	DestroyGS(&KillPB);

        CloseResourceFile(optFile);

		renPB.pCount = 2;
		renPB.pathname = (GSString255Ptr) &tempFile;
		renPB.newPathname = (GSString255Ptr) &workFile;
		ChangePathGS(&renPB);

    	workList[workIndex].sysResID = OpenResourceFile(0x8001, 0L, (Pointer) &sResFile);
        workList[workIndex].resFileID = OpenResourceFile(0x8003, 0L, (Pointer) &workFile);
        workList[workIndex].wFlag |= 0x4000;

	    SetCurResourceFile(curFile);
    	curDepth = SetResourceFileDepth(curDepth);

        InitCursor();
    }
	SetCtlParamPtr(oldPP);
	return retVal;
}

/*--------------------------------------
    MakeReferenceFile

	Marc Wolfgram,  4/26/92 11:12:31 PM
*/
word MakeReferenceFile(void)
{
char *c;
word i, j, k, typeCnt, resType, srcFile, fmtIdx, start;
long resID, itemCnt, output;
handle  h;
GSString255Ptr p;
GSString255Hndl refName;
namePtr nameP;
nameSubPtr nameS;
GrafPortPtr winP;

    output = 0L;

    refName = (GSString255Hndl) NewHandle(GetHandleSize(workList[workIndex].pathFile) + 2L, fMemID, 0x0018, 0L);

    p = (GSString255Ptr) *workList[workIndex].pathFile;
    strncpy((**refName).text, p->text, p->length);
    i = (p->length > 13) ? 13 : p->length;
    strcpy(&(**refName).text[i], ".n");
    (**refName).length = i + 2;

    SFPutFile2(SFPutH[vMode], 43, 2, 0x3005L, 1, (Ref) refName, &SFreply);

    DisposeHandle((Handle) refName);

    fmtIdx = 40 + ((**prefDataH).pFlag & 7);
        /* pFlag ref must change when we support xRef */

    if (SFreply.good) {
        h = (Handle) SFreply.nameRef;
        p = (GSString255Ptr) deref(h);
        c1cvt((char *) p);
        strncpy(&tempName[64], p->text, p->length);
        tempName[64 + p->length] = 0x00;
        sprintf(tempName, (char *) strings[48], &tempName[64]);
        winP = NoteWindow(tempName);
        DisposeHandle(h);

        h = (Handle) SFreply.pathRef;
        p = (GSString255Ptr) deref(h);
        c1cvt((char *) p);

        KillPB.pathname = refCreate.pathname = refOpen.pathname = p;

        KillPB.pCount = 1;
        refWritePB.pCount = 4;

        DestroyGS(&KillPB);
        CreateGS(&refCreate);
        OpenGS(&refOpen);

        DisposeHandle(h);

        refWritePB.refNum = refOpen.refNum;

        refWritePB.requestCount = (long) sprintf(tempName, (char *) strings[49]);
    	WriteGS(&refWritePB);

        nameP = (namePtr) *(workList[workIndex].resNameHndl);
        typeCnt = workList[workIndex].count;
        for (i = 0; i < typeCnt; i++) {
        	if (nameP[i].nFlag & 0x4000) {
	        	typeCnt++;
			    continue;
		    }
            resType = nameP[i].type;
            if (resType == 0x8014)
                continue;

            nameS = (nameSubPtr) *(nameP[i].itemHndl);
			itemCnt = nameP[i].count;
            start = 0;
            for (j = 0; j < itemCnt; j++) {
			    MoonCursor();
        	    if (nameS[j].nFlag & 0x4000) {
	        	    itemCnt++;
			        continue;
		        }
                if (nameS[j].nFlag & 0x8000) {
                    resID = nameS[j].id;
                    c = &nameS[j].name[10];
                    for (k = 192; *c; c++)
                        tempName[k++] = *c == ' ' ? '_' : *c;
                    tempName[k] = '\0';
    		        refWritePB.requestCount = (long) sprintf(tempName, (char *) strings[fmtIdx] + start, &tempName[192], resID);
    			    WriteGS(&refWritePB);
                    start = 1;
                    output++;
                }
            }
        }
        if (!output) {
            refWritePB.requestCount = (long) sprintf(tempName, (char *) strings[50]);
    	    WriteGS(&refWritePB);
        }

        refWritePB.pCount = 1;
        CloseGS(&refWritePB);

        CloseWindow(winP);
    }

    InitCursor();

    return 0;
}
