/*********************************************************/
/* This source code copyright (c) 1991-2001, Aaron Giles */
/* See the Read Me file for licensing information.       */
/* Contact email: mac@aarongiles.com                     */
/*********************************************************/

#if THINK_C
#include "THINK.Header"
#elif applec
#pragma load ":Headers:MPW.Header"
#elif __MWERKS__
//#include "MW.Header"
#else
#include "JPEGView.h"
#endif

void SaveWindowPosition(WindowPtr theWindow, Rect *position)
{
	*position = theWindow->portRect;
	GlobalRect(position, theWindow);
	if (!gDone) SaveGeneralPrefs();
}

void PlaceWindow(WindowPtr theWindow, Rect *theRect, Point defaultLoc)
{
	if (GetWVariant(theWindow) == dBoxProc || theRect->top == theRect->bottom || 
				DoSetWindowBounds(theWindow, theRect) != noErr) {
		FWMoveWindow(theWindow, defaultLoc.h, defaultLoc.v, true);
	}
}

/*
 * ChangeActive(theWindow)
 *
 *     Purpose: Changes the active window, flipping the menu bar if necessary and 
 *					updating the gActive* variables
 *      Inputs: theWindow = the new active window
 *     Returns: nothing
 *
 */
 
void ChangeActive(WindowPtr theWindow) 
{
	static WindowPtr gLastWindow = nil;
	ImageHandle oldImage = FrontImage(), newImage = nil;
	WindowPtr oldWindow = FWFrontWindow();
  	Point thePoint = { 0, 0 };
	
	MySetPort(nil);
	if (theWindow) {
		newImage = FindImage(theWindow);
		if (gSlideShow != kPaused) {
			if (theWindow == GetSlideBackWindow()) {
				if ((*gMainMonitor)->full) RehideMenuBar();
				else FullScreen(gMainMonitor);
			} else if (WindowKind(theWindow) != floatingWindowKind) {
				if (!newImage || !Full(newImage)) {
					if (newImage && !AnotherFull(newImage)) NormalScreen((*newImage)->dmon);
					else UnhideMenuBar();
				} else {
					if ((*(*newImage)->dmon)->full) RehideMenuBar();
					else FullScreen((*newImage)->dmon);
				}
			}
		}
		if (!WindowVisible(theWindow)) FWShowWindow(theWindow);
		FWSelectWindow(theWindow);
		MySetPort((CGrafPtr)theWindow);
		if (theWindow) {
			if (theWindow == GetColorsWindow()) DrawColorsWindow();
			else if (theWindow == GetStatWindow()) DrawStatWindow();
		}
		if (newImage && !EmptyRgn((*newImage)->update)) InvalRgn((*newImage)->update);
		if (newImage) ActivateAnts((*newImage)->ants);
	}
	SetStatistics();
	if (theWindow != gLastWindow && (!theWindow || WindowKind(theWindow) != floatingWindowKind)) {
		gLastWindow = theWindow;
		if ((!gSlideShow && gThePrefs.autoComments) ||
			(gSlideShow && (*gSlideOptions)->autoComments)) {
			newImage = FrontImage();
			if (!newImage || !(*newImage)->comments) {
				if (GetCommentsWindow())
					if ((!gSlideShow && !gCommentsOpen) || gSlideShow) CloseComments();
			} else if (!CommentsClosed(newImage) && !GetCommentsWindow() &&
					   OpenComments() == noErr) {
				FWSelectWindow(GetCommentsWindow());
				FWShowWindow(GetCommentsWindow());
			}
		}
		if (GetSlideControlsWindow()) DrawSlideControlsWindow();
		if (GetSlideOptionsWindow()) UpdateSlideOptionsButtons();
	}
	AdjustMenus();
}

/*
 * DoCloneWindow(theWindow, behindWindow, newWindow)
 *
 *     Purpose: Makes a clone of the given window
 *      Inputs: theWindow = the window to clone
 *				behindWindow = the window behind which to put the newcomer
 *				newWindow = a pointer to a WindowPtr to receive the new window
 *     Returns: an OSErr describing the result
 *
 */

