/*
   start.cc - Simple delays so the about window can be read...

   Marc Wolfgram, 25Jan91
 */
 
#pragma noroot
#pragma keep "o/start"

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

word 			adbWait(word);
remFileLinkPtr  buildFileLink(remFileLinkPtr, word, GSString255Ptr);
void			drawSplashText(word);
void            getVersionInfo(word);
void            justifyString(word, char *, word, word);
word            remLoader(remTypeLinkPtr);
void            remUnloader(remFileLinkPtr);
int             sortMenuProc(remTypeLinkPtr *, remTypeLinkPtr *);

/* in shell.asm... */
void DrawMenuBar2(void);
void fInitLoad2(GSString255Ptr, InitialLoadOutputRecPtr);

extern word fResID, pResID, vMode, moonIndex;
extern long callVector, *strings, moonTick, moonPhase[8];
extern remFileLinkPtr linkREM;
extern remTypeLinkPtr rootREM, rootSEM;
extern EventRecord fTaskRec, miscTaskRec;
extern master       MasterRace[];
extern GrafPortPtr  helpWin1;

struct vRes {
    long    v;
    word    c;
    char    t;
};
typedef struct vRes **vResHand;

word fMenuGlobal, AddMenuID, callFileID;
MenuTemplate **selectorMenuH;
long **selectorItemH, shVersion;
char tmpstr[40];
char vStr[10];

ResultBuf255    fNameEntry;
ResultBuf255    prefix8 = { 255 };

OpenRecGS       openPB = { 0, 0, (GSString255Ptr) &editPath };

DirEntryRecGS   dirPB = { 13, 0, 0, 1, 1, &fNameEntry };

PrefixRecGS     pfxPB = { 2, 8 };

fStartStopRec   start;

fResDataRec getVerPB = { 5, 0x8029, 1L };
fResRefRec  verRelPB = { 3, 0x8029, 1L };
fResDataRec strPB = { 5, 0x8007, 1L };

struct {
    char name[30], version[10], author[40];
} title;

Rect aboutRect[2] = {{1, 126, 41, 496 }, {41, 214, 61, 496 }};

segment "F_MISCCODE";

/*--------------------------------------
    startFailText is called by the Foundation function in shell.asm when
    something really bad happens during startup.

    Marc Wolfgram
*/
void startFailText(word err)
{
   GrafOff();
   printf("Error $%0.4X occurred during Foundation startup!\nPress <RETURN> to exit... ", err);
   getchar();
}

