#if !defined(BRGRIMPL_H) && !defined(__BEDRC__)
#define BRGRIMPL_H
//========================================================================================
//
//     File:			BRGrImpl.h
//     Release Version:	$ 1.0d1 $
//
//     Creation Date:	9/23/92
//
//     COPYRIGHT 1992-1993 SYMANTEC CORPORATION. ALL RIGHTS RESERVED. UNPUBLISHED -- RIGHTS
//     RESERVED UNDER THE COPYRIGHT LAWS OF THE UNITED STATES. USE OF COPYRIGHT NOTICE IS
//     PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION OR DISCLOSURE.
//
//     THIS SOFTWARE CONTAINS PROPRIETARY AND CONFIDENTIAL INFORMATION OF SYMANTEC
//     CORPORATION. USE, DISCLOSURE, OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
//     EXPRESS WRITTEN PERMISSION OF SYMANTEC CORPORATION.
//
//     RESTRICTED RIGHTS LEGEND
//     Use, duplication, or disclosure by the Government is subject to restrictions as set
//     forth in subparagraph (c)(l)(ii) of the Rights in Technical Data and Computer
//     Software clause at DFARS 252.227-7013. Symantec Corporation, 10201 Torre Avenue,
//     Cupertino, CA 95014.
//
//========================================================================================

#include <stddef.h>

#ifndef BRRECT_H
#include "BRRect.h"
#endif

#ifndef GCCOLOR_H
#include "BRColor.h"
#endif

#ifndef BRGRCOMM_H
#include "BRGrComm.h"
#endif

#ifndef BRPEN_H
#include "BRPen.h"
#endif

#ifndef BRTSTRS_H
#include "BRTStrs.h"
#endif

#if defined(BR_BUILD_WIN) && !defined(_INC_WINDOWS)
#include <windows.h>
#endif

#if defined(BR_BUILD_MAC) && !defined(BRMACWIN_H)
#include "BRMacWin.h"
#endif

//========================================================================================
// Forward class declarations
//========================================================================================

class BR_CView;
class BR_CPen;
class BR_CGraphicsTool;

//========================================================================================
// Generic code
//========================================================================================

class BR_CBedToolSelector : public _BR_CAutoDestructObject
{
public:
	BR_CBedToolSelector(BR_CView* pane,
						BR_CGraphicsTool* graphicsTool,
						GraphicsToolSelectionOptions selectOptions,
						BR_SGraphicsToolSuspendResumeState* state);

	~BR_CBedToolSelector();

	BR_Boolean fUnselect;

private:
	BR_CView* fPane;
	BR_CGraphicsTool* fGraphicsTool;
	BR_Boolean m_fRestoreTool;
	GraphicsToolSelectionOptions fSelectOptions;
	BR_SGraphicsToolSuspendResumeState* fToolState;
};





//========================================================================================
// Windows code
//========================================================================================

#ifdef BR_BUILD_WIN
//========================================================================================
// BR_CBedWinGrImpl
// I use this class to encapsulate misc utility functions that I use in Windows
//========================================================================================

// ?KVV: This type should be private to BR_CBedWinGrImpl, but it's too much pain since
// 	we're working with 2 compilers at the same time.  Fix after we switch to ZTC 3.1.

class BR_CBedWinGrImpl
{
public:

	enum LineSlope
	{
		kSlope0, kSlope1, kSlope2, kSlope3, kSlope4, kSlope5, kSlope6, kSlope7, kNoSlope = 100// The start and the fEnd points are the same
	};


	static void AdjustPointsForLine(short& paneX0,
									short& paneY0,
									short paneX1,
									short paneY1,
									BR_CPen::PenThickness penThickness,
									short& paneX2,
									short& paneY2,
									BR_Boolean& paneX0Y0Changed);
	//	Interpolates the fEnd point of a line to be drawn from (x0, y0) to (x1, y1)
	//  so that (x1, y1) is hilited.  Pen size is passed as penThickness.  The result
	//  is placed in paneX2, paneY2.  PaneX0Y0Changed is set to TRUE if (paneX0, paneY0)
	//  were affected and the line drawing routine should move the start point of the line.