OSErr DoCloneWindow(WindowPtr theWindow, WindowPtr behindWindow, WindowPtr *newWindow)
{
	ImageHandle newImage, theImage = FindImage(theWindow);
	DescType thePalette;
	short palette;
	OSErr theErr;

	if (!theImage) return errAENotModifiable;
	if (newImage = CopyImage(theImage)) {
		palette = (*newImage)->npalette;
		theErr = MakeNewWindow(newImage, true, gThePrefs.expandSmall);
		if (theErr == noErr) {
			switch ((*theImage)->npalette) {
				case plSys: thePalette = kAEPSystem; break;
				case plGrey: thePalette = kAEPGrayscale; break;
				case plImage: thePalette = kAEPImage; break;
				case plQuant: thePalette = kAEPQuantized; break;
			}
			DoSetPalette((*newImage)->window, thePalette);
			AddWindowItem(newImage);
			if (behindWindow) SendBehind((*newImage)->window, behindWindow);
			*newWindow = (*newImage)->window;
		}
	} else theErr = memFullErr;
	return theErr;
}

/*
 * DoCloseWindow(theWindow, restore)
 *
 *     Purpose: Handles the closing of the given window, disposing of the associated 
 *					image, if necessary
 *      Inputs: theWindow = the window to close
 *				restore = flag: true to restore colors when closing last image
 *     Returns: nothing
 *
 */
 
OSErr DoCloseWindow(WindowPtr theWindow, Boolean restore) 
{
	WindowPtr statWindow = GetStatWindow(), commentsWindow = GetCommentsWindow(),
				colorsWindow = GetColorsWindow(), slideBackWindow = GetSlideBackWindow(),
				slideControlsWindow = GetSlideControlsWindow();
	ImageHandle theImage = FindImage(theWindow);
	long dialogID = GetWRefCon(theWindow);
	Boolean reset = false;
	ushort i = 0;

	MySetPort(nil);
	if (WindowKind(theWindow) == dialogKind) DispatchDialogEvent(theWindow, kDialogClose);
	else if (dialogID == kHelpWindowID) CloseHelp();
	else if (theWindow == statWindow) CloseStats();
	else if (theWindow == commentsWindow) {
		ImageHandle frontImage = FrontImage();
		gCommentsOpen = false, CloseComments();
		if ((!gSlideShow && gThePrefs.autoComments) || 
			(gSlideShow && (*gSlideOptions)->autoComments))
			if (frontImage) (*frontImage)->flags |= ifCommentsClosed;
	} else if (theWindow == colorsWindow) CloseColors();
	else if (theWindow == slideControlsWindow) CloseSlideControls();
	else if (theWindow == slideBackWindow) CloseSlideBackWindow();
	else if (theImage) {
		Boolean normal = (Full(theImage) && !AnotherFull(theImage));
		MonitorHandle imageMonitor = (*theImage)->dmon;

		if (normal) NormalScreen(imageMonitor);
		DeleteWindowItem(theImage);
		DisposeImage(theImage);
		if (!gImageRoot && theImage && (restore || gDone)) ResetColors();
	}
	ChangeActive(FWFrontWindow());
	return noErr;
}

/*
 * DoCreateWindow(theType, behindWindow, theWindow)
 *
 *     Purpose: Handles the creation of static windows and positions them correctly
 *      Inputs: theType = the type of window to create
 *				behindWindow = the window's location
 *				theWindow = pointer to receive the new WindowPtr
 *     Returns: nothing
 *
 */
 
