/*
 *  File:		fill.c
 *  Function:	fatbits fill routines
 *  Author:		Paul Elseth
 *				Copyright (c) 1991, Paul Elseth
 *
 *	Change History:
 *	
 *		12/16/91	PBE		created
 */

#ifndef	__FILL__
#include "fill.h"
#endif

#ifndef	__EDITOR__
#include "editor.h"
#endif
#ifndef	__GLOBALS__
#include "globals.h"
#endif
#ifndef	__FATBITS__
#include "fatbits.h"
#endif
#ifndef	__FATUTILS__
#include "fatUtils.h"
#endif
#ifndef	__MEMUTILS__
#include "memutils.h"
#endif
#ifndef	__UTILS__
#include "utils.h"
#endif
#ifndef	__COLOR__
#include "color.h"
#endif
#ifndef __QDAUX__
#include <qdaux.h>
#endif
#ifndef __orca__
#include <orca.h>
#endif
#ifndef	__OPTIONS__
#include "options.h"
#endif

#pragma noroot


/*                              
 *	FillSource()
 *		Create the source graphPort/locInfo for MakeMask() and FillIcon().
 */
static
short FillSource(GrafPort *tempPort, QDIconRecord **iconH)
{
	unsigned	w, h, rowBytes;
	LocInfo		portInfo;
	short		err;

    w = (**iconH).iconWidth;
	h = (**iconH).iconHeight;

	w = (w * 2 + 7) & 0xfff8;

    rowBytes = (w / 4 + 7) & 0xfff8;
    portInfo.boundsRect.h1 = 0;
/*	portInfo.boundsRect.h2 = (x + 1) & 0xfffe;	*/
	portInfo.boundsRect.h2 = rowBytes * 4;
    portInfo.boundsRect.v1 = 0;
    portInfo.boundsRect.v2 = h;
    portInfo.width = rowBytes;

	err = GetNewPtr(h * rowBytes, &portInfo.ptrToPixImage);
	if (err == 0) {
		OpenPort(tempPort);
		portInfo.portSCB = GetMasterSCB();
		SetPortLoc(&portInfo);
		SetPortRect(&portInfo.boundsRect);
		EraseRect(&portInfo.boundsRect);
		}

	return err;
}


/*
 *	DisposeSource()
 *		Dispose of the temporary grafPort.
 */
static
void DisposeSource(GrafPort *port)
{
	ClosePort(port);
	DisposeIfPtr(port->portInfo.ptrToPixImage);
}


/*
 *	Icon2Pixmap()
 *		Copy icon record into a pixel map.
 */
static
void Icon2Pixmap(QDIconRecord **iconH, GrafPort *port)
{
	QDIconRecord	*iconP;
    char			*pixmap, *image;
	unsigned int	rowBytes, h, w;

	iconP = *iconH;
	w = iconP->iconWidth;
	h = iconP->iconHeight;
	image = (char *) &iconP->iconImage;

	rowBytes = port->portInfo.width;
	pixmap = port->portInfo.ptrToPixImage;

	asm {
	    ldx	h
vLoop:  lda	w
		dec	a
		lsr	a
		tay
		inc	a
	    pha
		sep	#0x20
hLoop:  lda	[image],y
		sta	[pixmap],y
		dey
		bpl	hLoop
	    rep	#0x20
		pla
        clc
        adc	image
        sta	image
        bcc	noInc1
        inc	image+2
noInc1:	clc
		lda	pixmap
        adc	rowBytes
		sta	pixmap
	    bcc	noInc2
        inc	pixmap+2
noInc2: dex
		bne	vLoop
		}
}


/*
 *	Pixmap2Icon()
 *		Copy a pixel map into an icon record.
 */