	static BR_CBedWinGrImpl::LineSlope GetLineSlope(short x0,
													short y0,
													short x1,
													short y1);
	// Calculates slope of a line defined by (x0, y0) to (x1, y1).  Currently we
	// recognize eight possible line slopes, and that seems to be enough.

private:
	static short abs(short a);
	// Just to make sure we're not using the macro.					 

	static POINT gCorrectionTable[][2];			// Correction table for line endpoints
};




//----------------------------------------------------------------------------------------
//	BR_CBedWinGrImpl::abs
//----------------------------------------------------------------------------------------
inline short BR_CBedWinGrImpl::abs(short a)
{
	return a >= 0 ? a : -a;
}
#endif

#ifdef BR_BUILD_WIN
//========================================================================================
// BR_CBedWinGrSharedMem
// 
// 	We need to allocate fMemory that's shared by all Bedrock applications and not
//  discarded when the application on whose behalf it was allocated terminates.
//  To achieve that, we use local fQueueHeap functions which use bcl.DLL local fQueueHeap.
//  This class doesn't really belong here, and we'll move it somewhere later.
//========================================================================================

class BR_CBedWinGrSharedMem
{
public:
	static void* Allocate(size_t size);
	//	Allocates size bytes of fMemory from the shared pool.  Returns NULL on
	// failure.

	static void* ReAllocate(void* p,
							size_t newSize);
	// Realocates a previously allocated block so that the size is newSize.
	// ReAllocate(NULL, n) is the same as Allocate(n). Returns NULL on failure.

	static void Free(void* p);
	// Frees previously allocated fMemory.  Free(NULL) is a no-op.

private:
	static void* HandleToPtr(HANDLE memHandle);
	static HANDLE PtrToHandle(void* p);
};

//----------------------------------------------------------------------------------------
//	BR_CBedWinGrSharedMem::HandleToPtr
//----------------------------------------------------------------------------------------
inline void* BR_CBedWinGrSharedMem::HandleToPtr(HANDLE memHandle)
{
	return memHandle != 0 ? (void*)(void _near*)memHandle : NULL;
}

//----------------------------------------------------------------------------------------
//	BR_CBedWinGrSharedMem::PtrToHandle
//----------------------------------------------------------------------------------------
inline HANDLE BR_CBedWinGrSharedMem::PtrToHandle(void* p)
{
	return LOWORD(p);
}
#endif

#ifdef BR_BUILD_WIN
//========================================================================================
//  BR_CBedWinGDIHandlePool:
//  
//  We do scaling ourselves, so GDI doesn's scale pens for us.  Even if we used
//  GDI to do scaling, it won't scale fonts anyway.  So we keep a pool of pens
//  and fonts of different sizes and dynamically switch GDI object handles as
//  we select fonts and pens into panes scaled by different factors
//========================================================================================

class BR_CBedWinGDIHandlePool
{
public:
	HANDLE RequestHandle(BR_CGraphicsTool* requestor,
						 unsigned short sizeInPixels,
						 const BR_CColor& objectColor,
						 unsigned short style,
						 const BR_TString<BR_Char>& name = "");
	// The client wants to use a GDI object whose size is known in pixels.  Name can
	// be NULL for pens.  An alias to "name" will be saved.

	void ReleaseHandle(HANDLE handle);
	// The client is done using this handle; we reference-count handles, so this
	// method is necessary.

	void PurgeLazyHandles();
	//ReleaseHandle does not necessary delete a handle when it's released.   This is an
	// optimization technique.  We want all handles deleted when the application quits, so
	// we call this method to ensure proper GDI object cleanup.

protected:
	BR_CBedWinGDIHandlePool();
	~BR_CBedWinGDIHandlePool();