OSErr DoCreateWindow(DescType theType, WindowPtr behindWindow, WindowPtr *theWindow) 
{
	ImageHandle theImage;
	OSErr theErr = noErr;
	
	switch (theType) {
		case kAEWTPreferences:
			OpenPrefs();
			if (*theWindow = GetPrefsWindow()) ChangeActive(*theWindow);
			else theErr = memFullErr;
			break;
		case kAEWTSlideShow:
			OpenSlideOptions();
			if (*theWindow = GetSlideOptionsWindow()) ChangeActive(*theWindow);
			else theErr = memFullErr;
			break;
		case kAEWTAboutHelp:
			OpenAboutHelp();
			if (*theWindow = GetAboutHelpWindow()) ChangeActive(*theWindow);
			else theErr = memFullErr;
			break;
		case kAEWTHelp:
			if (!gHelpFound) theErr = errNoHelpFound;
			else {
				OpenHelp();
				if (*theWindow = GetHelpWindow()) {
					DoMoveWindow(*theWindow, behindWindow);
					FWShowWindow(*theWindow);
				} else theErr = memFullErr;
			}
			break;
		case kAEWTStatistics:
			OpenStats();
			if (*theWindow = GetStatWindow()) {
				DoMoveWindow(*theWindow, behindWindow);
				FWShowWindow(*theWindow);
			} else theErr = memFullErr;
			break;
		case kAEWTComments:
			OpenComments();
			if (*theWindow = GetCommentsWindow()) {
				DoMoveWindow(*theWindow, behindWindow);
				FWShowWindow(*theWindow);
			} else theErr = memFullErr;
			break;
		case kAEWTColors:
			OpenColors();
			if (*theWindow = GetColorsWindow()) {
				DoMoveWindow(*theWindow, behindWindow);
				FWShowWindow(*theWindow);
			} else theErr = memFullErr;
			break;
		case kAEWTSlideControls:
			OpenSlideControls();
			if (*theWindow = GetColorsWindow()) {
				DoMoveWindow(*theWindow, behindWindow);
				FWShowWindow(*theWindow);
			} else theErr = memFullErr;
		case kAEWTAbout:
			OpenAbout();
			for (theImage = gImageRoot; theImage; theImage = (*theImage)->next)
				if (IsAboutBox(theImage)) break;
			if (theImage && (*theWindow = (*theImage)->window)) {
				DoMoveWindow(*theWindow, behindWindow);
				FWShowWindow(*theWindow);
			} else theErr = memFullErr;
			break;
	}
	return theErr;
}

/*
 * DoMoveWindow(theWindow, behindWindow)
 *
 *     Purpose: Handles the proper moving of windows in the floating window environment
 *      Inputs: theWindow = the window to move
 *				behindWindow = the window's location
 *     Returns: nothing
 *
 */
 
OSErr DoMoveWindow(WindowPtr theWindow, WindowPtr behindWindow) 
{
	if (theWindow == behindWindow) return noErr;
	if (WindowKind(theWindow) == floatingWindowKind) {
		if (!behindWindow) ChangeActive(theWindow);
		else {
			if (WindowKind(behindWindow) != floatingWindowKind) 
				behindWindow = FWBottomFloatingWindow();
			SendBehind(theWindow, behindWindow);
		}
	} else {
		if (!behindWindow || WindowKind(behindWindow) == floatingWindowKind) 
			ChangeActive(theWindow);
		else SendBehind(theWindow, behindWindow);
	}
	return noErr;
}

/*
 * IsZoomed(theWindow)
 *
 *     Purpose: Determines the zoomed state of the given window
 *      Inputs: theWindow = the window to examine
 *     Returns: a boolean: true if the window is zoomed; false otherwise
 *
 */

Boolean IsZoomed(WindowPtr theWindow)
{
	ImageHandle theImage = FindImage(theWindow);
	
	if (theImage) return !EqualSizeRect(&(*theImage)->wrect, &(*theImage)->crect);
	else if (theWindow == GetStatWindow()) return gThePrefs.statsZoomed;
	else if (theWindow == GetHelpWindow()) {
		Rect defaultRect = { 0, 0, 300, 480 };
		return !EqualSizeRect(&theWindow->portRect, &defaultRect);
	} else return false;
}

/*
 * DoZoomWindow(theWindow, zoomed)
 *
 *     Purpose: Zooms the given window
 *      Inputs: theWindow = the window to clone
 *				zoomed = flag: true to zoom the window, false to unzoom
 *     Returns: an OSErr describing the result
 *
 */

