/*
   scrap.c - the clipboard lives here...

   Marc Wolfgram, 11Mar92
   ----------------------------------------------------------------
 */

#pragma noroot
#pragma keep "o/scrap"

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

void OpenHelp(void);
void ItemProc(void);
void drawItemText(char *, word);
void drawRectText(CtlRecHndl, char *, word);
void hiliteRect(CtlRecHndl);
void allocItemList(GrafPortPtr, word, long);

struct pScrap {
	word 		scb;
	Rect		frame;
};
typedef struct pScrap *pScrapPtr;

struct rScrap {
	word		scrapType;
	long		scrapID;
	GSString255	scrapPath;
};
typedef struct rScrap rScrap, *rScrapPtr, **rScrapHndl;

union scrap {
	Pointer		gPtr;
	rScrapPtr	rPtr;
	pScrapPtr	pPtr;
};
typedef union scrap scrap;

extern word workIndex, fMenuGlobal, wClass, c320, CurMurphy, fResID, pResID, fScrapCnt, vMode;
extern long	*strings, callVector;
extern char *AlertArray[], tempName[];
extern workFileRec  workList[];  /* work file array [0..3] */
extern void AttrProc(), DrawProc(), NullProc(), PrefProc(), ClipProc();
extern GrafPortPtr  SysWPtr, helpWin1, helpWin2;
extern WindColorPtr WColors[];
extern EventRecord  miscTaskRec;
extern prefDataHndl prefDataH;
extern master       MasterRace[];
extern fWindowRec	CurWindow;
extern EventRecord  fTaskRec;
extern remFileLinkPtr   linkREM;
extern remTypeLinkPtr   rootREM;
extern fResNameRec namePB;
extern fResLinkRec fBuildLinkPB;
extern SFReplyRec2  SFreply;
extern int          SFPutH[];
extern NameRecGS    KillPB;
extern Point        winLoc[];

fResRefRec		refPB;
fResDataRec     dataPB;
fResData2Rec    chngPB;


word bitFlags[] = {
        0x4000, 0x0800, 0x0080, 0x0040, 0x0010, 0x0008, 0x0004, 0x8000,
        0xbfff, 0xf7ff, 0xff7f, 0xffbf, 0xffef, 0xfff7, 0xfffb, 0x7fff };
word copyFlag;
long dAlert[] = {0xfL, 0xeL, 0x12L, 0x13L, 0x14L};
char dText[128];

byte normMask[8];
byte dehiMask[8] = { 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa };

TEFormat HelpStyle = { 0, 18L, { 4, 0, 268, 0, 0, 0, 0L, 0}, 12L,
    { 0x08000000, 0xF, 0, 0L }, 1, { 0xFFFFFFFFL, 0x0L } };

CreateRecGS	    xCreatePB = { 3, 0L, 0xc3, 0x06 };
IORecGS		    xWritePB;

GSString32      defName;

segment "F_MISCCODE";

/*--------------------------------------
	itemCopy - TypeSelector copy support

	Marc Wolfgram,  3/11/92 21:15:20
*/
void itemCopy(void)
{

word            i, j, listItem, hostType, clipResFile, curResFile;
long            hostID, clipID;
GrafPortPtr     winP;
fListCtlRecHndl ctlH;
NameRecGS 		KillPB;
fMemberHndl     memH;
fMemberPtr      memP;
rScrapPtr		scrapP;
rScrapHndl		scrapH;
ExpandPathRecGS expandPB;

	/* call findparent code recursively to get to the top */

    copyFlag = 9;
	hostType = CurWindow.resType;

   	KillPB.pCount = 1;
    KillPB.pathname = &clipFile;
    DestroyGS(&KillPB);
    curResFile = GetCurResourceFile();
    CreateResourceFile(1L, 0x5e, 0xc3, (Pointer) &clipFile);
	clipResFile = OpenResourceFile(0x8003, 0L, (Pointer) &clipFile);
	if (toolerror()) {
		/* error opening scrap file */
		return;
	}

    winP = findSignature(REM_signature + REM_tselector + workIndex, 0, hostType, 0L);
  	ctlH = (fListCtlRecHndl) GetCtlHandleFromID(winP, 2L);
    if (listItem = NextMember2(0, (Handle) ctlH)) {
        memH = (**ctlH).ctlListRef;
        memP = (fMemberPtr) deref((Handle) memH);
        hostID = memP[listItem-1].nref;
        clipID = CopyResource(workList[workIndex].resFileID, clipResFile, hostType, hostID);

		scrapH = (rScrapHndl) NewHandle((long) sizeof(struct rScrap), fMemID, 0x0018, 0L);
        scrapP = (rScrapPtr) deref((Handle) scrapH);

        expandPB.pCount = 2;
        expandPB.inputPath = &clipFile;
        expandPB.outputPath = (ResultBuf255Ptr) &scrapP->scrapID;
        asm {
        	inc expandPB+6		/* sorry for this, I'll worry */
			inc expandPB+6		/* about cleaning it up later */
		}
        scrapP->scrapID = 0xff0000L;
		ExpandPathGS(&expandPB);

        scrapP->scrapType = hostType;
        scrapP->scrapID = clipID;

        ZeroScrap();
        PutScrap((long) sizeof(struct rScrap), 0x8003, (Pointer) scrapP);
    	DisposeHandle((Handle) scrapH);
        SetupMenu(0x4800);
    }

    CloseResourceFile(clipResFile);
    SetCurResourceFile(curResFile);
	InitCursor();
}

