/*--------------------------------------
    common.c

    Mark & Marc,  5/31/93 12:51:50
    contains utility routines for the entire unit
*/

#include "icon.h"

extern EventRecordPtr       fEventPtr;
extern word                 fUserID;
extern word                 edResFileID;
extern word                 pixWid;
extern long                 remHelpID;

void MakeGlobalRect(Rect *inR, Rect *outR)
{
    BlockMove(inR, outR, 8L);
    LocalToGlobal(&outR->v1);
    LocalToGlobal(&outR->v2);
}

word getVid(void)
{
	return (GetMasterSCB() & 0x80) ? 2 : 1;
}

word setMaxOf(word a, word b)
{
    return (a > b) ? a : b;
}

word setMinOf(word a, word b)
{
    return (a > b) ? b : a;
}

void stuffRect(Rect *r, word l, word t, word w, word h)
{
    r->h1 = l;
    r->v1 = t;
    r->h2 = l + w;
    r->v2 = t + h;
}

handle loadEdRes(long id, word resType)
{
handle  retHndl;

	retHndl = fSpecialMagic2(resType, id, 0L, 0, edResFileID);
	retHndl = fSpecialMagic2(rWindParam1, 0L, retHndl, 1, edResFileID);
	return retHndl;
}

void unloadEdRes(long id, word resType)
{
handle  retHndl;

	retHndl = fSpecialMagic2(resType, id, 0L, 0, edResFileID);
}

void checkData(GrafPortPtr winP) {

privateDataHndl	privH;
privateDataPtr  privP;
long			size;

    privH = (privateDataHndl) fGetPrivateData2(winP, 0L, 0L);
    privP = *privH;
    if (privP->flag == 0) {
        return;
    }
    switch (privP->resType) {
        case rIcon:
    		size = GetHandleSize(privP->editH);
            HUnlock(privP->resData);
		    SetHandleSize(size, privP->resData);
    		HandToHand((Handle) privP->editH, privP->resData, size);
            HLock(privP->resData);
            fWriteResource2(privP->resType, privP->resID, 0);
    		privP->flag = 0x0000;	/* set dirty flag to 0 */
            break;

        case rCursor:
            makeCursor(privP);
            fWriteResource2(privP->resType, privP->resID, 0);
    		privP->flag = 0x0000;	/* set dirty flag to 0 */
            break;
        case rBundle:
		    privP->resData = RebuildBundle(privP->structH);
            fWriteResource2(privP->resType, privP->resID, 0);
			privP->flag = 0x0000;
            break;
        default:
            break;
	}
}

void makeCursor (privateDataPtr privP)
{
word            i, j, *k;
long            sizeH, imageSize;
CursorPtr       cursorP;
QDIconRecord    *iconP;
Pointer         i0, o0, temp1;

    sizeH = GetHandleSize((Handle) privP->editH);
    HUnlock(privP->resData);
    SetHandleSize(sizeH + 10L, privP->resData);
    HLock(privP->resData);
    iconP = *(privP->editH);
    cursorP = (CursorPtr) *(privP->resData);
    cursorP->cursorHeight = iconP->iconHeight;
    cursorP->cursorWidth = iconP->iconWidth / 4;
    imageSize = (long) iconP->iconSize;
    i0 = (char *) &(iconP->iconImage[0]);
    o0 = (char *) &(cursorP->cursorData[0]);

    BlockMove(i0, o0, imageSize);
    temp1 = o0;
    for (i = 0; i < imageSize; i++) {
        *temp1 ^= 0xff;
        temp1++;
    }
    i0 += imageSize;
    o0 += imageSize;
    BlockMove(i0, o0, imageSize);
    o0 += imageSize;
    k = (word *) o0;
    *k = privP->hotSpot.v;
    o0++;
    o0++;
    k = (word *) o0;
    *k = privP->hotSpot.h;
    o0 += 4;
    *o0 = (pixWid == 2) ? 0x80 : 0x00;
    for (i = 0; i < 9; i++) {
        o0++;
        *o0 = 0x00;
    }
}

void extractCursor (privateDataPtr privP)
{
word            *k, i, j;
long            sizeH, imageSize;
CursorPtr       cursorP;
QDIconRecord    *iconP;
Pointer         i0, o0, temp1;

    if (!privP->editH) {
        privP->editH = (QDIconRecord **) NewHandle(100L, fUserID, 0x8018, 0L);
    }
    HUnlock((Handle) privP->editH);

    sizeH = GetHandleSize(privP->resData);
    SetHandleSize(sizeH, (Handle) privP->editH);
    HLock((Handle) privP->editH);
    iconP = *(privP->editH);
    cursorP = (CursorPtr) *(privP->resData);

    iconP->iconHeight = cursorP->cursorHeight;
    iconP->iconWidth = cursorP->cursorWidth * 4;
    imageSize = iconP->iconHeight * (iconP->iconWidth / 2);
    iconP->iconSize = imageSize & 0xffff;

    i0 = (char *) &(iconP->iconImage[0]);
    o0 = (char *) &(cursorP->cursorData[0]);

    BlockMove(o0, i0, imageSize);
    j = imageSize & 0xffff;
    temp1 = i0;
    for (i = 0; i < j; i++) {
        *temp1 ^= 0xff;
        temp1++;
    }
    i0 += imageSize;
    o0 += imageSize;
    BlockMove(o0, i0, imageSize);
    o0 += imageSize;

    k = (word *) o0;
    privP->hotSpot.v = *k;
    o0++;
    o0++;
    k = (word *) o0;
    privP->hotSpot.h = *k;
}