/*--------------------------------------
    openAboutWindow

    Marc Wolfgram, 10/16/91 23:11:38 (moved from about.c)
*/
GrafPortPtr openAboutWin(word ID)
{
GrafPortPtr retWinPtr;
word        vID, proto;

    proto = FALSE;
    if (ID == -1) {
        ID = 0;
        proto = TRUE;
    }

	vID = ID;
    if (ID == 0 || fTaskRec.modifiers & 0x1b00) /* apple shift option control */
        vID = fResID;

    getVersionInfo(vID);

    retWinPtr = NewWindow2(0L, 0L, 0L, 0L, 2, About_Window, rWindParam1);
    SetPort(retWinPtr);
    ShowWindow(retWinPtr);
    DrawOneCtl(GetCtlHandleFromID(retWinPtr, About_PicCtl));

    if (ID) {
    	if (fTaskRec.modifiers & 0x1b00) {
	    	for (;;) {
				drawSplashText(proto);
				if (adbWait(330))
					break;
				EraseRect(&aboutRect[0]);
				EraseRect(&aboutRect[1]);
        		justifyString(1, "Lunar Productions", 310, 15);
        		justifyString(1, "1808 Michael Drive", 310, 25);
        		justifyString(1, "Waukesha, Wisconsin  53186", 310, 35);
        		justifyString(1, "414/549-9261", 310, 45);
				if (adbWait(330))
					break;
				EraseRect(&aboutRect[0]);
				EraseRect(&aboutRect[1]);
        		justifyString(0, "AppleLink:", 145, 10);
        		justifyString(2, "D3672", 480, 10);
        		justifyString(0, "America Online:", 145, 20);
        		justifyString(2, "M Wolfgram, Jimurphy3", 480, 20);
        		justifyString(0, "GEnie:", 145, 30);
        		justifyString(2, "M.Wolfgram2, A2Pro.Jim", 480, 30);
        		justifyString(0, "internet:", 145, 40);
        		justifyString(2, "mwolfgram@aol.com", 480, 40);
        		justifyString(2, "Apple II Forever", 480, 55);
				if (adbWait(360))
					break;
				EraseRect(&aboutRect[0]);
				EraseRect(&aboutRect[1]);
        		justifyString(1, "Dedicated to John Kasper III", 310, 20);
        		justifyString(1, "Butch", 310, 30);
        		justifyString(1, "July 4, 1952 - January 20, 1992", 310, 40);
				if (adbWait(360))
					break;
				EraseRect(&aboutRect[0]);
				EraseRect(&aboutRect[1]);
            }
        }
        else {
        	sprintf(tmpstr, "%s  %s", title.name, title.version);
        	justifyString(1, tmpstr, 310, 10);
        	justifyString(1, title.author, 310, 20);
    		justifyString(1, "Copyright 1991-1992 by Lunar Productions", 310, 35);
        	sprintf(tmpstr, (char *) strings[11], (long) RealFreeMem()/1024L);
        	justifyString(2, tmpstr, 480, 55);
			adbWait(0);
      	}
    }
    else
    	drawSplashText(proto);

    return retWinPtr;
}

/*--------------------------------------
    getVersionInfo

    Marc Wolfgram, 10/16/91 23:13:28 (moved from about.c)
*/
void getVersionInfo(word ID)
{
char        *pstr;
vResHand    vHand;

    getVerPB.resFileID = ID;
    verRelPB.resFileID = ID;

    remLoadResource((fResDataRecPtr) &getVerPB);
    if (toolerror()) {
        strcpy(title.name,"REM name not available");
        strcpy(title.version,"0.0");
        strcpy(title.author,"REM author unknown");
    }
    else {
        HLock(getVerPB.resData);
        vHand = (vResHand) getVerPB.resData;
        if (ID == fResID)
            shVersion = (**vHand).v;
        VersionString(0, (**vHand).v, vStr);
        strncpy(title.version, p2cstr(vStr), 9);
        pstr = (char *) &(**vHand).t;
        strncpy(title.name, p2cstr(pstr), 29);
        strncpy(title.author, p2cstr(pstr + *pstr + 1), 39);

        remReleaseResource((fResRefRecPtr) &verRelPB);
    }
}

/*--------------------------------------
	drawSplashText

	Marc Wolfgram,  1/ 4/92 11:16:12
*/
void drawSplashText(word matt)
{
	justifyString(1, "Copyright 1991-1992 by Lunar Productions", 310, 10);
    if (matt) {
	    justifyString(1, "____________________________________________", 310, 25);
	    justifyString(1, "____________________________________________", 310, 37);
	    justifyString(1, "Wolfgram, Murphy & Collins", 310, 20);
	    justifyString(1, "Install a final version of System 6 soon!", 310, 35);
        justifyString(2, title.version, 480, 55);
	}
    else {
	    justifyString(0, "Marc Wolfgram", 210, 25);
	    justifyString(0, "Jim Murphy", 260, 35);
	    justifyString(0, "Mark Collins", 310, 45);
        justifyString(2, title.version, 480, 55);
    }
}