static
void Pixmap2Icon(GrafPort *port, QDIconRecord **iconH, Boolean mask)
{
	QDIconRecord	*iconP;
    char			*pixmap, *image;
	unsigned int	rowBytes, h, w;
    short			invFlag;

	iconP = *iconH;
	w = iconP->iconWidth;
	h = iconP->iconHeight;
	image = (char *) &iconP->iconImage;
    if (mask) {
		image += iconP->iconSize;
	    invFlag = 0xffff;
	    }
    else
    	invFlag = 0x0000;

	rowBytes = port->portInfo.width;
	pixmap = port->portInfo.ptrToPixImage;

	asm {
	    ldx	h
vLoop:  lda	w
		dec	a
		lsr	a
		tay
		inc	a
	    pha
		sep	#0x20
hLoop:  lda	[pixmap],y
		eor	invFlag
		sta	[image],y
		dey
		bpl	hLoop
	    rep	#0x20
		pla
        clc
        adc	image
        sta	image
        bcc	noInc1
        inc	image+2
noInc1:	clc
		lda	pixmap
        adc	rowBytes
		sta	pixmap
	    bcc	noInc2
        inc	pixmap+2
noInc2: dex
		bne	vLoop
		}
}


/*
 *	FillIcon()
 *		Fill an area in the icon.
 */
void FillIcon(IconData **dataH, Point pt)
{
	GrafPort		tempPort, *oPort;
    QDIconRecord	**iconH;
    Cursor			*oCurs;
	Rect			r;
	Pattern			patt;
    short			leakTable[2];
    short			x, y;
	short			err;

	
    oCurs = GetCursorAdr();
	SetWaitCursor();
    oPort = GetPort();

    CopyUndoIcon(dataH);
    iconH = (**dataH).iconH;
    
	leakTable[0] = 1;
    leakTable[1] = PickColor(pt.h, pt.v, dataH, false);
	Pt2Pixel(pt.h, pt.v, dataH, false, &x, &y);

    err = FillSource(&tempPort, iconH);
	if (err == 0) {	
/* make sure the xtra space in the background is _not_ the leak color: */
		MakePattern(leakTable[1] ^ 0x00ff, patt);	
        FillRect(&tempPort.portRect, patt);

        Icon2Pixmap(iconH, &tempPort);	/* copy icon image into the offscreen pixelmap */

        MakePattern((**dataH).color, patt);
        SeedFill(&tempPort.portInfo, &tempPort.portRect,
				 &tempPort.portInfo, &tempPort.portRect, x * 2, y,
				 destModeLeaveMask + resMode640DMask, patt, leakTable);
		err = toolerror();

		Pixmap2Icon(&tempPort, iconH, false);

        DisposeSource(&tempPort);

        SetPort(oPort);

        r = (**dataH).fatIRect;
        InsetRect(&r, 2, 1);
		InvalRect(&r);
        UpdateEm(dataH);
        DrawFatImage(dataH);
        Dirty(dataH);
        }
	else
		SetPort(oPort);

	SetMyCursor(oCurs);

    if (err != 0)
		SysError(err);
}


/*
 *	MakeMask()
 *		Construct a mask for this icon.
 */
void MakeMask(IconData **dataH)
{
	GrafPort		tempPort, *oPort;
	QDIconRecord	**iconH;
    Cursor			*oCurs;
	LocInfo			portInfo;
    short			leakTable[2];
	short			err;

	oCurs = GetCursorAdr();
	SetWaitCursor();
    oPort = GetPort();

    CopyUndoIcon(dataH);
    iconH = (**dataH).iconH;

    err = FillSource(&tempPort, iconH);
    if (err == 0) {
		Icon2Pixmap(iconH, &tempPort);
        
		leakTable[0] = 1;
		leakTable[1] = 0xffff;	/* leak color is white */

		CalcMask(&tempPort.portInfo, &tempPort.portRect,
        		 &tempPort.portInfo, &tempPort.portRect,
       			 destModeClrToOnes + resMode640DMask, 0L, leakTable);
		err = toolerror();

		Pixmap2Icon(&tempPort, iconH, true);

		RedrawFatbits(dataH, true);
		Dirty(dataH);
        }

	DisposeSource(&tempPort);
    SetPort(oPort);
	SetMyCursor(oCurs);

    if (err != 0)
		SysError(err);
}