OSErr DoZoomWindow(WindowPtr theWindow, Boolean zoomed)
{
	ImageHandle theImage = FindImage(theWindow);
	Rect newRect, oldRect, monRect;

	if (theImage) {
		oldRect = (*theImage)->wrect;
		newRect = (*theImage)->crect;
		GetActiveRect((*theImage)->dmon, &monRect);
		if (!Full(theImage)) monRect.top += gTitleBarHeight;
		if (zoomed || (Width(&newRect) > Width(&monRect)) || (Height(&newRect) > Height(&monRect))) {
			OffsetRect(&newRect, -newRect.left, -newRect.top);
			newRect.right = (long)newRect.right * (long)Height(&monRect) / (long)newRect.bottom;
			newRect.bottom = Height(&monRect);
			if (Width(&newRect) > Width(&monRect)) {
				newRect.bottom = (long)newRect.bottom * (long)Width(&monRect) / (long)newRect.right;
				newRect.right = Width(&monRect);
			}
		}
		(*theImage)->wrect = newRect;
		ResizeWindow(theImage);
		if (AntsHaveSelection((*theImage)->ants)) {
			Rect selRect;
			GetAntsSelection((*theImage)->ants, &selRect);
			MapRect(&selRect, &oldRect, &(*theImage)->wrect);
			SetAntsSelection((*theImage)->ants, &selRect);
		}
	} else if ((theWindow == GetStatWindow()) && (!gThePrefs.statsZoomed != !zoomed))
		ZoomStats();
	else if (theWindow == GetHelpWindow()) {
		Rect defaultRect = { 0, 0, 300, 480 };
		if (zoomed) {
			defaultRect = theWindow->portRect;
			GlobalRect(&defaultRect, theWindow);
			GetActiveRect(GetMostDevice(&defaultRect), &defaultRect);
			InsetRect(&defaultRect, kWindowBorderWidth, kWindowBorderHeight);
			defaultRect.top += gTitleBarHeight;
		} else {
			GlobalRect(&defaultRect, theWindow);
			NudgeWindowRect(&defaultRect, GetMostDevice(&defaultRect));
		}
		FWMoveWindow(theWindow, defaultRect.left, defaultRect.top, false);
		ResizeHelp(&defaultRect);
	}
	return noErr;
}

/*
 * MakeNewWindow(theImage, first, autoExpand)
 *
 *     Purpose: Creates a new window for the given image, closing the old one if it exists
 *      Inputs: theImage = a pointer to the image record
 *				first = flag: true if this is the first image in a series, false
 *						if this is just a follower
 *				autoExpand = flag: true to expand small images to largest size
 *     Returns: an OSErr describing the problem (hopefully noErr)
 *
 */
 
OSErr MakeNewWindow(ImageHandle theImage, Boolean first, Boolean autoExpand)
{
	static WindowPtr gLastWindow = nil;
	short resID = Full(theImage) ? rFullImageWindow : 
				((IsAboutBox(theImage)) ? rAboutImageWindow : rImageWindow);
	Rect winRect, oldRect = { 0, 0, 0, 0 };
	WindowPtr behindWindow;
	WCTabHandle winColors;
	Str255 theTitle;

	if (AntsHaveSelection((*theImage)->ants)) HideAnts((*theImage)->ants);
	(*theImage)->wrect = (*theImage)->crect;
	ScaleRect(&(*theImage)->wrect, (*theImage)->dmon, Full(theImage), autoExpand);
	if (Full(theImage)) {
		winRect = (*(*theImage)->dmon)->rect;
		OffsetRect(&(*theImage)->wrect, 
				   (Width(&winRect) - Width(&(*theImage)->wrect)) >> 1,
				   (Height(&winRect) - Height(&(*theImage)->wrect)) >> 1);
	} else {
		winRect = (*theImage)->wrect;
		PositionWindow(&winRect, (*theImage)->dmon);
	}
	if (gSlideShow) behindWindow = FWFrontWindow();
	else behindWindow = (first) ? (WindowPtr)-1 : gLastWindow;
	if ((*theImage)->window) {
		oldRect = (*theImage)->window->portRect;
		GlobalRect(&oldRect, (*theImage)->window);
		FWCloseWindow((*theImage)->window);
	} else {
		(*theImage)->window = AllocateWindow();
		if (!(*theImage)->window) return memFullErr;
	}
	MakeTitle(theImage, theTitle);
	MySetPort(nil);
	if (!FWGetNewCWindow(resID, (Ptr)(*theImage)->window, behindWindow)) return memFullErr;
	SetWindowKind((*theImage)->window, userKind);
	if (NeedsWhiteBG(theImage) && !Full(theImage) &&
		(winColors = (WCTabHandle)GetResource('wctb', 0)))
		SetWinColor((*theImage)->window, winColors);
	SizeWindow((*theImage)->window, Width(&winRect), Height(&winRect), false);
	FWMoveWindow((*theImage)->window, winRect.left, winRect.top, false);
	SetWTitle((*theImage)->window, theTitle);
	SetAntsPort((*theImage)->ants, (*theImage)->window);
	SetAntsLimitRect((*theImage)->ants, &(*theImage)->wrect);
	gLastWindow = (*theImage)->window;
	if (AntsHaveSelection((*theImage)->ants)) {
		Rect selRect;
		GetAntsSelection((*theImage)->ants, &selRect);
		MapRect(&selRect, &oldRect, &(*theImage)->wrect);
		SetAntsSelection((*theImage)->ants, &selRect);
	}
	if (!GWOrigSize(theImage) && 
		(!EqualSizeRect(&(*theImage)->wrect, &oldRect) || Dithered(theImage))) 
		KillGWorld(theImage);
	return noErr;
}