/*--------------------------------------
    remInit

    Marc Wolfgram, 10/16/91 23:14:57
*/
void remInit(void)
{
word remRFID, retVal, attr;
long idx, typeID, curFile;
remStartResHndl remHndl;
remTypeLinkPtr sPtr, tPtr;

    linkREM = 0L;
    rootREM = rootSEM = 0L;
    AddMenuID = 512;

    curFile = SetResFile2(pResID, 1);

    for (idx = CountResources(remType); idx > 0L; idx--) {
        MoonCursor();
        typeID = GetIndResource(remType, idx);
        attr = SetResAttr(remType, typeID);
        remHndl = (remStartResHndl) LoadResource(remType, typeID);
        SetResourceAttr(attr, remType, typeID);
        if ((**remHndl).version == 0 && (**remHndl).minShell <= shVersion)
            rootSEM = buildTypeLink(rootSEM, remHndl, 0L);  /* link later */
        ReleaseResource(-1, remType, typeID);
    }

    openPB.pCount = 2;
    OpenGS(&openPB);
    dirPB.refNum = openPB.refNum;

    pfxPB.buffer.getPrefix = (ResultBuf255Ptr) &prefix8;
    GetPrefixGS(&pfxPB);
    pfxPB.buffer.setPrefix = (GSString255Ptr) &editPath;
    SetPrefixGS(&pfxPB);

    for(;;) {
    	MoonCursor();
        fNameEntry.bufSize = 255;

        GetDirEntryGS(&dirPB);
        retVal = toolerror();
        if (!retVal) {
            if (dirPB.fileType != 0xBC || dirPB.auxType != 0x4006L)
                continue;

            fNameEntry.bufSize = fNameEntry.bufString.length + 2;
            fNameEntry.bufString.length = 0x3a38;    /* patch path to "8:" */

            remRFID = OpenResourceFile(1, 0L, (Pointer) &fNameEntry);
			if (toolerror())
				continue;

            linkREM = buildFileLink(linkREM, remRFID, (GSString255Ptr) &fNameEntry);

            for (idx = CountResources(remType); idx > 0L; idx--) {
                MoonCursor();
                typeID = GetIndResource(remType, idx);
                attr = SetResAttr(remType, typeID);
                remHndl = (remStartResHndl) LoadResource(remType, typeID);
                SetResourceAttr(attr, remType, typeID);
                if ((**remHndl).version == 0 && (**remHndl).minShell <= shVersion) {
                    if ((**remHndl).resType == 0 || (**remHndl).rFlag & 0x1000)
                	    rootSEM = buildTypeLink(rootSEM, remHndl, getFileLinkRef(remRFID));
                    else
                        rootREM = buildTypeLink(rootREM, remHndl, getFileLinkRef(remRFID));
                }
                ReleaseResource(-1, remType, typeID);
            }
        }
        else {
            if (retVal == endOfDir)
                retVal == 0;
            break;
        }
    }

    pfxPB.buffer.setPrefix = (GSString255Ptr) &prefix8.bufString;
    SetPrefixGS(&pfxPB);

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

    for (sPtr = rootSEM; sPtr != 0L; sPtr = sPtr->next) {
        if (sPtr->link != 0L) {
            for (tPtr = rootSEM; tPtr != sPtr; tPtr = tPtr->next)
                tPtr->link = sPtr->link;
            break;
        }
    }

    SetResFile1(curFile);
}

/*--------------------------------------
    buildFileLink

    Marc Wolfgram,  4/29/91 18:59:39
*/
remFileLinkPtr buildFileLink(remFileLinkPtr rPtr, word resFileID, GSString255Ptr rFile)
{
Handle rHndl;

    if (rPtr == 0L) {
        rHndl = NewHandle((long) sizeof (remFileLink), fMemID, 0xC018, 0L);
        rPtr = (remFileLinkPtr) deref(rHndl);
        rPtr->next = 0L;
        rPtr->resFileID = resFileID;
        rPtr->userID = 0;
        rPtr->active = 0;
        rPtr->entry = 0L;
        rPtr->fileName.length = rFile->length;
        strncpy(rPtr->fileName.text, rFile->text, (int) rFile->length);
    }
    else
        rPtr->next = buildFileLink(rPtr->next, resFileID, rFile);

    return rPtr;
}

