//	SmoothUpdater.h

#ifndef _H_SmoothUpdater
#define _H_SmoothUpdater

#include <BM.h>

EXTERN_C_START

typedef struct {
	u_long			magic;
	BM_WorldH		bmw;
	M_Rect			port_rect;
} SU_World;


typedef	struct	{
	u_long		magic;
	CGrafPtr	port;
	GDHandle	device;
} SU_GraphicsState;


#define SU_World_MEMCLR(suw_struct)		U_MEMCLR(sizeof(suw_struct), &suw_struct)
#define SU_World_CREATED(suw_struct)	(suw_struct.bmw != NULL)

#define SU_World_BM_WORLD(suw)		((suw)->bmw)

#define SU_World_GRAPH_PTR(suw)		BM_dmWorld_BW_PORT(SU_World_BM_WORLD(suw))
#define SU_World_CGRAPH_PTR(suw)	BM_dmWorld_COLOR_PORT(SU_World_BM_WORLD(suw))
#define SU_World_GDEVICE(suw)		BM_dmWorld_GDEVICE(SU_World_BM_WORLD(suw))

Err			SU_NewWorld(const M_Rect *bounds,			/* >> */
						Boolean erase,					/* >> */
						SU_World *suw);					/* << */

Err			SU_UpdateWorld(const M_Rect *bounds,		/* >> */
							SU_World *suw);				/* <> */

			// allocates new and copies bits too
Err			SU_DuplicateWorld(const SU_World *src,		/* >> */
								SU_World *dest);		/* << */

Err			SU_BlitWorld(BM_BlitMode mode,				/* >> */
							const SU_World *src,		/* >> */
							SU_World *dest);			/* <> */

Err			SU_EraseWorld(SU_World *dest);				/* <> */

Err			SU_DisposeWorld(SU_World *su);				/* <> */

			//	dest can be source1 or source2
Err			SU_XorWorlds(const SU_World *source1,		/* >> */
					const SU_World *source2,			/* >> */
					SU_World *dest);					/* <> */

Err			SU_ConvertWorldToRegion(const SU_World *src,	/* >> */
							RgnHandle *returned_rgn);	/* << */

Err			SU_InvertWorldOnscreen(const SU_World *src,	/* >> */
					Boolean hi_bit_only,				/* >> */
					GrafPtr dest_port);					/* <> */


Err			SU_SaveGraphicsState(SU_GraphicsState *state);				/* << */
Err			SU_RestoreGraphicsState(const SU_GraphicsState *state);		/* >> */


Err			SU_StartDrawingOffscreen(
					SU_World *dest,						/* <> */
					Boolean erase_dest,					/* >> */
					const M_Rect *bounds0,				/* >> */
					SU_GraphicsState *saved_state);		/* << */
	

Err			SU_StopDrawingOffscreen(
					SU_World *dest,							/* <> */
					const SU_GraphicsState *saved_state);	/* >> */


EXTERN_C_END

/* ---- front end stuff ---- */

#define		SU_START_GET_SMOOTH_UPDATE(SCREEN_RECT, SU_WORLD, ERR)	\
{																	\
	SU_GraphicsState	_graphics_state;							\
																	\
	ERR = RCE(SU_StartDrawingOffscreen(&SU_WORLD, TRUE, 			\
				&SCREEN_RECT, &_graphics_state));					\
	if (!ERR) {
		
#define		SU_END_GET_SMOOTH_UPDATE(SU_WORLD, ERR)					\
		ICE(SU_StopDrawingOffscreen(&SU_WORLD, &_graphics_state));	\
	}																\
}


#endif