/*--------------------------------------
	itemPaste - resourceScrap family paste

	Marc Wolfgram,  3/29/92 16:19:51
*/
void itemPaste(void)
{
word            i, clipType, clipResFile, curResFile;
long            clipID, copyID, curFile;
rScrapHndl		scrapH;
fResNameRec     namePB;

    copyFlag = 1;
	scrapH = (rScrapHndl) GetScrapHandle(0x8003);
    if (!toolerror()) {
    	curResFile = GetCurResourceFile();
		clipResFile = OpenResourceFile(0x8003, 0L, (Pointer) &(**scrapH).scrapPath);
		if (!toolerror()) {

			clipType = (**scrapH).scrapType;
    		clipID = (**scrapH).scrapID;
    		copyID = CopyResource(clipResFile, workList[workIndex].resFileID, clipType, clipID);

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

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

    		InitCursor();

            curFile = SetResFile2(fResID, -1);

    		if (clipID != copyID) {
    			sprintf(&tempName[128], "%0.8lX", copyID);
    			i = AlertWindow(0x0034, (Pointer) AlertArray, 24L);
			}
			else
 				i = AlertWindow(0x0034, (Pointer) AlertArray, 23L);

            SetResFile1(curFile);

    		CloseResourceFile(clipResFile);
    		SetCurResourceFile(curResFile);
		}
	}
}

/*--------------------------------------
    showClipboard

    Marc Wolfgram, 11/29/91 15:53:49
*/
void showClipboard(void)
{
GrafPortPtr     winP;
fWindowRecPtr   refP;
fWindowRecHndl  refH;

    winP = findSignature(0x48e5, 1, 0, 0L);
    if (!winP) {
        refH = (fWindowRecHndl) NewHandle(20L, fMemID, 0x0018, 0L);
        refP = (fWindowRecPtr) deref((Handle) refH);
        refP->Signature     = 0x48e5;
        refP->resType       = 0;
        refP->resID         = 0L;
        refP->resFileID     = 0;
        refP->remTaskMask   = 0x001f7fffL;
        refP->remSignature  = 0;
        refP->resPrivate    = 0L;
        HUnlock(refH);

        winP = NewWindow2(0L, (Long) refH, (VoidProcPtr) &ClipProc, 0L, 2, Clip_Window, 0x800e);
		CenterWindow(winP);
		ShowWindow(winP);
        SetPort(winP);
        SetOriginMask(0xfffe, winP);
    }
}

/*--------------------------------------
    checkClipboard

    Marc Wolfgram, 11/29/91 15:54:10
*/
void checkClipboard(void)
{
word scrapCnt;
Rect clipRect;
GrafPortPtr     winP, oldP;
fWindowRecPtr   refP;
fWindowRecHndl  refH;

    scrapCnt = GetScrapCount();
    if (scrapCnt != fScrapCnt) {
        fScrapCnt = scrapCnt;
        winP = findSignature(0x48e5, 0, 0, 0L);
        if (winP) {
            oldP = GetPort();
            SetPort(winP);
            GetPortRect(&clipRect);
            EraseRect(&clipRect);
            InvalRect(&clipRect);
            SetPort(oldP);
        }
    }
    return;
}

/*--------------------------------------
	Extended support for the clipProc

	Marc Wolfgram,  4/13/92  9:29:29 PM
*/
void drawClipboard(void)
{
word 		i;
Long		scrapSize, shamu;
Handle		scrapH;
scrap 		sP;
Rect		clipRect;
Point 		clipTemp;
fResNameRec	namePB;

	scrapH = GetScrapHandle(0x0000); /* text scrap */
	if (!toolerror()) {
		scrapSize = GetScrapSize(0x0000);

	    GetPortRect(&clipRect);
/*    	(long) clipTemp = GetContentOrigin(GetPort());  */
        shamu = GetContentOrigin(GetPort());
        asm {
            lda >shamu
            sta >clipTemp
            lda >shamu+2
            sta >clipTemp+2
        }
		clipRect.v1 -= clipTemp.v;
		clipRect.h1 -= clipTemp.h;

    	LETextBox(*scrapH, (word) scrapSize, &clipRect, 0);
		return;
	}

    scrapH = GetScrapHandle(0x0001); /* picture scrap */
    if (toolerror())
    	scrapH = GetScrapHandle(0x8001); /* mask scrap */
	if (!toolerror()) {
		sP.gPtr = deref(scrapH);
		clipRect.v1 = sP.pPtr->frame.v1;
		clipRect.h1 = sP.pPtr->frame.h1;
		clipRect.v2 = sP.pPtr->frame.v2;
		clipRect.h2 = sP.pPtr->frame.h2;
		HUnlock((Handle) scrapH);
		DrawPicture(scrapH, &clipRect);
		return;
    }

    scrapH = GetScrapHandle(0x0002); /* sound scrap */
	if (!toolerror()) {
        MoveTo(10,10);
	    DrawCString((Pointer) strings[32]);
		return;
    }

	scrapH = GetScrapHandle(0x0064); /* textedit style */
	if (!toolerror()) {
        MoveTo(10,10);
	    DrawCString((Pointer) strings[33]);
		return;
    }

	scrapH = GetScrapHandle(0x4945); /* icon
		word iDataLen (null is end of list)
			c064 iDataBoss (path)
				c016 iDataName (file)
					word iDataType
						word iDataAux
							byte iDataBig (icon image)
								byte iDataSmall */
	if (!toolerror()) {
		return;
    }

	scrapH = GetScrapHandle(0x8002); /* color table scrap */
	if (!toolerror()) {
        MoveTo(10,10);
	    DrawCString((Pointer) strings[34]);
		return;
    }

	scrapH = GetScrapHandle(0x8003); /* resource reference scrap */
	if (!toolerror()) {
		sP.gPtr = deref(scrapH);

    	namePB.pCount = 3;
    	namePB.resType = sP.rPtr->scrapType;
		namePB.resName = &tempName[128];
    	remGetStdTypeName(&namePB);
    	sprintf(tempName, (char *) strings[35], &tempName[128], sP.rPtr->scrapID);
        HUnlock((Handle) scrapH);

        MoveTo(10,10);
	    DrawCString((Pointer) tempName);
		return;
    }
}