/*--------------------------------------
    buildTypeLink

    Marc Wolfgram,  4/27/91 15:25:48
 */
remTypeLinkPtr buildTypeLink(remTypeLinkPtr rPtr, remStartResHndl srHndl, remFileLinkPtr link)
{
Handle rHndl;
struct remStartRes *srPtr;

    srPtr = (struct remStartRes *) deref((Handle) srHndl);
    if (rPtr == 0L) {
        rHndl = NewHandle((long) sizeof (remTypeLink), fMemID, 0xC018, 0L);
        rPtr = (remTypeLinkPtr) deref(rHndl);
        rPtr->next = 0L;
        rPtr->rFlag = srPtr->rFlag;
        rPtr->link = link;
        rPtr->resType = srPtr->resType;
        rPtr->itemID = 0;
        if (srPtr->rFlag & 0x8000)
            rPtr->itemID = AddMenuID++;
        if (srPtr->rMenuID == 0L)
            rPtr->menuHndl = 0L;
        else {
            rPtr->menuHndl = (MenuTemplate **) remLoadSpecial(rMenu, srPtr->rMenuID);
            (**rPtr->menuHndl).menuID = 5;
        }
        pstrncpy(rPtr->resName, (char *) &srPtr->resName[0], 31);
    }
    else if (rPtr->resType != srPtr->resType)
        rPtr->next = buildTypeLink(rPtr->next, srHndl, link);

    return rPtr;
}

segment "          ";

/*--------------------------------------
    getFileLinkRef

    Marc Wolfgram,  4/29/91 19:09:24
*/
remFileLinkPtr getFileLinkRef(word resFileID)
{
    remFileLinkPtr rPtr;

    rPtr = linkREM;

    while (rPtr != 0L) {
        if (rPtr->resFileID == resFileID)
            break;
        rPtr = rPtr->next;
    }

    return rPtr;
}

/*--------------------------------------
    getTypeLinkRef

    Marc Wolfgram,  4/28/91 10:10:19
 */
remTypeLinkPtr getTypeLinkRef(word resType)
{
word list;
remTypeLinkPtr rPtr;

    list = 0;
    rPtr = rootREM;

    while (resType != rPtr->resType) {
        rPtr = rPtr->next;
        if ((long) rPtr == 0L) {
            if (list)
                resType = 0;
            else
                list++;
            rPtr = rootSEM;
        }
    }
    return rPtr;
}

/*--------------------------------------
    getMenuLinkRef

    Marc Wolfgram,  5/ 1/91 20:05:54
 */
remTypeLinkPtr getMenuLinkRef(word itemID)
{
word list;
remTypeLinkPtr rPtr;

    list = 0;
    rPtr = rootREM;

    while (itemID != rPtr->itemID) {
        rPtr = rPtr->next;
        if ((long) rPtr == 0L && list == 0) {
            list++;
            rPtr = rootSEM;
        }
    }
    return rPtr;
}

/*--------------------------------------
    getREMTypeName

    Marc Wolfgram,  6/29/91 11:27:16
*/
char *getREMTypeName(word resType)
{
remTypeLinkPtr rPtr;

    for (rPtr = rootREM; rPtr; rPtr = rPtr->next)
        if (resType == rPtr->resType)
            return rPtr->resName;

    for (rPtr = rootSEM; rPtr; rPtr = rPtr->next)
        if (resType == rPtr->resType)
            return rPtr->resName;

    return (char *) 0L;
}

/*--------------------------------------
    disposeFileLink

    Marc Wolfgram,  4/29/91 19:33:34
 */
