/**************************************************************/
/**  C++ code Copyright (C) Nick V. King <nking@eworld.com>  **/
/**************************************************************/

#include <surf_mac.h>

#include <gui_mac.h>
#include <utils_mac.h>
#include <headers_mac.h>
#include <ids_mac.h>

macscreen::macscreen(void)
{
	Rect newBounds;
	SetRect(&newBounds, -1, -1, 0, 0);
	QDErr offscreenError = NewGWorld(&offscreenGWorld, 8, &newBounds, 0, 0, 0);

	use_left = -1;
	use_right = 0;
	use_top = -1;
	use_bottom = 0;
	_x = 0;
	_y = 0;
	_dotsize = 1;
	heap_check(gfp = new grey_font_mac(0, 0));
}

macscreen::~macscreen(void)
{
	DisposeGWorld(offscreenGWorld);
}

surface& macscreen::resize_usable(int x0, int y0, int x1, int y1, int ofsx, int ofsy)
{
	Rect newBounds;
	SetRect(&newBounds, x0, y0, x1, y1);
	GWorldFlags resultFlags = UpdateGWorld(&offscreenGWorld, 8, &newBounds, 0, 0, 0);
	if ((long)resultFlags < 0)
		IndexedStringError(stopAlertID, 9);
	else
	{
		use_left = x0;
		use_top = y0;
		use_right = x1;
		use_bottom = y1;
	}
	lock();
	clear();
	unlock();
	return *this;
}

void macscreen::moveto(const int x, const int y)
{
	MoveTo(x, y);
	_x = x;
	_y = y;
}

void macscreen::moverel(const int x, const int y)
{
	Move(x, y);
	_x += x;
	_y += y;
}

void macscreen::clear(void)
{
	extern int			backgroundColor;
	extern short		localFont;

	Rect theRect;
	SetRect(&theRect, use_top, use_left, use_right, use_bottom);
	RGBForeColor(backgroundColor == 1 ? &blackRGB : &whiteRGB);
	RGBBackColor(backgroundColor == 1 ? &whiteRGB : &blackRGB);
	EraseRect(&theRect);
	TextFont(localFont);
	gfp->length(0);
}

void macscreen::invert(void)
{
	Rect theRect;
	SetRect(&theRect, use_top, use_left, use_right, use_bottom);
	InvertRect(&theRect);
}

surface& macscreen::operator<<(LINE& theLine)
{
	MoveTo(theLine.x1(), theLine.y1());
	LineTo(theLine.x2(), theLine.y2());
	return *this;
}

surface& macscreen::operator<<(dot& theDot)
{
	Rect theDotRect;
	SetRect(&theDotRect, theDot.x(), theDot.y(),
	theDot.x()+theDot.size(), theDot.y()+theDot.size());
	PaintOval(&theDotRect);
	return *this;
}

surface& macscreen::operator<<(text& theText)
{ 
	if (theText.length())
	{
		extern Boolean	fixedTextSize;
		extern short	currentResolution;

		short xposition = theText.x();
		short yposition = theText.y();
		short height	= fixedTextSize ? 9 : theText.height();
		TextSize((short)(height*currentResolution/(float)72));
		ConstStr255Param theMessage = c2pstr((char*)(const char*)theText.words());
  		if (xposition < 0)
			xposition = image_left()+(int)((abs(xposition)/100.0) * image_width() - StringWidth(theMessage)/2);
		MoveTo(xposition, yposition+3);
		DrawString(theMessage);
	}
	return *this;
}

void macscreen::flush(void)
{
	RGBColor foregroundRGB, backgroundRGB;
	SaveColors(foregroundRGB, backgroundRGB);
	RGBForeColor(&blackRGB);
	RGBBackColor(&whiteRGB);
	if (!(gfp->null()))
	{
		for (int n = 0; n < gfp->length(); n++)
		{
			if (!(gfp->null(n)))
				fill_rect(gfp->element(n));
			_y += gfp->height();
		}
	}
	gfp->length(0);
	yield();
	RestoreColors(foregroundRGB, backgroundRGB);
}

void macscreen::fill_rect(const int n)
{
	extern int dataColor;

	Rect theBlock;
	SetRect(&theBlock, _x, _y, _x+gfp->width(), _y+gfp->height());
	if (dataColor == 1)
		DrawPicture((PicHandle)gfp->memory_pattern(n), &theBlock);
	else
		FillCRect(&theBlock, (PixPatHandle)gfp->memory_pattern(n));
}