	virtual HANDLE CreateHandle(BR_Boolean& isStockObject,
								unsigned short sizeInPixels,
								const BR_CColor& objectColor,
								unsigned short style,
								const BR_TString<BR_Char>& name) = 0;
	// Creates a new GDI object with given attributes.  Sets isStockObject to TRUE if
	// the object is a stock GDI object.

	virtual BR_Boolean IsEqual(struct SGDIHandlePoolStruct* handleInfo,
							   const BR_CColor& objectColor,
							   unsigned short style,
							   const BR_TString<BR_Char> &name) = 0;
	// Compares a GDI object fEntryArray in the table with the requested parameters.  We make
	// this virtual since some attrs (e.g., color) are a part of some GDI objects (pens)
	// and aren't of others (fonts); we're just trying to reuse GDI objects better. 

protected:
	struct SGDIHandlePoolStruct
	{
		unsigned short fRefCount;				// Objects are reference counted
		unsigned short fLazyCount;				// How many times the lazy object was not needed
		HANDLE fGDIHandle;						// The GDI handle
		BR_Boolean fIsStockObject;				// Is this is stock GDI object?
		unsigned short fSizeInPixels;			// Its size in pixels
		BR_CColor fColor;						// Its color
		unsigned short fStyle;					// Style	
		char* fName;							// For fonts, name
	};


	SGDIHandlePoolStruct* fHandleTable;
	unsigned short fStreamSize;
	unsigned short fCapacity;
	unsigned short fLazyHandles;

	enum
	{
		kResizeIncrement = 10,					// We dynamically expand the table by this many entries
		kMaxLazyHandles = 10,					// This is max # of handles we keep after they are released
		kLazyThreshold = 9						// After a lazy handle is not needed this many times, we delete it
	};


	void ReallocTable(unsigned short newTableSize);
	// Reallocates fMemory for the handle table and sets new fCapacity. BR_THROWS xMemoryExhaused on failure.

	BR_Boolean IsLazyObject(const SGDIHandlePoolStruct& table) const;
	// Checks if the object pointed by table is a lazy object that the appliation
	// no longer needs but we kept around hoping it will be needed soon.

	void DeleteEntry(SGDIHandlePoolStruct& table);
	// Deletes a table fEntryArray: deletes the GDI object handle and frees fMemory taken by the name string.
};




//----------------------------------------------------------------------------------------
//	BR_CBedWinGDIHandlePool::IsLazyObject
//----------------------------------------------------------------------------------------
inline BR_Boolean BR_CBedWinGDIHandlePool::IsLazyObject(const SGDIHandlePoolStruct &table) const
{
	return table.fRefCount == 0;
}
#endif

#ifdef BR_BUILD_WIN
//========================================================================================
//  BR_CBedWinPenPool:
//  
//  We use this to maintain a pool of GDI pens.  There is only one instance of
//  this class.
//========================================================================================

class BR_CBedWinPenPool : public BR_CBedWinGDIHandlePool
{
public:
	BR_CBedWinPenPool();
	~BR_CBedWinPenPool();

	void CreateCommonPens();
	//Creates some most common pens so that access later is faster.

	void DeleteCommonPens();
	// Deletes precreated pens.  No precreated pens should be fLeft when the
	//application terminates -- static dtors don't get called for DLLs!

protected:
	virtual HANDLE CreateHandle(BR_Boolean& isStockObject,
								unsigned short sizeInPixels,
								const BR_CColor& objectColor,
								unsigned short style,
								const BR_TString<BR_Char>& name = "");

	virtual BR_Boolean IsEqual(SGDIHandlePoolStruct* handleInfo,
							   const BR_CColor& objectColor,
							   unsigned short style,
							   const BR_TString<BR_Char>& name = "");

	HANDLE fBlackPenHandle;
	HANDLE fWhitePenHandle;
	HANDLE fNullPenHandle;
};