void disposeFileLink(remFileLinkPtr rPtr)
{
Handle rHndl;

    if (rPtr != 0L) {
        rHndl = FindHandle((Pointer) rPtr);
        HLock(rHndl);
        disposeFileLink(rPtr->next);
        remUnloader(rPtr);
        CloseResourceFile(rPtr->resFileID);
        DisposeHandle(rHndl);
    }
}

/*--------------------------------------
    disposeTypeLink

    Marc Wolfgram,  4/27/91 15:47:18
 */
void disposeTypeLink(remTypeLinkPtr rPtr)
{
Handle rHndl;

    if (rPtr != 0L) {
        rHndl = FindHandle((Pointer) rPtr);
        HLock(rHndl);
        disposeTypeLink(rPtr->next);
        if (rPtr->menuHndl != 0L)
            remTwiddleSpecial(rMenu, (Handle) rPtr->menuHndl, 2);
        DisposeHandle(rHndl);
    }
}

/*--------------------------------------
    remLoader

    Marc Wolfgram,  4/28/91 11:35:10
*/
word remLoader(remTypeLinkPtr rPtr)
{
word  retVal;
InitialLoadOutputRec  loadRec;

    start.edUserID = 0;
    retVal = 0;
    if (rPtr->link->userID == 0) {
        pfxPB.buffer.getPrefix = (ResultBuf255Ptr) &prefix8;
        GetPrefixGS(&pfxPB);
        pfxPB.buffer.setPrefix = (GSString255Ptr) &editPath;
        SetPrefixGS(&pfxPB);

        fInitLoad2((GSString255Ptr) &rPtr->link->fileName, (InitialLoadOutputRecPtr) &loadRec);
        retVal = toolerror();

        pfxPB.buffer.setPrefix = (GSString255Ptr) &prefix8.bufString;
        SetPrefixGS(&pfxPB);

        if (retVal == 0) {
            rPtr->link->entry = (long) loadRec.startAddr;
            start.edUserID = rPtr->link->userID = loadRec.userID;
            start.edResFileID = rPtr->link->resFileID;
            start.shResFileID = fResID;
            start.fdResFileID = pResID;
            SetVectors(rPtr->link->entry, rPtr->rFlag & 0x0004); /* APW ? */
        }
    }

    callFileID = rPtr->link->resFileID;
    callVector = rPtr->link->entry;

    if (start.edUserID)
        callREM(_STARTUP, (Pointer) &start);

    return retVal;
}

/*--------------------------------------
    remUnloader

    Marc Wolfgram,  5/19/91 12:34:22
*/
void remUnloader(remFileLinkPtr rPtr) {

    if (rPtr->userID != 0) {
        start.edUserID = rPtr->userID;
        start.edResFileID = rPtr->resFileID;
        callVector = rPtr->entry;
        callREM(_SHUTDOWN, (Pointer) &start);
        rPtr->userID = UserShutDown(rPtr->userID, 0);
        rPtr->userID = 0;
        rPtr->active = 0;
        rPtr->entry = 0L;
    }
}

segment "F_MISCCODE";

/*--------------------------------------
	adbWait

	Marc Wolfgram,  1/ 4/92 11:18:25
*/
word adbWait(word ticks)
{
word event;
long timeout;

	timeout = GetTick() + (long) ticks;
	do {
        if (ticks && GetTick() > timeout) {
        	event = 0;
	        break;
		}
        event = (GetNextEvent(-1, &miscTaskRec)) ? miscTaskRec.what : 0;
	} while (event != 1 && event != 3); /* hit adb and we're gone */
	return event;
}

/*--------------------------------------
    justifyString

   		CStr-	PStr-
	Left    0       3
	Center  1       4
	Right	2       5

	Marc Wolfgram, 12/ 8/91 17:00:15
*/
void justifyString(word mode, char *s, word h, word v)
{
	switch(mode) {
	case 0:
	case 3:
		MoveTo(h, v);
		break;

	case 1:
	    MoveTo(h-(CStringWidth(s)/2), v);
    	break;
    case 2:
	    MoveTo(h-(CStringWidth(s)), v);
    	break;

    case 4:
	    MoveTo(h-(StringWidth(s)/2), v);
    	break;

    case 5:
	    MoveTo(h-(StringWidth(s)), v);
    	break;
	}
    if (mode < 3)
    	DrawCString(s);
	else
		DrawString(s);
}

