//	O.h

#include "O_p.h"
#include "Utils.h"

long		gErr;

#ifndef __68k__
	#define	O_TWIRLY_INC(_idxS, _num)	(_idxS) = (O_kTwirlType)((_idxS) + (_num))
#else
	#define	O_TWIRLY_INC(_idxS, _num)	(_idxS) = (O_kTwirlType)((_idxS) + (_num) + (_num) + (_num))
#endif

#define	O_FOR_EACH_TWIRLY_RES(_idxS)	\
	for (_idxS = O_kTwirl_START; (_idxS) < O_kTwirl_NUMTYPES; O_TWIRLY_INC(_idxS, 1))

#define	O_FOR_EACH_TWIRLY(_idxS)	\
	for (_idxS = O_kTwirl_START; (_idxS) <= O_kTwirl_END; O_TWIRLY_INC(_idxS, 1))

#define	O_FOR_EACH_TWIRLY_REVERSE(_idxS)	\
	for (_idxS = (O_kTwirlType)(O_kTwirl_END); (_idxS) >= O_kTwirl_START; O_TWIRLY_INC(_idxS, -1))

#define		O_kTwirly_ResOffset			200
static		PicHandle					s_O_TwirlyA[O_kTwirl_NUMTYPES];

OSErr		O_PreAllocate(void)
{
	Err		err = Err_NONE;
	
	if (s_O_TwirlyA[0] == NULL) {
		O_kTwirlType	loop;
		
		O_FOR_EACH_TWIRLY_RES(loop) {
		
			s_O_TwirlyA[loop] = GetPicture(O_kTwirly_ResOffset + loop);
			
			if (s_O_TwirlyA[loop] == NULL) {
				OTLN_Report(22, OTLNp_STR(12), loop);
				err = Err_ALLOC;
			}
		}
	}
	
	return err;
}

OSErr		O_PostDispose(void)
{
	O_kTwirlType	loop;

		O_FOR_EACH_TWIRLY_RES(loop) {
	
		if (s_O_TwirlyA[loop] != NULL) {
			ReleaseResource((Handle)s_O_TwirlyA[loop]);
			s_O_TwirlyA[loop] = NULL;
		}
	}
	
	return Err_NONE;
}

OSErr		O_BlitTwirly(O_kTwirlType twirly, Rect *destRect)
{
//	if (twirly == O_kTwirl_UP || twirly == O_kTwirl_DOWN) {
		EraseRect(destRect);
//	}
	
	DrawPicture(s_O_TwirlyA[twirly], destRect);

	#ifndef __68k__
		if (Is_OS_X()) {
			FlushCurPort();
	//		GrafPtr		thePort;
	//		
	//		GetPort(&thePort);
	//		QDFlushPortBuffer((CGrafPtr)thePort, NULL);
		}
	#endif

	return Err_NONE;
}

OSErr		O_TwirlArrow(Rect *destRect, Boolean twirlDown)
{
	Err				err = Err_NONE;	
	short			extraTick = 1;
	long			lastTick;
	O_kTwirlType	arrow;
	
	if (!Is_OS_X()) {
		extraTick++;
	}
	
	lastTick = TickCount();
	
	if (twirlDown) {
		O_FOR_EACH_TWIRLY(arrow) {

			err = O_BlitTwirly(arrow, destRect);
			#ifndef __68k__
				if (!err) {
					lastTick += extraTick;
					do {} while (TickCount() < lastTick);
				}
			#endif
		}
	} else {
		O_FOR_EACH_TWIRLY_REVERSE(arrow) {
	
			err = O_BlitTwirly(arrow, destRect);
			#ifndef __68k__
				if (!err) {
					lastTick += extraTick;
					do {} while (TickCount() < lastTick);
				}
			#endif
		}
	}
	
	return err;
}

/**		O_HiliteTwirly	[29]
	this is a callback from TrackMouse1, and therefore does not return an error
**/
void	O_HiliteTwirly(Rect *theRect, void *data, Boolean pressedB, Boolean Last)
{
	Boolean			upB		= *(Boolean *)data;
	O_kTwirlType	twirly	= upB 
		? (pressedB ? O_kTwirl_UP_PRESSED : O_kTwirl_UP) 
		: (pressedB ? O_kTwirl_DOWN_PRESSED : O_kTwirl_DOWN);
	
	(void)O_BlitTwirly(twirly, theRect);
}