extern BR_CBedWinPenPool gBedWinPenPool;
#endif

#ifdef BR_BUILD_WIN
//========================================================================================
//  BR_CBedWinFontPool:
//  
//  We use this to maintain a pool of GDI fonts.  There is only one instance of
//  this class.
//========================================================================================

class BR_CBedWinFontPool : public BR_CBedWinGDIHandlePool
{
public:
	BR_CBedWinFontPool();
	~BR_CBedWinFontPool();

protected:
	virtual HANDLE CreateHandle(BR_Boolean& isStockObject,
								unsigned short sizeInPixels,
								const BR_CColor& objectColor,
								unsigned short style,
								const BR_TString<BR_Char>& name);

	virtual BR_Boolean IsEqual(SGDIHandlePoolStruct* handleInfo,
							   const BR_CColor& objectColor,
							   unsigned short style,
							   const BR_TString<BR_Char>& name);

	static int FAR PASCAL EnumFontsProc(LPLOGFONT logFont,
										LPTEXTMETRIC textMetric,
										short fontType,
										LPSTR userData);
};








extern BR_CBedWinFontPool gBedWinFontPool;

#endif

#ifdef BR_BUILD_WIN
//========================================================================================
// CLASS BR_CBedWinLineRegion
// Implements a polygon region that is used to draw lines with a pattern pen
//========================================================================================

class BR_CBedWinLineRegion : public _BR_CAutoDestructObject
{
public:
	BR_CBedWinLineRegion(short x0,
						 short y0,
						 short x1,
						 short y1,
						 BR_CPen::PenThickness thickness);
	virtual~ BR_CBedWinLineRegion();

	operator HRGN() const;

private:
	HRGN fRgnHandle;
};


//----------------------------------------------------------------------------------------
//	BR_CBedWinLineRegion::operator HRGN
//----------------------------------------------------------------------------------------
inline BR_CBedWinLineRegion::operator HRGN() const
{
	return fRgnHandle;
}
#endif

#ifdef BR_BUILD_WIN
//========================================================================================
// CLASS BR_CBedWinRectRgn
// Creates a simple rectangular region
//========================================================================================

class BR_CBedWinRectRgn : public _BR_CAutoDestructObject
{
public:
	BR_CBedWinRectRgn(RECT& rect);
	virtual~ BR_CBedWinRectRgn();

	operator HRGN() const;

	BR_Boolean fDelete;

private:
	HRGN fRgnHandle;
};

//----------------------------------------------------------------------------------------
//	BR_CBedWinRectRgn::operator HRGN
//----------------------------------------------------------------------------------------
inline BR_CBedWinRectRgn::operator HRGN() const
{
	return fRgnHandle;
}
#endif

#ifdef BR_BUILD_WIN
//========================================================================================
// CLASS BR_CBedWinRoundRectRgn
// Creates a simple round-rect region
//========================================================================================

class BR_CBedWinRoundRectRgn : public _BR_CAutoDestructObject
{
public:
	BR_CBedWinRoundRectRgn(RECT& rect,
						   POINT radii);
	virtual~ BR_CBedWinRoundRectRgn();

	operator HRGN() const;

private:
	HRGN fRgnHandle;
};

//----------------------------------------------------------------------------------------
//	BR_CBedWinRoundRectRgn::operator HRGN
//----------------------------------------------------------------------------------------
inline BR_CBedWinRoundRectRgn::operator HRGN() const
{
	return fRgnHandle;
}
#endif

#ifdef BR_BUILD_WIN
//========================================================================================
// CLASS BR_CBedWinEllipticRgn
// Creates a simple ellipse region
//========================================================================================

class BR_CBedWinEllipticRgn : public _BR_CAutoDestructObject
{
public:
	BR_CBedWinEllipticRgn(RECT& rect);
	virtual~ BR_CBedWinEllipticRgn();