/*--------------------------------------
	MoonCursor - better than a spinning beachball - maybe...

	Mark Collins,   1/ 2/92 23:25:01
	Marc Wolfgram,  1/28/92 23:46:36 fixed bit 31 trash-o-rama
*/
void MoonCursor(void)
{
	word lastIndex;
	long tick, mask;

	if ((tick = GetTick()) > moonTick) {
		lastIndex = (moonIndex) ? moonIndex -1 : 7;
		mask = ((long) GetCursorAdr() == moonPhase[lastIndex]) ? 0x80000000L : 0L;
		SetCursor((Pointer) (moonPhase[moonIndex++] | mask));
    	moonTick = tick + 10L;
    	moonIndex &= 7;
	}
}

/*--------------------------------------
	stringInit

	Marc Wolfgram,  2/17/92 21:34:39
*/
void stringInit(void)
{
word i, j;
char *c;
struct SLP {
    word count;
    char text;
} *stringListPtr;

    strPB.resFileID = fResID;
    remLoadResource((fResDataRecPtr) &strPB);
    stringListPtr = (struct SLP *) deref((handle) strPB.resData);
    strings = (long *) *NewHandle((long) (stringListPtr->count * 4), fMemID, 0x8018, 0L);
    for (c = &stringListPtr->text, i = stringListPtr->count, j = 0; i; i--) {
        strings[j++] = (long) &c[1];
        c += c[0] + 1;
    }
}

word MasterMenu[14][8] = {
	{ 0x0001, UndoItem, 0 },
	{ 0x0002, CutItem, 0 }, /* copy and paste applied from editor */
	{ 0x0004, ClearItem, 0 },
	{ 0x0008, PageSetupItem,
			  PrintItem, 0 },
	{ 0x0010, SelectAllItem, 0 },
	{ 0x0020, CloseItem, 0 },
	{ 0x0040, NewItem,
			  OpenItem, 0 },
	{ 0x0080, SaveItem,
			  SaveAsItem,
			  ImportDataItem,
			  NameResItem,
			  MakeRefItem, 0 },
	{ 0x0100, AboutItem,
			  UserResourceItem,
			  HelpItem,
			  PreferencesItem, 0 },
	{ 0x0200, CloseFileItem,
			  OptimizeItem, 0 },
	{ 0x0400, CopyItem, 0 },
	{ 0x0800, PasteItem, 0 },
	{ 0x1000, 0 },
	{ 0x2000, 0 }
};

/*--------------------------------------
	SetupMenu - revised structure
					bit 15 - global incoming
				bits 0..13 - enabled mask

                    bit 14 - change enables set bit
				bits 0..13 - change mask


	Marc Wolfgram,  1/20/92 21:01:01
*/
void SetupMenu(word mbits)
{
int i, j, notmbits;

 	if ((mbits & 0x8000) == 0) { /* change globals per flag and mbits 0..13 */
     	if (mbits & 0x4000) 		/* these bits added to globals */
	    	fMenuGlobal |= (mbits & 0x3fff);
        else {            			/* these bits removed from globals */
            fMenuGlobal &= ((mbits ^ 0x3fff) & 0x3fff);
		}
        mbits = fMenuGlobal;
        fMenuGlobal |= 0x8000;
 	}

    for (i = 0; i < 14; i++) {
        if (mbits & MasterMenu[i][0]) {
    		for (j = 1; MasterMenu[i][j]; j++)
            	EnableMItem(MasterMenu[i][j]);
        }
        else {
    		for (j = 1; MasterMenu[i][j]; j++)
            	DisableMItem(MasterMenu[i][j]);
    	}
    }
}