/*
 * ScaleRect(theRect, theMonitor, full)
 *
 *     Purpose: Scales the given rectangle to fit on the specified monitor
 *      Inputs: theRect = pointer to the rectangle to be fit
 *				theMonitor = pointer to the monitor to put the rect on
 *				full = flag: true if it will be displayed full screen
 *     Returns: nothing
 *
 */
 
void ScaleRect(Rect *theRect, MonitorHandle theMonitor, Boolean full, Boolean autoExpand)
{
	long theWidth, theHeight;

	theWidth = Width(&(*theMonitor)->rect);
	theHeight = Height(&(*theMonitor)->rect);
	if (!full) {
		theHeight -= gTitleBarHeight;
		if (theMonitor == gMainMonitor) theHeight -= gMenuHeight;
	}
	OffsetRect(theRect, -theRect->left, -theRect->top);
	if ((theRect->right > theWidth) || autoExpand) {
		theRect->bottom = (long)theRect->bottom * theWidth / (long)theRect->right;
		theRect->right = theWidth;
	}
	if (theRect->bottom > theHeight) {
		theRect->right = (long)theRect->right * theHeight / (long)theRect->bottom;
		theRect->bottom = theHeight;
	}
}

/*
 * MakeTitle(theImage, theTitle)
 *
 *     Purpose: Creates a window title for the given image
 *      Inputs: theImage = a pointer to the image
 *				theTitle = an Str255 to store the title in
 *     Returns: nothing
 *
 */
 
void MakeTitle(ImageHandle theImage, StringPtr theTitle) 
{
	long scaleX, scaleY;

	BlockMove((*theImage)->file.name, theTitle, 64);
	if ((*theImage)->num) {
		AddChar(theTitle, ' ');
		AddNumber(theTitle, (*theImage)->num);
	}
	if (!EqualSizeRect(&(*theImage)->wrect, &(*theImage)->crect)) {
		scaleX = 200L * (long)Width(&(*theImage)->wrect) / Width(&(*theImage)->crect);
		scaleX = (scaleX + 1) >> 1;
		scaleY = 200L * (long)Height(&(*theImage)->wrect) / Height(&(*theImage)->crect);
		scaleY = (scaleY + 1) >> 1;
		AddChar(theTitle, ' ');
		AddChar(theTitle, '(');
		if (abs(scaleX - scaleY) <= 1) {
			AddNumber(theTitle, (scaleX + scaleY) / 2);
		} else {
			AddNumber(theTitle, scaleX);
			AddChar(theTitle, '%');
			AddChar(theTitle, '/');
			AddNumber(theTitle, scaleY);
		}
		AddChar(theTitle, '%');
		AddChar(theTitle, ')');
	}
}