	operator HRGN() const;

private:
	HRGN fRgnHandle;
};

//----------------------------------------------------------------------------------------
//	BR_CBedWinEllipticRgn::operator HRGN
//----------------------------------------------------------------------------------------
inline BR_CBedWinEllipticRgn::operator HRGN() const
{
	return fRgnHandle;
}
#endif

#ifdef BR_BUILD_WIN
//========================================================================================
// CLASS BR_CBedWinCompatibleDC
// Creates a DC compatible with the given one and destroys it in the dtor
//========================================================================================

class BR_CBedWinCompatibleDC : public _BR_CAutoDestructObject
{
public:
	BR_CBedWinCompatibleDC(HDC orgDC);
	virtual~ BR_CBedWinCompatibleDC();

	BR_Boolean fDelete;
	HDC fDC;

	operator HDC() const;
};

//----------------------------------------------------------------------------------------
//	BR_CBedWinCompatibleDC::operator HDC
//----------------------------------------------------------------------------------------
inline BR_CBedWinCompatibleDC::operator HDC() const
{
	return fDC;
}
#endif

#ifdef BR_BUILD_WIN
//========================================================================================
// CLASS BR_CBedWinBitmap
// Creates a bitmap with given color depth and size and destroys it in the dtor
//========================================================================================

class BR_CBedWinBitmap : public _BR_CAutoDestructObject
{
public:
	BR_CBedWinBitmap(BR_Distance width,
					 BR_Distance height,
					 unsigned short colorPlanes,
					 unsigned short bitsPerPixel);
	virtual~ BR_CBedWinBitmap();

	BR_Boolean fDelete;
	HANDLE fBitmap;

	operator HANDLE() const;
};

//----------------------------------------------------------------------------------------
//	BR_CBedWinBitmap::operator HANDLE
//----------------------------------------------------------------------------------------
inline BR_CBedWinBitmap::operator HANDLE() const
{
	return fBitmap;
}
#endif

#ifdef BR_BUILD_WIN
//========================================================================================
// CLASS BR_CBedWinSelectObject
// Selects a GDI object into a DC in the ctor and unselects in the dtor
//========================================================================================

class BR_CBedWinSelectObject : public _BR_CAutoDestructObject
{
public:
	BR_CBedWinSelectObject(HDC dc,
						   HANDLE gdiObject);
	virtual~ BR_CBedWinSelectObject();

	BR_Boolean fRestoreOld;

private:
	HDC fDC;
	HANDLE fOldObject;
};
#endif

#ifdef BR_BUILD_WIN
//========================================================================================
// CLASS BR_CBedWinScreenDC
// Creates a screen DC by calling 'CreateDC("DISPLAY", NULL, NULL)'
//========================================================================================

class BR_CBedWinScreenDC : public _BR_CAutoDestructObject
{
public:
	BR_CBedWinScreenDC();
	virtual~ BR_CBedWinScreenDC();

	operator HDC() const;

	HDC fDC;
};

//----------------------------------------------------------------------------------------
//	BR_CBedWinScreenDC::operator HDC
//----------------------------------------------------------------------------------------
inline BR_CBedWinScreenDC::operator HDC() const
{
	return fDC;
}
#endif

#ifdef BR_BUILD_WIN
//========================================================================================
// CLASS BR_CBedWinNullPen
// Temporarily disables the current pen
//========================================================================================

class BR_CBedWinNullPen : public _BR_CAutoDestructObject
{
public:
	BR_CBedWinNullPen(HDC dc);
	virtual~ BR_CBedWinNullPen();

private:
	HDC fDC;
	HANDLE fOldPen;
};
#endif

#ifdef BR_BUILD_WIN
//========================================================================================
// CLASS BR_CBedWinNullBrush
// Temporarily disables the current brush
//========================================================================================