/*--------------------------------------
    ListDispatcher

    Marc Wolfgram,  6/ 4/92  6:57:03 PM
*/
void listDispatcher(word action, word type, long ID)
{
GrafPortPtr found;

    switch (action) {
    case 1:                     /* root - open a type/custom selector */
        type = (word) ID;
        found = findSignature(REM_signature + REM_nselector + workIndex, 1, type, 0L) +
                       findSignature(REM_signature + REM_tselector + workIndex, 1, type, 0L);
        if (!found)
            openTypeWindow(workIndex, type);
        break;

    case 2:                     /* root - display the type info alert */
        type = (word) ID;
        showTypeInfo(workIndex, type);
        break;

    case 0x2f0:       			/* std selector - open the editor or  */
    case 0x2f1:         		/*                         script or  */
    case 0x2f2:                 /*                         HexEdit    */
        openEditor(type, ID, action & 3);
        break;

    case 0x2f3:                 /* std selector - edit the attributes */
        editAttributes(type, ID);
        break;

    case 0x2f4:                 /* std selector - death to this item! */
        deleteRequested(type, ID);
        break;

    case 0x2f5:                 /* std selector - export to some file */
        exportRequested(type, ID);
        break;

    case 0x2f6:					/* show item dependents */
        dependentsRequested(type, ID);
        break;

    default:                    /* something else - we are mystified! */
        break;
    }
}