void macscreen::print(const char* printer_name)
{
	extern TPPrPort printPort;
	extern WindowPtr mainWindow;
	extern GDHandle currentDevice;

	GDHandle saveDevice;
	CGrafPtr savePort;
	GetGWorld(&savePort, &saveDevice);

	SetGWorld((CGrafPtr)mainWindow, currentDevice);
	PrOpenPage(printPort, 0L);
	LockPixels(GetGWorldPixMap(offscreenGWorld));
	CopyBits((const BitMap*)*GetGWorldPixMap(offscreenGWorld),
	(const BitMap*)(&(*(TPrPort*)printPort).gPort.portBits),
	&offscreenGWorld->portRect, &offscreenGWorld->portRect, 0, 0);
	if (!offscreenLocked)
		UnlockPixels(GetGWorldPixMap(offscreenGWorld));
	PrClosePage(printPort);

	SetGWorld(savePort, saveDevice);
}

void macscreen::update(void)
{
	extern Rect			mainWindowContents;
	extern Point		offset;

	GDHandle saveDevice;
	CGrafPtr savePort;
	GetGWorld(&savePort, &saveDevice);
	SetGWorld((CGrafPtr)mainWindow, currentDevice);
	RGBColor foregroundRGB, backgroundRGB;
	SaveColors(foregroundRGB, backgroundRGB);
	RGBForeColor(&blackRGB);
	RGBBackColor(&whiteRGB);

	Rect sourceRect = mainWindowContents;
	OffsetRect(&sourceRect, offset.h, offset.v-toolbarHeight);

	Rect maskRect;
	SectRect(&sourceRect, &offscreenGWorld->portRect, &maskRect);
	RgnHandle maskRegion = NewRgn();
	RectRgn(maskRegion, &maskRect);

	RgnHandle outsideRegion = NewRgn();
	RectRgn(outsideRegion, &sourceRect);
	DiffRgn(outsideRegion, maskRegion, outsideRegion);
	OffsetRgn(outsideRegion, -offset.h, -offset.v+toolbarHeight);
	PenPat((ConstPatternParam)&qd.gray);
	PenMode((offset.h % 2) == (offset.v % 2) ? patCopy : notPatCopy);
	PaintRgn(outsideRegion);
	PenNormal();
	DisposeRgn(outsideRegion);

	OffsetRgn(maskRegion, -offset.h, -offset.v+toolbarHeight);
	LockPixels(GetGWorldPixMap(offscreenGWorld));
	CopyBits((const BitMap*)*GetGWorldPixMap(offscreenGWorld), &mainWindow->portBits,
	&sourceRect, &mainWindowContents, 0, maskRegion);
	if (!offscreenLocked)
		UnlockPixels(GetGWorldPixMap(offscreenGWorld));

	DisposeRgn(maskRegion);
	RestoreColors(foregroundRGB, backgroundRGB);
	SetGWorld(savePort, saveDevice);
}

void macscreen::lock(void)
{
	SetGWorld(offscreenGWorld, 0);
	LockPixels(GetGWorldPixMap(offscreenGWorld));
	offscreenLocked = true;
}

void macscreen::unlock(void)
{
	UnlockPixels(GetGWorldPixMap(offscreenGWorld));
	SetGWorld((CGrafPtr)mainWindow, currentDevice);
	offscreenLocked = false;
}

Boolean macscreen::locked(void)
{
	return(offscreenLocked);
}

PicHandle macscreen::PICT(void)
{
	GDHandle saveDevice;
	CGrafPtr savePort;
	GetGWorld(&savePort, &saveDevice);
	SetGWorld(offscreenGWorld, 0);
	LockPixels(GetGWorldPixMap(offscreenGWorld));
	PicHandle convertToPICT = OpenPicture(&offscreenGWorld->portRect);
	RGBForeColor(&blackRGB);
	RGBBackColor(&whiteRGB);
	CopyBits((const BitMap*)*GetGWorldPixMap(offscreenGWorld),
	(const BitMap*)*GetGWorldPixMap(offscreenGWorld),
	&offscreenGWorld->portRect, &offscreenGWorld->portRect, 0, 0);
	ClosePicture();
	UnlockPixels(GetGWorldPixMap(offscreenGWorld));
	SetGWorld(savePort, saveDevice);
	return(convertToPICT);
}

/***********/
/**  End  **/
/***********/