class BR_CBedWinNullBrush : public _BR_CAutoDestructObject
{
public:
	BR_CBedWinNullBrush(HDC dc);
	virtual~ BR_CBedWinNullBrush();

private:
	HDC fDC;
	HANDLE fOldBrush;
};
#endif

//========================================================================================
// Macintosh code
//========================================================================================

#if defined(BR_BUILD_MAC) && !defined(BRGRHELP_H)
#include "BRGrHelp.h"
#endif

#ifdef BR_BUILD_MAC
//========================================================================================
// CLASS BR_CBedMacGrImpl
// Contains a set of static methods that are used to implement graphics on the Mac side
//========================================================================================

class BR_CBedMacGrImpl
{
public:
	// Dashed Lines
	static void DrawDashedLine(Point mouseStartPoint,
							   Point endPt,
							   BR_CPen::PenStyle penStyle);
	static void DrawDashedPoly(PolyHandle dashPoly,
							   BR_CPen::PenStyle penStyle);
	static void DrawDashedRect(const Rect& dashRect,
							   BR_CPen::PenStyle penStyle);

	// Miscellaneous
	static extended Degs2Rads(short angle);
	static short GetAngleFromSlope(Point ctPt,
								   Point pt);

	static void ThrowQuickDrawError(short err);

protected:
	static void CalcPenSizeLine(Point mouseStartPoint,
								Point endPt,
								short dashHeight,
								Point& tangDhDv);
	static void DrawDashSeg(Fixed h,
							Fixed v,
							short dashHeight,
							Point segStart,
							Point tangDhDv);
	static void InitDashedLine();
	static void DashedLine(Point mouseStartPoint,
						   Point endPt,
						   const PenState& paintStructure,
						   BR_CPen::PenStyle penStyle);

public:
	enum
	{
		kMaxDashedSegments = 12, kNumDashedStyles = 4, kMaxPenSize = 64
	};


	struct BR_SDash
	{
		short fNumSegments;
		Fixed fSegments[BR_CBedMacGrImpl::kMaxDashedSegments];
	};


	static BR_SDash gDashes[kNumDashedStyles];
	static short gLastSeg;
	static Fixed gLastSegDist;
	static Boolean gLastDrawSeg;
};



#endif

#ifdef BR_BUILD_MAC
typedef BitMapPtr* BitMapHandle;

//========================================================================================
// class BR_CBedMacPrivateOffscreen
//========================================================================================

class BR_CBedMacPrivateOffscreen : public BR_CDrawEnvironment
{
public:

	typedef enum
	{
		kDeepestScreen, kLargestAreaScreen
	} ScreenOption;

	enum
	{
		kDefaultDepth = -1
	};


	virtual~ BR_CBedMacPrivateOffscreen();

	virtual short GetPixelDepth() const = 0;
	virtual CTabHandle GetColors() const = 0;

	virtual void GetResolution(BR_CPoint& ptResolution) const = 0;

	virtual OSErr SetBitMapSize(BR_Distance width,
								BR_Distance height) = 0;

	static BR_CBedMacPrivateOffscreen* OffscreenFromPixMap(PixMapHandle pmh);

	static OSErr MakeBestBitMap(BR_CBedMacPrivateOffscreen** theOffscreen,
												 const Rect &bounds,
												 short depth,
												 CTabHandle colors);// Color table to assign to off-screen

	static OSErr MakeBestBitMapForScreen(BR_CBedMacPrivateOffscreen** theOffscreen,
														  const Rect &bounds,    
														  ScreenOption screenOption);// Choose greatest depth or greatest area

	virtual void GetBoundsRect(Rect &r) const;
	PixMapHandle GetBitMapHandle() const;
	void SetBitMapHandle(PixMapHandle hPix);

	virtual BitMapPtr LockOffscreenPixels() = 0;
	virtual void UnlockOffscreenPixels() = 0;
	virtual Boolean PixelsLocked() const;

	// Prepare creates a drawing environment for the Pixel Buffer so it can be drawn upon.
	virtual OSErr PrepareOffscreen() = 0;