/*--------------------------------------
	checkMenuFlag - revised structure

	Marc Wolfgram,  1/20/92 20:59:21
*/
void checkMenuFlag(word fFlag)
{
long *ID;
fWindowRecHndl  refH;

    if (fFlag & 0x0080) {
    	fMenuGlobal &= 0xfbe0;
    	fMenuGlobal |= (fFlag & 0x001f);
	    if (fFlag & 0x0002)
	    	fMenuGlobal |= 0x0c00;
        SetupMenu(fMenuGlobal);
    }
    if (helpWin1 && (fFlag & 0x0040)) {
        refH = (fWindowRecHndl) GetWRefCon(helpWin1);
        if ((**refH).remSignature == 1) {
            ID = (long *) callVector + 8;
            (**refH).resID = *ID;
            (**refH).resFileID = callFileID;
            updateHelp1(refH);
        }
    }
}

/*--------------------------------------
	setupTypeMenu does great things for the Type Window popup

	Marc Wolfgram,  1/21/92 23:04:25
*/
word setupTypeMenu(word resType, GrafPortPtr winP)
{
word i, item;
CtlRecHndl		menuBarH;
remTypeLinkPtr  remP;

	item = 0x2f0;

    if (winP) {
        menuBarH = GetMenuBar();
        SetMenuBar(GetCtlHandleFromID(winP, 1L));
    }

	remP = getTypeLinkRef(resType);

	/* first check the Edit Item for availability by type and mode */

    if (remP->resType != resType || remP->rFlag & 0x1000 || (!vMode && !(remP->rFlag & 0x0010))) {
    	DisableMItem(0x2f0);
		item = 0x2f1;
	}
 	else
    	EnableMItem(0x2f0);

	/* next check the Find xxx items from MasterRace */

    DisableMItem(0x2f6);
   	for (i = 0; MasterRace[i].rType; i++) {
    	if (MasterRace[i].rType == resType) {
            EnableMItem(0x2f6);
            break;
        }
    }

    /* last, check the Edit Using xxx items by mode and set item */

	if (vMode) {
    	EnableMItem(0x2f1);
        EnableMItem(0x2f2);
        EnableMItem(0x2f4);
	}
	else {
    	DisableMItem(0x2f1);
        DisableMItem(0x2f2);
        DisableMItem(0x2f4);
		if (item == 0x2f1)
			item = 0x2f3;
	}

    SetCtlValue(item, GetCtlHandleFromID(winP, 1L));

    if (winP)
        SetMenuBar(menuBarH);

	return item;
}

/*--------------------------------------
	setupItemMenu does so-so things for the Item Window popup

    Marc Wolfgram,  6/18/92  1:42:14
    Generalized     7/28/92 21:50:49
*/
word setupItemMenu(word defItem, word resType, GrafPortPtr winP)
{
word i, item;
CtlRecHndl		menuBarH;
remTypeLinkPtr  remP;

    item = defItem;

    menuBarH = GetMenuBar();
    SetMenuBar(GetCtlHandleFromID(winP, 1L));

    remP = getTypeLinkRef(resType);

	/* first check the Edit Item for availability by type and mode */

    if (remP->resType != resType || remP->rFlag & 0x1000 || (!vMode && !(remP->rFlag & 0x0010))) {
    	DisableMItem(0x2f0);
        if (defItem == 0x2f0)
            item = 0x2f1;
	}
 	else
    	EnableMItem(0x2f0);

    /* last, check the Edit Using xxx items by mode and set item */

	if (vMode) {
    	EnableMItem(0x2f1);
        EnableMItem(0x2f2);
	}
	else {
    	DisableMItem(0x2f1);
        DisableMItem(0x2f2);
		if (item == 0x2f1 || defItem == 0x2f1 || defItem == 0x2f2)
    	    item = 0x2f3;
	}
    DisableMItem(0x2f4);
    if (defItem == 0x2f4)
	    item = 0x2f3;

    SetCtlValue(item, GetCtlHandleFromID(winP, 1L));

    SetMenuBar(menuBarH);

	return item;
}