/*
 * PositionWindow(theRect, theMonitor)
 *
 *     Purpose: Attempts to find the next free slot for a given image rectangle; it first
 *					tries the given upper-left, then scans downward, and finally to the
 *					right for an ideal spot; if nothing else is found, the original
 *					upper-left is returned
 *      Inputs: theRect = a pointer to the proposed image rectangle in global coordinates
 *				theMonitor = a pointer to the monitor rectangle
 *     Returns: nothing
 *
 */
 
void PositionWindow(Rect *theRect, MonitorHandle theMonitor)
{
	short rightSpace, bottomSpace, shift;
	Rect monRect, startRect;
	
	monRect = (*theMonitor)->rect;
	monRect.top += gTitleBarHeight;
	if (theMonitor == gMainMonitor) monRect.top += gMenuHeight;
	OffsetRect(theRect, monRect.left - theRect->left, monRect.top - theRect->top);
	rightSpace = monRect.right - theRect->right;
	bottomSpace = monRect.bottom - theRect->bottom;
	if (rightSpace < (2 * kWindowBorderWidth)) OffsetRect(theRect, rightSpace >> 1, 0);
	else OffsetRect(theRect, kWindowBorderWidth, 0);
	if (bottomSpace < (2 * kWindowBorderHeight)) OffsetRect(theRect, 0, bottomSpace >> 1);
	else OffsetRect(theRect, 0, kWindowBorderHeight);
	rightSpace = monRect.right - theRect->right;
	bottomSpace = monRect.bottom - theRect->bottom;
	startRect = *theRect;
	
	for (shift = 0; shift < bottomSpace; shift += kWindowStepDown) {
		*theRect = startRect;
		OffsetRect(theRect, 0, shift);
		while ((theRect->right <= monRect.right) && (theRect->bottom <= monRect.bottom)) {
			if (!SlotTaken(theRect)) return;
			OffsetRect(theRect, kWindowStepRight, kWindowStepDown);
		}
	}
	for (shift = 0; shift < rightSpace; shift += kWindowStepRight) {
		*theRect = startRect;
		OffsetRect(theRect, shift, 0);
		while ((theRect->right <= monRect.right) && (theRect->bottom <= monRect.bottom)) {
			if (!SlotTaken(theRect)) return;
			OffsetRect(theRect, kWindowStepRight, kWindowStepDown);
		}
	}
	*theRect = startRect;
	return;
}

/*
 * SlotTaken(theRect)
 *
 *     Purpose: Determines if the proposed rectangle is already taken by another
 *					window, within half of the step distance
 *      Inputs: theRect = the proposed rectangle
 *     Returns: true if the given slot is free; false otherwise
 *
 */
 
Boolean SlotTaken(Rect *theRect) 
{
	ImageHandle theImage;
	WindowPtr theWindow;
	register short temp;
	
	for (theImage = gImageRoot; theImage; theImage = (*theImage)->next) {
		theWindow = (*theImage)->window;
		if (theWindow && GetContRgn(theWindow) && WindowVisible(theWindow)) {
			temp = theRect->left - (*GetContRgn(theWindow))->rgnBBox.left;
			if (temp < 0) temp = -temp;
			if (temp >= (kWindowStepRight / 2)) continue;
			temp = theRect->top - (*GetContRgn(theWindow))->rgnBBox.top;
			if (temp < 0) temp = -temp;
			if (temp >= (kWindowStepDown / 2)) continue;
			return true;
		}
	}
	return false;
}

/*
 * ResizeWindow(theImage)
 *
 *     Purpose: Resizes and displays the window for the given image
 *      Inputs: theImage = a pointer to the image record
 *     Returns: true if everything went okay; false otherwise
 *
 */
 
