/****************************/
/*      MISC ROUTINES       */
/* (c)2002 Pangea Software  */
/* By Brian Greenstone      */
/****************************/


/***************/
/* EXTERNALS   */
/***************/

//#include <TextUtils.h>
//#include <osutils.h>
//#include <timer.h>
//#include <DriverServices.h>
//#include <stdlib.h>
//#include <math.h>

/****************************/
/*    CONSTANTS             */
/****************************/

#define	DEFAULT_FPS	4

/**********************/
/*     VARIABLES      */
/**********************/

float	gFramesPerSecond, gFramesPerSecondFrac;


/****************** DO SYSTEM ERROR ***************/

void ShowSystemErr(long err)
{
#pragma unused (err)
}

		
/*********************** DO ALERT *******************/

void DoAlert(Str255 s)
{
#pragma unused (s)
}
		


/****************** ALLOC HANDLE ********************/

Handle AllocHandle(long size)
{
Handle	hand;
OSErr	err;

	hand = NewHandleClear(size);					// alloc in APPL
	if (hand == nil)
	{
		hand = TempNewHandle(size,&err);			// try TEMP mem
		return(hand);
	}
	else
		return(hand);								// use APPL
}


/****************** ALLOC PTR ********************/

void *AllocPtr(long size)
{
Ptr	pr;

	pr = NewPtrClear(size);						// alloc in APPL
	return(pr);
}


/************* COPY PSTR **********************/

void CopyPStr(ConstStr255Param	inSourceStr, StringPtr	outDestStr)
{
short	dataLen = inSourceStr[0] + 1;
	
	BlockMoveData(inSourceStr, outDestStr, dataLen);
	outDestStr[0] = dataLen - 1;
}


/******************* FLOAT TO STRING *******************/

void FloatToString(float num, Str255 string)
{
Str255	sf;
long	i,f;

	i = num;						// get integer part
	
	
	f = (fabs(num)-fabs((float)i)) * 10000;		// reduce num to fraction only & move decimal --> 5 places	

	if ((i==0) && (num < 0))		// special case if (-), but integer is 0
	{
		string[0] = 2;
		string[1] = '-';
		string[2] = '0';
	}
	else
		NumToString(i,string);		// make integer into string
		
	NumToString(f,sf);				// make fraction into string
	
	string[++string[0]] = '.';		// add "." into string
	
	if (f >= 1)
	{
		if (f < 1000)
			string[++string[0]] = '0';	// add 1000's zero
		if (f < 100)
			string[++string[0]] = '0';	// add 100's zero
		if (f < 10)
			string[++string[0]] = '0';	// add 10's zero
	}
	
	for (i = 0; i < sf[0]; i++)
	{
		string[++string[0]] = sf[i+1];	// copy fraction into string
	}
}


/*********************** DUMP GWORLD **********************/
//
//    Assumes that GWorld's PixMap has already been Locked
//   

void DumpGWorld(GWorldPtr thisWorld, WindowPtr thisWindow, short copyMode)
{
GrafPtr		oldPort,thisPort;
PixMapHandle pm;
Rect		srcRect,destRect;
		
		
	GetPort(&oldPort);
	pm = GetGWorldPixMap(thisWorld);	
	if ((pm == nil) || (*pm == nil))
		return;

	thisPort = GetWindowPort(thisWindow);
	SetPort(thisPort);
			
	ForeColor(blackColor);
	BackColor(whiteColor);
		
	GetPortBounds(thisPort, &destRect);
	GetPortBounds(thisWorld, &srcRect);
		
	CopyBits((BitMap *)*pm,GetPortBitMapForCopyBits(thisPort),
			&srcRect,&destRect,copyMode,0);

	SetPort(oldPort);

			/* MAKE OS X SHOW US THE WINDOW */
				
	QDFlushPortBuffer(thisPort, nil);	
	
}


/******************* DO LOCK PIXELS **************/

void DoLockPixels(GWorldPtr world)
{
PixMapHandle pm;
	
	pm = GetGWorldPixMap(world);
	LockPixels(pm);
}


/***************** DO UNLOCK PIXELS **************/

void DoUnlockPixels(GWorldPtr world)
{
	PixMapHandle pm;
	
		pm = GetGWorldPixMap(world);
		UnlockPixels(pm);
}



/************** CALC FRAMES PER SECOND *****************/
//
// This version uses UpTime() which is only available on PCI Macs.
//

void CalcFramesPerSecond(void)
{
AbsoluteTime currTime,deltaTime;
static AbsoluteTime time = {0,0};
Nanoseconds	nano;

	currTime = UpTime();

	deltaTime = SubAbsoluteFromAbsolute(currTime, time);
	nano = AbsoluteToNanoseconds(deltaTime);

	gFramesPerSecond = 1000000.0f / (float)nano.lo;
	gFramesPerSecond *= 1000.0f;

	if (gFramesPerSecond < DEFAULT_FPS)			// (avoid divide by 0's later)
		gFramesPerSecond = DEFAULT_FPS;
	gFramesPerSecondFrac = 1.0f/gFramesPerSecond;		// calc fractional for multiplication


	time = currTime;	// reset for next time interval
}


/******************* MY FLUSH EVENTS **********************/
//
// This call makes damed sure that there are no events anywhere in any event queue.
//

void MyFlushEvents(void)
{
EventRecord 	theEvent;

	FlushEvents (everyEvent, REMOVE_ALL_EVENTS);	
	FlushEventQueue(GetMainEventQueue());

			/* POLL EVENT QUEUE TO BE SURE THINGS ARE FLUSHED OUT */
			
	while (GetNextEvent(mDownMask|mUpMask|keyDownMask|keyUpMask|autoKeyMask, &theEvent));


	FlushEvents (everyEvent, REMOVE_ALL_EVENTS);	
	FlushEventQueue(GetMainEventQueue());
}


/********************** WAIT **********************/

void Wait(long ticks)
{
long	start;
	
	start = TickCount();

	while (TickCount()-start < ticks)
		MyFlushEvents();

}

