//============================================================
//============================================================
//==														==
//==				Animated Cursor File					==
//==														==
//============================================================
//============================================================


#include "UnivUtilities.h"
#include "AnimCursor.h"

//========================================================  Local Variables  

acurHandle		animCursorH = kNilPointer;
Boolean			useColorCursor = FALSE;


//========================================================  Functions  
//========================================================  GetMonoCursors  

Boolean GetMonoCursors (acurHandle ballCursH)

{
	short			i, j;
	CursHandle		cursHdl;
	
	if (ballCursH)							// Were we passed a legit acur handle? 
	{
		j = (*ballCursH)->n;				// Get number of 'frames' in the acur 
		for (i = 0; i < j; i++)				// Start walking the frames 
		{
			cursHdl = GetCursor((*ballCursH)->frame[i].resID);
			if (cursHdl == kNilPointer)		// Did the cursor load? It didn't?... 
			{								// Well then, toss what we got. 
				for (j = 0; j < i; j++)
					DisposHandle((*ballCursH)->frame[j].cursorHdl);
				return(FALSE);				// And report this to mother. 
			}								// However!... 
			else							// If cursor loaded ok... 
			{								// Detach it from the resource map... 
				DetachResource((Handle)cursHdl);	// And then assign it to our struct 
				(*ballCursH)->frame[i].cursorHdl = (Handle)cursHdl;
			}
		}
	}
	return(TRUE);							// Mom, success! 
}


//========================================================  GetColorCursors  

Boolean GetColorCursors (acurHandle ballCursH)

{
	short			i, j;
	CCrsrHandle		cursHdl;
	Boolean			result = TRUE;
	
	if (ballCursH)
	{
		j = (*ballCursH)->n;				// Get the number of cursors 
		HideCursor();						// Hide the cursor 
		for (i = 0; i < j; i++)				// Walk through the acur resource 
		{
			cursHdl = GetCCursor((*ballCursH)->frame[i].resID);	// Get the cursor 
			if (cursHdl == kNilPointer)		// Make sure a real cursor was returned 
			{								// If not, trash all cursors loaded 
				for (j = 0; j < i; j++)				
					DisposCCursor((CCrsrHandle)(*ballCursH)->frame[j].cursorHdl);
				result = FALSE;			// Tell calling proc we failed 
				break;						// And break out of the loop 
			}
			else							// But, if the cursor loaded ok 
			{								// add it to our list or cursor handles 
				(*ballCursH)->frame[i].cursorHdl = (Handle)cursHdl;
				SetCCursor((CCrsrHandle)(*ballCursH)->frame[i].cursorHdl);
			}
		}
		InitCursor();						// Show the cursor again (as arrow) 
	}
	return(result);							// Return to calling proc w/ results 
}


//========================================================  InitAnimatedCursor  

void InitAnimatedCursor (acurHandle ballCursH)

{
	short			i, j;
	Boolean			useColor;
	
	useColor = isColor;
	if (!ballCursH) 
		ballCursH = (void *)GetResource('acur', 128);
	if (ballCursH && ballCursH != animCursorH)
	{
		HNoPurge((Handle)ballCursH);
		MoveHHi((Handle)ballCursH);
		HLock((Handle)ballCursH);
		if (useColor)
			useColor = GetColorCursors(ballCursH);
		if (!useColor && !GetMonoCursors(ballCursH))
			return;
		DisposCursors();
		animCursorH = ballCursH;
		useColorCursor = useColor;
		(*ballCursH)->index = 0;
	}
}


//========================================================  LoadCursors  

void LoadCursors (void)

{
	CursHandle		handCursorH;
	
	InitAnimatedCursor((acurHandle)GetResource('acur', rAcurID));
	handCursorH = GetCursor(rHandCursorID);
	HLock((Handle)handCursorH);
	handCursor = **handCursorH;
	HUnlock((Handle)handCursorH);
}


//========================================================  DisposCursors  

void DisposCursors (void)

{
	register short		i, j;
	
	if (animCursorH != kNilPointer)
	{
		j = (*animCursorH)->n;
		if (useColorCursor)
		{
			for (i = 0; i < j; i++)
			{
				if ((*animCursorH)->frame[i].cursorHdl != kNilPointer)
					DisposCCursor((CCrsrHandle)(*animCursorH)->frame[i].cursorHdl);
			}
		}
		else
		{
			for (i = 0; i < j; i++)
			{
				if ((*animCursorH)->frame[i].cursorHdl != kNilPointer)
					DisposHandle((Handle)(*animCursorH)->frame[i].cursorHdl);
			}
		}
		ReleaseResource((Handle)animCursorH);
		animCursorH = kNilPointer;
	}
}


//========================================================  IncrementCursor  

void IncrementCursor (void)

{
	if (animCursorH == 0)
		InitAnimatedCursor(kNilPointer);
	if (animCursorH)
	{
		(*animCursorH)->index++;
		(*animCursorH)->index %= (*animCursorH)->n;
		if (useColorCursor)
			SetCCursor((CCrsrHandle)(*animCursorH)->frame[(*animCursorH)->index].cursorHdl);
		else
			SetCursor((CursPtr)*(*animCursorH)->frame[(*animCursorH)->index].cursorHdl);
	}
	else
		SetCursor((CursPtr)*GetCursor(watchCursor));
}


//========================================================  DecrementCursor  

void DecrementCursor (void)

{
	if (animCursorH == 0)
		InitAnimatedCursor(kNilPointer);
	if (animCursorH)
	{
		(*animCursorH)->index--;
		if (((*animCursorH)->index) < 0)
			(*animCursorH)->index = ((*animCursorH)->n) - 1;
		if (useColorCursor)
			SetCCursor((CCrsrHandle)(*animCursorH)->frame[(*animCursorH)->index].cursorHdl);
		else
			SetCursor((CursPtr)*(*animCursorH)->frame[(*animCursorH)->index].cursorHdl);
	}
	else
		SetCursor((CursPtr)*GetCursor(watchCursor));
}


//========================================================  SpinCursor  

void SpinCursor (short incrementIndex)

{
	long		dummyLong;
	short		i;
	
	for (i = 0; i < incrementIndex; i++)
	{
		IncrementCursor();
		Delay(1, &dummyLong);
	}
}

//========================================================  BackSpinCursor  

void BackSpinCursor (short decrementIndex)

{
	long		dummyLong;
	short		i;
	
	for (i = 0; i < decrementIndex; i++)
	{
		DecrementCursor();
		Delay(1, &dummyLong);
	}
}