	// UnPrepareOffscreen tears down a drawing environment leaving the pixel buffer remaining.
	virtual void UnPrepareOffscreen() = 0;

	virtual OSErr CreatePixelBuffer(const Rect &bounds,
									// Bounds in Global Coords
									short depth = kDefaultDepth,
									// Image Depth
									CTabHandle colors = nil,
									BR_Boolean useTemporaryStorage = FALSE) = 0;// color table for pixmap

	virtual OSErr CreateForScreen(const Rect &bounds, 			 // Global Rectangle
								  ScreenOption screenOption) = 0;//Choose greatest depth or greatest area

	virtual void Dispose() = 0;					// Release the internals

	virtual void Copy(BR_CBedMacPrivateOffscreen &destbits,
									  const Rect &dest,
									  short xferMode);
	virtual void BlitAll(short xfermode);
	virtual void Blit(const Rect &dest,
									  short xferMode);
	virtual void BlitTo(BR_CDrawEnvironment &dest,
										short xferMode);
protected:
	PixMapHandle fBits;
	BR_CBedMacPrivateOffscreen();

	void SetPixelsLocked(Boolean bitsLocked);
	virtual void PrepareToDispose();

	static OSErr GetScreenGDevice(GDHandle* screenGDevice,
												   const Rect &bounds,  
												   ScreenOption screenOption);// Choose greatest depth or greatest area

	virtual void ClearOffscreenFields();

private:
	BR_Boolean fBitsLocked;
};

//----------------------------------------------------------------------------------------
//	BR_CBedMacPrivateOffscreen::GetBitMapHandle
//----------------------------------------------------------------------------------------
inline PixMapHandle BR_CBedMacPrivateOffscreen::GetBitMapHandle() const
{
	return fBits;
}

//----------------------------------------------------------------------------------------
//	BR_CBedMacPrivateOffscreen::SetBitMapHandle
//----------------------------------------------------------------------------------------
inline void BR_CBedMacPrivateOffscreen::SetBitMapHandle(PixMapHandle hPix)
{
	fBits = hPix;
}
#endif

#ifdef BR_BUILD_MAC
//========================================================================================
// class BR_CBedMacGrafPortBitMap
//========================================================================================

class BR_CBedMacGrafPortBitMap : public BR_CBedMacPrivateOffscreen
{
public:
	BR_CBedMacGrafPortBitMap();
	virtual~ BR_CBedMacGrafPortBitMap();
	virtual BitMapPtr LockOffscreenPixels();
	virtual void UnlockOffscreenPixels();

	virtual OSErr PrepareOffscreen();
	virtual void UnPrepareOffscreen();

	virtual short GetPixelDepth() const;
	virtual CTabHandle GetColors() const;

	virtual OSErr SetBitMapSize(BR_Distance width,
								BR_Distance height);

	virtual void GetResolution(BR_CPoint& ptResolution) const;

	virtual OSErr CreatePixelBuffer(const Rect& bounds,
									short depth,
									CTabHandle table,
									BR_Boolean useTemporaryStorage);

	virtual OSErr CreateForScreen(const Rect& bounds,		 // Global Rectangle
								  ScreenOption screenOption);// Choose greatest depth or greatest area

	virtual void Dispose();						// Release the internals
};



#endif

#ifdef BR_BUILD_MAC
//========================================================================================
// class BR_CBedMacColorGrafPortBitMap
//========================================================================================

class BR_CBedMacColorGrafPortBitMap : public BR_CBedMacPrivateOffscreen
{
public:
	virtual~ BR_CBedMacColorGrafPortBitMap();
	BR_CBedMacColorGrafPortBitMap();

	virtual BitMapPtr LockOffscreenPixels();
	virtual void UnlockOffscreenPixels();

	virtual OSErr PrepareOffscreen();
	virtual void UnPrepareOffscreen();