/*--------------------------------------
    sortMenuProc

    Marc Wolfgram,  5/ 7/91 23:18:27
*/
int sortMenuProc(remTypeLinkPtr *a, remTypeLinkPtr *b)
{
    return CompareStrings(0, (*a)->resName, (*b)->resName);
}

segment "          ";

/*--------------------------------------
    buildAddMenu

    Marc Wolfgram,  5/ 7/91 21:15:01
*/
void buildAddMenu(void)
{
int i;
long *itemArray, count;
Handle itemHndl, menuHndl;
MenuItemTemplate *item;
remTypeLinkPtr rPtr;

    if (AddMenuID > 512) {

        count = AddMenuID-512;

        menuHndl = NewHandle((count + 1L) * 4L, fMemID, 0x0018, 0L);
        itemArray = (long*) deref(menuHndl);

        i = 0;
        rPtr = rootREM;
        while(rPtr != 0L) {
            MoonCursor();
            if (rPtr->itemID != 0)
                itemArray[i++] = (long) rPtr;
            rPtr = rPtr->next;
        }
        rPtr = rootSEM;
        while(rPtr != 0L) {
            MoonCursor();
            if (rPtr->itemID != 0)
                itemArray[i++] = (long) rPtr;
            rPtr = rPtr->next;
        }
        itemArray[i] = 0L;

        qsort(itemArray, count, 4L, sortMenuProc);

        for (i = 0; itemArray[i] != 0L; i++) {
            MoonCursor();
            rPtr = (remTypeLinkPtr) itemArray[i];

            itemHndl = NewHandle(14L, fMemID, 0xC018, 0L);
            item = (MenuItemTemplate *) *itemHndl;
            item->version = 0;
            item->itemID = rPtr->itemID;
            item->itemChar = 0x00;
            item->itemAltChar = 0x00;
            item->itemCheck = 0;
            item->itemFlag = (rPtr->rFlag & 0x1000) ? 0 : 1;
            item->itemTitleRef = (Ref) rPtr->resName;
            InsertMItem2(1, (Ref) itemHndl, -1, 4);
            itemArray[i] = (long) itemHndl;
        }
        DisposeHandle((Handle) menuHndl);

        CalcMenuSize(0, 0, 4);
    }
}

/*--------------------------------------
    InsertMenu5

    Marc Wolfgram, 10/10/91 19:43:53
*/
void insertMenu5(MenuTemplate **templateH)
{
MenuRecHndl menuH;

    if (templateH) {
    	remTwiddleSpecial(rMenu, (Handle) templateH, 0);
        menuH = GetMHandle(5);
        if (menuH)
            DeleteMenu(5);
        menuH = NewMenu2(1, (Ref) templateH);
        InsertMenu(menuH, 4);
        FixMenuBar();
        DrawMenuBar2();
    }
    return;
}

/*--------------------------------------
    removeMenu5

    Marc Wolfgram, 10/10/91 19:44:09
*/
void removeMenu5(void)
{
word i;
long *iList;
MenuRecHndl menuH;

    menuH = GetMHandle(5);
    if (menuH) {
        DeleteMenu(5);
        DrawMenuBar2();
        DisposeMenu(menuH);
    }
    if (selectorMenuH) {
 		remTwiddleSpecial(rMenu, (Handle) selectorMenuH, 3);
		selectorMenuH = 0L;
	}

    if (selectorItemH) {
 		iList = (long *) deref((Handle) selectorItemH);
       	for (i = 0; iList[i] != 0L; i++)
	 		remTwiddleSpecial(rMenuItem, (Handle) iList[i], 3);
		DisposeHandle((Handle) selectorItemH);
		selectorItemH = 0L;
	}
    return;
}