Boolean ResizeWindow(ImageHandle theImage) 
{
	Rect windowRect, oldRect, oldLocalRect;
	Str255 theTitle;
	short space;
	
	if (!(*theImage)->window) return false;
	if (AntsHaveSelection((*theImage)->ants)) HideAnts((*theImage)->ants);
	oldLocalRect = oldRect = (*theImage)->window->portRect;
	GlobalRect(&oldRect, (*theImage)->window);
	windowRect = (*theImage)->wrect;
	OffsetRect(&(*theImage)->wrect, -windowRect.left, -windowRect.top);
	OffsetRect(&windowRect, oldRect.left - windowRect.left, oldRect.top - windowRect.top);
	if (Full(theImage)) {
		space = Width(&(*(*theImage)->dmon)->rect) - Width(&(*theImage)->wrect);
		OffsetRect(&(*theImage)->wrect, space >> 1, 0);
		space = Height(&(*(*theImage)->dmon)->rect) - Height(&(*theImage)->wrect);
		OffsetRect(&(*theImage)->wrect, 0, space >> 1);
	} else {
		if (NudgeWindowRect(&windowRect, (*theImage)->dmon))
			FWMoveWindow((*theImage)->window, windowRect.left, windowRect.top, false);
		(*theImage)->wrect = windowRect;
		OffsetRect(&(*theImage)->wrect, -(*theImage)->wrect.left, -(*theImage)->wrect.top);
		SizeWindow((*theImage)->window, Width(&windowRect), Height(&windowRect), false);
	}
	//if (EqualRect(&(*theImage)->wrect, &oldLocalRect)) return true;
	PushPort();
	MySetPort((CGrafPtr)(*theImage)->window);
	InvalRect(&(*theImage)->window->portRect);
	PopPort();
	if (!GWOrigSize(theImage) && 
		(!EqualRect(&(*theImage)->wrect, &oldLocalRect) || Dithered(theImage))) 
		KillGWorld(theImage);
	MakeTitle(theImage, theTitle);
	SetWTitle((*theImage)->window, theTitle);
	SetAntsLimitRect((*theImage)->ants, &(*theImage)->wrect);
	if (AntsHaveSelection((*theImage)->ants)) {
		Rect selRect;
		GetAntsSelection((*theImage)->ants, &selRect);
		MapRect(&selRect, &oldLocalRect, &(*theImage)->wrect);
		SetAntsSelection((*theImage)->ants, &selRect);
	}
	return true;
}

/*
 * NudgeWindowRect(windowRect, theMonitor)
 *
 *     Purpose: Nudges the given rectangle to fit on the monitor
 *      Inputs: windowRect = pointer to the rectangle to nudge
 *				theMonitor = handle to the monitor the rect is on
 *     Returns: true if it needed to be moved; false otherwise
 *
 */
 
Boolean NudgeWindowRect(Rect *windowRect, MonitorHandle theMonitor)
{
	Boolean nudged = false;
	Rect screenRect;
	short space;
	
	GetActiveRect(theMonitor, &screenRect);
	screenRect.top += gTitleBarHeight;
	if (screenRect.right <= windowRect->right) {
		OffsetRect(windowRect, screenRect.right - windowRect->right, 0);
		space = windowRect->left - screenRect.left;
		if (space > (2 * kWindowBorderWidth)) 
			OffsetRect(windowRect, -kWindowBorderWidth, 0);
		else OffsetRect(windowRect, -(space >> 1), 0);
		nudged = true;
	}
	if (screenRect.left > windowRect->left) {
		OffsetRect(windowRect, screenRect.left - windowRect->left, 0);
		space = screenRect.right - windowRect->right;
		if (space > (2 * kWindowBorderWidth)) 
			OffsetRect(windowRect, kWindowBorderWidth, 0);
		else OffsetRect(windowRect, (space >> 1), 0);
		nudged = true;
	}
	if (screenRect.bottom <= windowRect->bottom) {
		OffsetRect(windowRect, 0, screenRect.bottom - windowRect->bottom);
		space = windowRect->top - screenRect.top;
		if (space > (2 * kWindowBorderHeight)) 
			OffsetRect(windowRect, 0, -kWindowBorderHeight);
		else OffsetRect(windowRect, -(space >> 1), 0);
		nudged = true;
	}
	if (screenRect.top > windowRect->top) {
		OffsetRect(windowRect, 0, screenRect.top - windowRect->top);
		space = screenRect.bottom - windowRect->bottom;
		if (space > (2 * kWindowBorderHeight)) 
			OffsetRect(windowRect, 0, kWindowBorderHeight);
		else OffsetRect(windowRect, (space >> 1), 0);
		nudged = true;
	}
	return nudged;
}