	virtual short GetPixelDepth() const;
	virtual CTabHandle GetColors() const;

	virtual OSErr SetBitMapSize(BR_Distance width,
								BR_Distance height);

	virtual void GetResolution(BR_CPoint& ptResolution) const;

	virtual OSErr CreatePixelBuffer(const Rect &bounds,
													   short depth,
													   CTabHandle colors,
													   BR_Boolean useTemporaryStorage);// Color table to assign to off-screen

	virtual OSErr CreateForScreen(const Rect &bounds,
								  // Global Rectangle
								  ScreenOption screenOption);// Choose greatest depth or greatest area

	virtual void Dispose();						//Release the internals

protected:

	static OSErr SetUpPixMap(short depth		/* Desired number of bits/pixel in off-screen */,
							 const Rect& bounds		/* Desired Bounding Rect in Global Coords */,
							 CTabHandle colors	/* Color table to assign to off-screen */,
							 short bytesPerRow	/* Number of bytes per row in the PixMap */,
							 BR_Boolean useTempMem,
							 PixMapHandle& aPixMap/* Handle to the PixMap being initialized */ );

	static OSErr CreateGDevice(PixMapHandle basePixMap/* Handle to the PixMap to base GDevice on */ ,
							   GDHandle* retGDevice/* Returns a handle to the new GDevice */ );

	static OSErr VerifyImageInfo(const Rect &bounds,
													 short depth,
													 CTabHandle colors,
													 short* bytesPerRow);
};
#endif

#ifdef BR_BUILD_MAC
//========================================================================================
//	CLASS BR_CBedMacTempRgn
//
//		We use this class whenever we need to make a temporary region.  It knows about
//		exception handling so it's safe to use, too.
//
//========================================================================================

class BR_CBedMacTempRgn : public _BR_CAutoDestructObject
{
public:
	BR_CBedMacTempRgn();
	~BR_CBedMacTempRgn();

	operator RgnHandle() const;
	void GetBoundingBox(Rect& bounds) const;

	RgnHandle fRgnHandle;
};

//----------------------------------------------------------------------------------------
//	BR_CBedMacTempRgn::operator RgnHandle
//----------------------------------------------------------------------------------------
inline BR_CBedMacTempRgn::operator RgnHandle() const
{
	return fRgnHandle;
}
#endif

#ifdef BR_BUILD_MAC
//========================================================================================
//	CLASS BR_CBedMacGrafPort
//
//		Used to create a self-cleaning-up mono GrafPort.  Some QuickDraw routines
//		(line SeedCFill) require a GrafPort and will not work with a PixMap
//
//========================================================================================

class BR_CBedMacGrafPort : public _BR_CAutoDestructObject
{
public:
	BR_CBedMacGrafPort(const Rect& bounds);
	~BR_CBedMacGrafPort();

	operator GrafPtr() const;

	GrafPtr fGrafPtr;
};

//----------------------------------------------------------------------------------------
//	BR_CBedMacGrafPort::operator GrafPtr
//----------------------------------------------------------------------------------------
inline BR_CBedMacGrafPort::operator GrafPtr() const
{
	return fGrafPtr;
}

#endif

//========================================================================================
//	Macros
//
//		This is to make sure the canvas is being drawn to when a method is called
//
//========================================================================================

#ifdef BR_DEBUG
#  define DOCANVASCHECK_VOID()		BR_ASSERT(fView != NULL); \
                                    BR_ASSERT(fView->BedIsDrawing()); \
                                    if(!fView->BedIsDrawing() || fView == NULL) \
										return
#  define DOCANVASCHECK_VALUE(val)	BR_ASSERT(fView != NULL); \
                                    BR_ASSERT(fView->BedIsDrawing()); \
                                    if(!fView->BedIsDrawing() || fView == NULL) \
										return(val)
#else
#  define DOCANVASCHECK_VOID()
#  define DOCANVASCHECK_VALUE(val)
#endif

#endif