/*  Off Port Magic-  yet another form of hell  */

void CreateOffPort(word width, word height, GrafPort ***pMapH) {

GrafPortPtr		oPort;
GrafPortHndl	portH;
LocInfo		    locInfo;
Handle		    pixImageHndl;
Ptr			    pixImagePtr;

	oPort = GetPort();
	portH = *pMapH = 0L;
	portH = (GrafPortHndl) NewHandle(sizeof(GrafPort), fUserID, 0x8018, 0L);
	HLock((Handle) portH);
	OpenPort(*portH);
	locInfo.portSCB = GetMasterSCB();
	locInfo.boundsRect.h1 = 0;
	locInfo.boundsRect.h2 = width;
	locInfo.boundsRect.v1 = 0;
	locInfo.boundsRect.v2 = height;
	locInfo.width = ((width / 4) + 7) & 0xfff8;
	pixImageHndl = NewHandle((long) (locInfo.width * height), fUserID, 0x8018, 0L);
	pixImagePtr = *pixImageHndl;
	locInfo.ptrToPixImage = pixImagePtr;
	SetPortLoc(&locInfo);
	SetPortRect(&locInfo.boundsRect);
	ClipRect(&locInfo.boundsRect);
	SetVisRgn(GetClipHandle());
	EraseRect(&locInfo.boundsRect);
	SetPort(oPort);
	HUnlock((Handle) portH);
	*pMapH = portH;
}

void AdjustOffPort(GrafPort **pMapH, word width, word height) {

GrafPortPtr		oPort, pMapP;
LocInfo		    locInfo;
Handle		    h, pixImageHndl;
Ptr			    pixImagePtr;

	oPort = GetPort();
	pMapP = *pMapH;
	SetPort(pMapP);
	h = FindHandle(pMapP->portInfo.ptrToPixImage);
	if (h)
		DisposeHandle(h);
	locInfo.portSCB = GetMasterSCB();
	locInfo.boundsRect.h1 = 0;
	locInfo.boundsRect.h2 = width;
	locInfo.boundsRect.v1 = 0;
	locInfo.boundsRect.v2 = height;
	locInfo.width = ((width / 4) + 7) & 0xfff8;
	pixImageHndl = NewHandle((long) (locInfo.width * height), fUserID, 0x8018, 0L);
	pixImagePtr = *pixImageHndl;
	locInfo.ptrToPixImage = pixImagePtr;
	SetPortLoc(&locInfo);
	SetPortRect(&locInfo.boundsRect);
	ClipRect(&locInfo.boundsRect);
	SetVisRgn(GetClipHandle());
	EraseRect(&locInfo.boundsRect);
	SetPort(oPort);
	HUnlock((Handle) pMapH);
}

word UpdateEditor(GrafPortPtr winP) {

	BeginUpdate(winP);
	EndUpdate(winP);
	return -1;
}

word EditorMenu(EventRecord *event) {

word            done;
WindowPtr		winP;
privateDataHndl	privH;
privateDataPtr	privP;
long            temp;
MouseRec        theMouse;

	winP = FrontWindow();
    privH = (privateDataHndl) fGetPrivateData2(winP, 0L, 0L);
    privP = *privH;
    temp = event->wmTaskData & 0x0000ffff;
	switch (temp) {
        case UNDOITEM:  /* undo */
            doUndo(privP);
            privP->flag = 0x0001;
            break;
        case COPYITEM:  /* copy */
            /* needs to be written */
            break;
        case PASTEITEM: /* paste */
            /* needs to be written */
            break;
        case CLEARITEM: /* clear */
            doClear(privP);
            privP->flag = 0x0001;
            break;
        case FLIPVERTITEM:
            flipIcon(privP);
            privP->flag = 0x0001;
            break;
        case FLIPHORZITEM:
            flipHorizIcon(privP);
            privP->flag = 0x0001;
            break;
        case FILLICONITEM:
            fillImage(privP);
            privP->flag = 0x0001;
            break;
        case FILLMASKITEM:
            fillMask(privP);
            privP->flag = 0x0001;
            break;
		case MAKEMASKITEM:			/* create mask */
			MakeMask(privP);
            privP->flag = 0x0001;
			break;
		case COPYMASKITEM:			/* copy icon to mask */
            copyIconToMask(privP);
            privP->flag = 0x0001;
			break;
        case IMPORTITEM:
            doImport(privP);
            privP->flag = 0x0001;
            break;
        case 0x0408L:               /* test item */
            checkData(winP);
            SetCursor(*privP->resData);
            done = false;
            do {
                theMouse = ReadMouse();
                if (theMouse.mouseStatus & 0x80) {
                    done = true;
                }
            } while (!done);
            InitCursor();
	}
	return 0;
}

void SetTitle(GrafPortPtr winP, long ID)
{
handle  title;

	title = NewHandle(128L, fUserID, 0x8018, 0L);
	fGetWindowTitle2(rPString, ID, *title);
    SetHandleSize((long) (**title & 0x000000FFL), title);
    SetWTitle((title | 0x80000000L), winP);
}

#pragma databank	1
#pragma toolparms	1
void DrawProc(void) {
	DrawEditor();
}
#pragma databank	0
#pragma toolparms	0