/*--------------------------------------
    editAttributes - saved the best, rewrote the rest

    Marc Wolfgram, 10/23/91 21:10:17

        AlertArray[1]   tempName[0]     resID
        AlertArray[2]   tempName[64]    newID
                        tempName[128]   resName
                        tempName[192]   resType/name/file
*/
word editAttributes(word resType, long resID)
{
word i, task, retVal, attr, dirtyID, invalID, done, nlen, bit, chngErr;
GrafPortPtr winP, found, oldP;
nameSubPtr chngSubP;

    miscTaskRec.wmTaskMask = 0x1B2006L;

    done = dirtyID = invalID = 0;
    AlertArray[1] = &tempName[0];
    AlertArray[2] = &tempName[64];

/* set PB constants */

    dataPB.pCount = 4;
    chngPB.pCount = namePB.pCount = 3;
    dataPB.resType = chngPB.resType = namePB.resType = resType;
    dataPB.resID = chngPB.resID = namePB.resID = resID;

    remGetResourceAttr(&dataPB);
    retVal = toolerror();
    if (retVal)
        return retVal;

    namePB.resName = &tempName[64];
    remGetStdTypeName(&namePB);
    if (tempName[64])
        nlen = sprintf(&tempName[192], "*%0.4X %p (%c)", resType, &tempName[64], (char) workIndex + '1');
    else
        nlen = sprintf(&tempName[192], "*%0.4X (%c)", resType, (char) workIndex + '1');
    tempName[192] = (char) nlen - 1;

    namePB.resName = &tempName[128];
    remGetResourceName(&namePB);
    if (!tempName[128])
        sprintf(&tempName[128], (char *) strings[29]);

    sprintf(&tempName[0], "\x08%0.8lX", resID);

/* check to see if ID's can be changed */

   found = findSignature(REM_signature + REM_native + workIndex, 0, resType, resID)
                + findSignature(REM_signature + REM_script + workIndex, 0, resType, resID)
                + findSignature(REM_signature + REM_hexascii + workIndex, 0, resType, resID);
   if (found)
       invalID++;

/* open the attributes window */

    oldP = GetPort();
    winP = NewWindow2(0L, 0L, (VoidProcPtr) &AttrProc, 0L, 2, 0xffbL, 0x800e);
	CenterWindow(winP);
    SetPort(winP);

    SetLETextByID(winP, 3L, (StringPtr) &tempName[0]);
    if (invalID) {
       i = AlertWindow(0x0035, (Pointer) AlertArray, 11L);
       HiliteControl(0x00ff, GetCtlHandleFromID(winP, 3L));
    }

    ShowWindow(winP);

    SetCtlValue((dataPB.special & 0x0300) + 1,GetCtlHandleFromID(winP, 4L));

    for (i = 0; i < 8; i++)
        if (dataPB.special & bitFlags[i])
            SetCtlValue(1,GetCtlHandleFromID(winP, (long) i + 5));

    do {
        retVal = 0;
        task = TaskMaster(0xffff, &miscTaskRec);
        if (task == wInControl) {
            switch (miscTaskRec.wmTaskData4) {
            case 1L:                                        /* ok button */
                attr = dataPB.special;

                bit = GetCtlValue(GetCtlHandleFromID(winP, 4L)) - 1;
                attr &= 0xfcff;
                attr |= bit;

                for (i = 0; i < 8; i++) {
                    bit = GetCtlValue(GetCtlHandleFromID(winP, (long) i+5));
                    if (bit)
                        attr |= bitFlags[i];
                    else
                        attr &= bitFlags[i+8];
                }

                if (dirtyID) {
                    GetLETextByID(winP, 3L, (StringPtr) &tempName[64]);
                    chngPB.result = Hex2Long(&tempName[65], (word) tempName[64]);
                    chngErr = toolerror();

                    if (resID != chngPB.result) {

                        if (!chngPB.result || chngPB.result & 0xf8000000L || chngErr) {
                            i = AlertWindow(0x0035, (Pointer) AlertArray, 10L);
                            SetLETextByID(winP, 3L, (StringPtr) &tempName[0]);
                            dirtyID = 0;
                            break;
                        }

                        chngSubP = getNameSubRec(workIndex, resType, chngPB.result);
                        if (chngSubP) {
                            i = AlertWindow(0x0035, (Pointer) AlertArray, 12L);
                            SetLETextByID(winP, 3L, (StringPtr) &tempName[0]);
                            dirtyID = 0;
                            break;
                        }

                        if (chngPB.result > 0x07FEFFFFL) {
                            if (AlertWindow(0x0035, (Pointer) AlertArray, 22L)) {
                            	SetLETextByID(winP, 3L, (StringPtr) &tempName[0]);
                            	dirtyID = 0;
                                break;
                            }
                        }
                        else {
                            if (AlertWindow(0x0035, (Pointer) AlertArray, 13L)) {
                                SetLETextByID(winP, 3L, (StringPtr) &tempName[0]);
                                dirtyID = 0;
                                break;
                            }
                        }
                        remSetResourceID(&chngPB);
                        dataPB.resID = chngPB.result;
                    }
                }
                if (dataPB.special != attr) {
                    dataPB.special = attr;
                    remSetResourceAttr(&dataPB);
                }
                done++;
                break;

            case 2L:                                        /* cancel button */
                done++;
                break;

            case 3L:                                        /* id line edit */
                dirtyID++;
                break;

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

    SetPort(oldP);
    CloseWindow(winP);
    return retVal;
}

/*--------------------------------------
	deleteRequested

	Marc Wolfgram and Mark Collins,  1/ 3/92  0:40:59
*/
word deleteRequested(word resType, long resID)
{
word 			done, retVal, i, dType, hostType, dependents, task;
long			hostID;
Pointer			oldPP;
resLinkRecHndl 	linkH;
GrafPortPtr		winP, oldP;
resLinkRecPtr   linkP;
Rect            dRect;

	oldPP = GetCtlParamPtr();

    miscTaskRec.wmTaskMask = 0x1B2006L;

	done = dependents = hostType = 0;
	hostID = 0L;

    refPB.pCount = 2;
	namePB.pCount = 3;
	namePB.resType = resType;
	namePB.resID = resID;
    namePB.resName = tempName;
    remGetWindowTitle(&namePB);
	sprintf(dText, "%p", tempName);
    AlertArray[0] = dText;		/* use as a cStr */
	dType = 4;					/* default for non-standard type */
	for (i = 0; MasterRace[i].rType; i++) {
		if (MasterRace[i].rType == resType) {
			dType = MasterRace[i].dType;
    		AlertArray[1] = (char *) strings[dType+35]; /* use as a cStr */
			break;
		}
    }
    retVal = AlertWindow(0x0034, (Pointer) AlertArray, dAlert[dType]);
	if (retVal == 1) {		/* blow the sucker away */
		refPB.resType = resType;
		refPB.resID = resID;
        retVal = remRemoveResource(&refPB);
	}
	else if (retVal) {        /* I want the sucker and his whole family blown away */
        SetCtlParamPtr((Pointer) &AlertArray);
		oldP = GetPort();
        winP = NewWindow2(0L, 0L, (VoidProcPtr) &DrawProc, 0L, 2, 0xefaL, 0x800e);
    	SetPort(winP);
		ShowWindow(winP);
		DrawControls(winP);

        MoveTo(15,48);
        if (dType & 2) { /* item has parents ( dType is 2 or 3) */
            WaitCursor();

            MoveTo(15,48);
			DrawCString((Pointer) strings[52]);
			MoveTo(15,48);

            linkH = remFindOwner(resType, resID);
            while ((linkH) && (**linkH).count == 1){
                hostType = (**linkH).ref[0].hostType;
                hostID = (**linkH).ref[0].hostID;
				DisposeHandle((handle) linkH);
        		linkH = remFindOwner(hostType, hostID);
			}
			if (linkH)
				DisposeHandle((handle) linkH);

            if (hostType) {
        		HiliteControl(0x00, GetCtlHandleFromID(winP, 0x702eL));
				namePB.pCount = 3;
				namePB.resType = hostType;
				namePB.resID = hostID;
            	namePB.resName = tempName;
            	remGetWindowTitle(&namePB);
               	sprintf(&tempName[128], (char *) strings[25], tempName);
				DrawCString((Pointer) &tempName[128]);
			}
			else
				DrawCString((Pointer) strings[53]);

            InitCursor();
        }
        else
			DrawCString((Pointer) strings[54]);

		if (dType & 1) { 	/* may have children */
			MoveTo(15,58);
			DrawCString((Pointer) strings[55]);
			MoveTo(15,58);
            fBuildLinkPB.pCount = 4;
            fBuildLinkPB.index = 0;
            fBuildLinkPB.hostType = resType;
            fBuildLinkPB.hostID = resID;
			retVal = remBuildLinkHand(&fBuildLinkPB);   /* callback parameter blocks */
        	dependents = fBuildLinkPB.index;
			DrawCString((Pointer) strings[dependents ? 56 : 57 ]);
        	if (dependents)
	        	HiliteControl(0x00, GetCtlHandleFromID(winP, 0x702fL));
        }
        else {
            MoveTo(15,58);
			DrawCString((Pointer) strings[58]);
    	}
        HiliteControl(0x0000, GetCtlHandleFromID(winP, 0x702dL));
	    HiliteControl(0x0000, GetCtlHandleFromID(winP, 0x7030L));
    	do {
        	retVal = 0;
        	task = TaskMaster(0xffff, &miscTaskRec);
        	if (task == wInControl) {
            	switch (miscTaskRec.wmTaskData4) {
				case 0x702dL:  		/* delete single item */
					refPB.resType = resType;
					refPB.resID = resID;
        			retVal = remRemoveResource(&refPB);
                    done++;
                    break;

            	case 0x702eL:      /* delete from parent */
                    MoonCursor();
					if (dependents)
						DisposeHandle(fBuildLinkPB.linkHand);
            		fBuildLinkPB.pCount = 4;
            		fBuildLinkPB.index = 0;
            		fBuildLinkPB.hostType = hostType;
            		fBuildLinkPB.hostID = hostID;
					retVal = remBuildLinkHand(&fBuildLinkPB);   /* callback parameter blocks */

                case 0x702fL:      /*  delete from item */
					linkP = (resLinkRecPtr) deref(fBuildLinkPB.linkHand);
					dependents = linkP->count;
					for (i = 0; i < dependents; i++) {
                    	MoonCursor();
                        refPB.resType = linkP->ref[i].resType;
						refPB.resID = linkP->ref[i].resID;
        				retVal = remRemoveResource(&refPB);
                    }
					refPB.resType = linkP->ref[0].hostType;
					refPB.resID = linkP->ref[0].hostID;
        			retVal = remRemoveResource(&refPB);

                    DisposeHandle(fBuildLinkPB.linkHand);

            	case 0x7030L:   	/* cancel */
                	done++;
	        		InitCursor();
                	break;

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

    	SetPort(oldP);
    	CloseWindow(winP);
        SetCtlParamPtr(oldPP);
    }
    return retVal;
}

/*--------------------------------------
    exportRequested

    Mark Collins,  6/19/92 10:35:37 PM
*/
word exportRequested (word resType, long resID)
{
word 			retVal;
GSString255Hndl	h;
GrafPortPtr     winP;

    defName.length = sprintf(defName.text, "Res%0.4X.%lX", resType, resID);

	retVal = 0;
	SFPutFile2(SFPutH[vMode], 43, 2, 0x3003L, 0, (Ref) &defName, &SFreply);
	if (SFreply.good) {
        h = (GSString255Hndl) SFreply.nameRef;
    	c1cvt((char *) *h);
        (**h).text[(**h).length] = 0x00;
        sprintf(defName.text, "Writing %s...", (**h).text);
        winP = NoteWindow(defName.text);

        h = (GSString255Hndl) SFreply.pathRef;
    	c1cvt((char *) *h);

        KillPB.pCount = 1;
        KillPB.pathname = (GSString255Ptr) *h;
        DestroyGS(&KillPB);

	    xCreatePB.pathname = (GSString255Ptr) *h;
		CreateGS(&xCreatePB);
        retVal = toolerror();
		if (!retVal) {
            xWritePB.pCount = 2;
        	xWritePB.dataBuffer = (Pointer) *h;
		    OpenGS(&xWritePB);
            retVal = toolerror();
		    if (!retVal) {

        		dataPB.pCount = 3;
		        dataPB.resType = resType;
		        dataPB.resID = resID;
 		        remLoadResource(&dataPB);

		        xWritePB.pCount = 4;
		        xWritePB.dataBuffer = (Pointer) *(dataPB.resData);
		        xWritePB.requestCount = GetHandleSize(dataPB.resData);
		        WriteGS(&xWritePB);
                retVal = toolerror();

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

                dataPB.pCount = 2;
                remReleaseResource((fResRefRecPtr) &dataPB);
            }
        }
        DisposeHandle((Handle) h);
        DisposeHandle((Handle) SFreply.nameRef);
        CloseWindow(winP);
	}

    return retVal;
}

/*--------------------------------------
    dependentsRequested

    Marc Wolfgram,  6/19/92 12:54:23 AM
*/
word dependentsRequested(word resType, long resID)
{
word i, count, retVal, hostIdx, itemIdx, itemCtl, linkGood;
Handle			winH;
GrafPortPtr     winP;
fWindowRecHndl  refH;
fWindowRecPtr   refP;
CtlRecHndl      ctlH;
resLinkRecHndl  linkH, oldH;
resLink        *linkP;

    linkGood = 0;

    winP = findSignature(REM_signature + REM_dselector + workIndex, 0, 0, 0l);
    if (winP) {
        SetPort(winP);
        refH = (fWindowRecHndl) GetWRefCon(winP);
        linkH = (resLinkRecHndl) (**refH).resPrivate;
        HLock((Handle) linkP);
        count = (**linkH).count;
        linkP = (**linkH).ref;

        itemCtl = linkP[0].hostID;
        hostIdx = linkP[0].hostHitTick;
        itemIdx = linkP[0].resHitTick;

        switch (itemCtl) {
        case 2:
            if (linkP[itemIdx].resType == resType && linkP[itemIdx].resID == resID) {
                hostIdx = itemIdx;
                linkGood++;
            }
            break;

        case 3:
            if (linkP[hostIdx].hostType == resType && linkP[hostIdx].hostID == resID) {
                for (i = 0; i < hostIdx; i++) {
                    MoonCursor();
                    if (linkP[i].resType == resType && linkP[i].resID == resID) {
                        itemIdx = hostIdx = i;
                        linkGood++;
                        break;
                    }
                }
            }
            break;

        case 4:
            if (linkP[hostIdx].resType == resType && linkP[hostIdx].resID == resID) {
                SelectWindow(winP);
                return;
            }
            break;
        }

        if (!linkGood) {
            for (i = 0; i < count; i++) {
                MoonCursor();
                if (linkP[i].resType == resType && linkP[i].resID == resID) {
                    hostIdx = itemIdx = i;
                    linkGood++;
                    break;
                }
            }
        }

        if (linkGood) {
            linkP[0].hostID = 4L;
            linkP[0].hostHitTick = hostIdx;
            linkP[0].resHitTick = itemIdx;
        }
        else {
			DisposeHandle((Handle) linkH);
            (**refH).resPrivate = (Handle) buildItemLink(resType, resID);
        }
        HUnlock((Handle) linkH);
        allocItemList(winP, resType, resID);
        SelectWindow(winP);
    }
    else {
        refH = (fWindowRecHndl) NewHandle(20L, fMemID, 0x0018, 0L);

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

        refP = (fWindowRecPtr) deref((Handle) refH);
        refP->Signature     = REM_signature + REM_dselector + workIndex;
        refP->remTaskMask   = 0x001f7fffL;
        refP->resFileID     = workList[workIndex].resFileID;
        refP->resPrivate    = (Handle) buildItemLink(resType, resID);
        HUnlock((Handle) refH);

        winP = NewWindow2((Pointer) strings[61 + workIndex], (Long) refH, (VoidProcPtr) &ItemProc, 0L, 1, (Ref) winH, 0x800e);
        SetPort(winP);
        MoveWindow(winLoc[workIndex].h, 52, winP);
        SetFrameColor(WColors[workIndex + c320], winP);
        allocItemList(winP, resType, resID);
        ShowWindow(winP);

    }

    (**refH).remSignature = setupItemMenu(0x2f6, resType, winP);
    ctlH = GetCtlHandleFromID(winP, 3L);
    InvalRect(&(**ctlH).ctlRect);
    ctlH = GetCtlHandleFromID(winP, 4L);
    InvalRect(&(**ctlH).ctlRect);

    InitCursor();

    return retVal;
}

/*  we think this is for size data at the bottom of root windows
Welcome to footer?

                    if (wClass == REM_fileroot)
                        linkItem = CountResources(refP->resType);
                    else {
                    linkItem = GetResourceSize(refP->resType, refP->resID);
                        if (linkItem == 1L)
                            drawItemText((char *) strings[71], 110);
                        else {

  */







Rect ItemTextRect = { 0, 2, 0, 260 };

#pragma databank 1

/*--------------------------------------
    ItemProc - called from the ItemProc attached to the dependents window

    Marc Wolfgram,  6/13/92  6:27:38 PM
*/
void ItemProc(void)
{
word            wfd;
long            curFile, depCtl;
GrafPortPtr     winP;
fWindowRecHndl  refH;
fListCtlRecHndl ctlH;
namePtr         nameP;
nameSubPtr      nameSubP;
resLinkRecHndl  linkH;
resLink        *linkP;

    winP = GetPort();
    curFile = SetResFile2(fResID, -1);
    refH = (fWindowRecHndl) GetWRefCon(winP);
    wfd = (**refH).Signature & 0x0003;
    linkH = (resLinkRecHndl) (**refH).resPrivate;

    linkP = &(**linkH).ref[(word) (**linkH).ref[0].hostHitTick];

    ctlH = (fListCtlRecHndl) GetCtlHandleFromID(winP, 3L);
    if (linkP->hostType) {
        nameP = getNameRec(wfd, linkP->hostType);
        drawRectText((CtlRecHndl) ctlH, nameP->name, 1);
    }
    else
        drawRectText((CtlRecHndl) ctlH, (char *) strings[65], 0);

    ctlH = (fListCtlRecHndl) GetCtlHandleFromID(winP, 4L);
    nameP = getNameRec(wfd, linkP->resType);
    drawRectText((CtlRecHndl) ctlH, nameP->name, 1);

    depCtl = (**linkH).ref[0].hostID;
    if (depCtl == 3L || depCtl == 4L)
        hiliteRect(GetCtlHandleFromID(winP, depCtl));

    DrawControls(winP);
    nameSubP = getNameSubRec(wfd, (**refH).resType, (**refH).resID);
    drawItemText(nameP ? nameSubP->name : (char *) strings[67], 112);
    SetResFile1(curFile);
}
#pragma databank 0

/*--------------------------------------
    drawItemText

    Marc Wolfgram,  6/17/92 12:23:43 AM
*/
void drawItemText(char *text, word v) {
    ItemTextRect.v1 = v;
    ItemTextRect.v2 = v + 10;
    EraseRect(&ItemTextRect);
    MoveTo(5, v + 9);
    DrawString(text);
}

/*--------------------------------------
    drawRectText

    Marc Wolfgram,  6/13/92  7:18:14 PM
*/
void drawRectText(CtlRecHndl ctlH, char *text, word enabled)
{
Rect insetR;

    insetR.v1 = (**ctlH).ctlRect.v1;
    insetR.h1 = (**ctlH).ctlRect.h1;
    insetR.v2 = (**ctlH).ctlRect.v2;
    insetR.h2 = (**ctlH).ctlRect.h2;

    InsetRect(&insetR, 2, 1);
    EraseRect(&insetR);
    MoveTo(insetR.h1 + 10, insetR.v1 + 8);
    DrawString(text);

    if (!enabled) {
        GetPenMask(&normMask);
        SetPenMask(&dehiMask);
        EraseRect(&insetR);
        SetPenMask(&normMask);
    }
}

/*--------------------------------------
    hiliteRect - used by the item dependents window

    Marc Wolfgram,  6/12/92 12:30:02 AM
*/
void hiliteRect(CtlRecHndl ctlH)
{
Rect insetR;

    insetR.v1 = (**ctlH).ctlRect.v1;
    insetR.h1 = (**ctlH).ctlRect.h1;
    insetR.v2 = (**ctlH).ctlRect.v2;
    insetR.h2 = (**ctlH).ctlRect.h2;

    InsetRect(&insetR, 2, 1);
    InvertRect(&insetR);
}

/*--------------------------------------
    openHelpWin - opens the help or debugger window

    Marc Wolfgram,  6/12/92 12:19:22 AM
    Mark Collins,   7/ 1/92  5:49:10 PM
*/
void openHelpWin(void)
{
word            debugHelp, signature;
long            winID;
fWindowRecPtr   refP;
fWindowRecHndl  refH;
GrafPortPtr		winP;

    debugHelp = fTaskRec.modifiers & 0x0800;
    if (debugHelp) {
        signature = 0x48ef;
        winP = helpWin2;
        winID = 0xef9L;
    }
    else {
        signature = 0x48e4;
        winP = helpWin1;
        winID = 0xef4L;
    }

	if (winP)
        SelectWindow(winP);
	else {
        refH = (fWindowRecHndl) NewHandle(20L, fMemID, 0x0018, 0L);
    	refP = (fWindowRecPtr) deref((Handle) refH);
    	refP->Signature     = signature;
    	refP->resType       = 0;
    	refP->resID         = 0L;
        refP->resFileID     = 0;
    	refP->remTaskMask   = 0x001f7fffL;
    	refP->remSignature  = 1;
    	refP->resPrivate    = 0L;
	    HUnlock((Handle) refH);
		winP = NewWindow2(0L, (Long) refH, (VoidProcPtr) &DrawProc, 0L, 2, (Ref) winID, rWindParam1);
        SetPort(winP);
        if (debugHelp)
            helpWin2 = winP;
        else
            helpWin1 = winP;
    }
}

/*--------------------------------------
    updateHelp1

    Mark Collins and Marc Wolfgram,  7/ 5/92 11:32:47 AM
*/
void updateHelp1(fWindowRecHndl refH)
{
long            resID, curFile;
Handle          helpH;
GrafPortPtr     oldP;

    resID = (**refH).resID;
    helpH = (**refH).resPrivate;
    if (helpH)
        DisposeHandle(helpH);

    if (resID)
        curFile = SetResFile2((**refH).resFileID, 1);
    else {
        curFile = SetResFile2(fResID, 1);
        resID = 94L;
    }

    oldP = GetPort();
    SetPort(helpWin1);
    helpH = LoadResource(rText, resID);
    if (!toolerror()) {
        DetachResource(rText, resID);
        (**refH).resPrivate = helpH;
        TESetText(13, (Ref) helpH, 0L, 0, (Ref) &HelpStyle, (Handle) GetCtlHandleFromID(helpWin1, 1L));
    }
    SetPort(oldP);
    SetResFile1(curFile);
}

char		bTextPtr[10];

/*--------------------------------------
    updateHelp2 (I guess this is a feature, eh?)

    Marc Wolfgram,  6/12/92 12:18:43 AM
*/
void updateHelp2(word task)
{
GrafPortPtr oldPort;

	if (!helpWin2)
		return;

	oldPort = GetPort();
	SetPort(helpWin2);

	sprintf(bTextPtr, "%0.8lx   ", fTaskRec.wmTaskMask);
	MoveTo(150, 19);
	DrawCString((Pointer) bTextPtr);

	sprintf(bTextPtr, "%0.4x/%0.4x   ", task, fTaskRec.modifiers);
	MoveTo(150, 28);
	DrawCString((Pointer) bTextPtr);

	sprintf(bTextPtr, "%0.8lx   ", (long) linkREM);
	MoveTo(150, 37);
	DrawCString((Pointer) bTextPtr);

	sprintf(bTextPtr, "%0.8lx   ", (long) rootREM);
	MoveTo(150, 46);
	DrawCString((Pointer) bTextPtr);

	sprintf(bTextPtr, "%0.8lx  ", callVector);
	MoveTo(150, 55);
	DrawCString((Pointer) bTextPtr);

	sprintf(bTextPtr, "%0.4x   ", fMenuGlobal);
	MoveTo(150, 64);
	DrawCString((Pointer) bTextPtr);

	sprintf(bTextPtr, "%0.4x  ", wClass);
	MoveTo(150, 73);
	DrawCString((Pointer) bTextPtr);

	sprintf(bTextPtr, "%0.4x  ", CurMurphy);
	MoveTo(150, 82);
	DrawCString((Pointer) bTextPtr);

	/* sprintf(bTextPtr, "%0.4x/%0.4x   ", 0, 0);
	MoveTo(150, 91);
	DrawCString((Pointer) bTextPtr); */

	sprintf(bTextPtr, "%0.4x  ", CurWindow.Signature);
	MoveTo(150, 109);
	DrawCString((Pointer) bTextPtr);

	sprintf(bTextPtr, "%0.4x  ", CurWindow.resType);
	MoveTo(150, 118);
	DrawCString((Pointer) bTextPtr);

	sprintf(bTextPtr, "%0.8lx    ", CurWindow.resID);
	MoveTo(150, 127);
	DrawCString((Pointer) bTextPtr);

	sprintf(bTextPtr, "%0.4x  ", CurWindow.resFileID);
	MoveTo(150, 136);
	DrawCString((Pointer) bTextPtr);

	sprintf(bTextPtr, "%0.8lx  ", CurWindow.remTaskMask);
	MoveTo(150, 145);
	DrawCString((Pointer) bTextPtr);

	sprintf(bTextPtr, "%0.4x  ", CurWindow.remSignature);
	MoveTo(150, 154);
	DrawCString((Pointer) bTextPtr);

	sprintf(bTextPtr, "%0.8lx   ", CurWindow.resPrivate);
	MoveTo(150, 163);
	DrawCString((Pointer) bTextPtr);

	SetPort(oldPort);
}

/*--------------------------------------
    CopyManager

    Marc Wolfgram,  9/20/92 15:56:53
*/
long copyManager(word source, word target, word resType, long resID, handle resData)
{
word        retVal;
long        curFile;
nameSubPtr  nameSubP;
Pointer     oldPP;
GrafPortPtr oldP, winP;

    miscTaskRec.wmTaskMask = 0x1B2006L;
    dataPB.pCount = 5;
    refPB.pCount = 3;
	dataPB.resType = refPB.resType = resType;
	refPB.resID = dataPB.resID = resID;

    if (copyFlag != 9) {
        refPB.resFileID = dataPB.resFileID = target;
	    retVal = remGetResourceAttr(&dataPB);
        if (!retVal) {
            if (copyFlag < 0x0009) { /* process for item only */
        		curFile = SetResFile2(fResID,-1);

    			namePB.pCount = 3;
    			namePB.resType = resType;
				namePB.resName = &tempName[128];
    			remGetStdTypeName(&namePB);
    			sprintf(tempName, (char *) strings[71], &tempName[128], resID);
        		AlertArray[0] = tempName;
	            oldPP = GetCtlParamPtr();
                SetCtlParamPtr((Pointer) &AlertArray);

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

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

                copyFlag = GetCtlValue(GetCtlHandleFromID(winP, 0x7039L));
                CloseWindow(winP);
                SetPort(oldP);
	            SetCtlParamPtr(oldPP);
                SetResFile1(curFile);
            }
            if (copyFlag & 0x0002)
                retVal = remRemoveResource(&refPB);
        }

    }

    dataPB.resFileID = source;

	retVal = remGetResourceAttr(&dataPB);

	dataPB.resData = resData;
    dataPB.resFileID = refPB.resFileID = target;

    if (workList[workIndex].resFileID == source) {
        nameSubP = getNameSubRec(workIndex, resType, resID);
        if (nameSubP->name[0] > 9) {
            nameSubP->name[9] = nameSubP->name[0] - 9;
            dataPB.pCount = 6;
            dataPB.resName = &(nameSubP->name[9]);
        }
        retVal = remAddResource(&dataPB);
        nameSubP->name[9] = 0x20;
    }
    else {
        curFile = SetResFile2(source, 1);
        RMGetResourceName(resType, resID, &tempName[128]);
        if (!toolerror()) {
            dataPB.pCount = 6;
            dataPB.resName = &tempName[128];
        }
        SetResFile1(curFile);

        retVal = remAddResource(&dataPB);

    }

	refPB.resID = dataPB.resID;
    retVal = remReleaseResource(&refPB);
    return dataPB.resID;
}
