#import "NetTalkThinker.h"
#import <appkit/appkit.h>
#import <dpsclient/dpsNeXT.h>

#define	_PATTERN_END	15

static int	newClientPattern[_PATTERN_END]
	= {0, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 0};
static int	newRequestPattern[_PATTERN_END]
	= {0, 1, 2, 3, 2, 1, 2, 3, 2, 1, 2, 3, 2, 1, 2};
static int *animationPattern;
static int	patternIterator;
static int	loopCount;

@implementation NetTalkThinker(IconAnimation)

- _display: anImage
{
	//  NXAppTile is composited first at 0,0 of the icon window's content view 
	//  (this is required in order to maintain the NeXT icon look).  'anImage' is 
	//  then composited at center (centering is also a requirement).

	NXPoint	contentViewOrigin = { 0.0, 0.0 };
	NXPoint	centerPoint = { 8.0, 8.0 };
	
	[appIconContentView lockFocus];
	[appTile composite:NX_SOVER toPoint:&contentViewOrigin];
	[anImage composite:NX_SOVER toPoint:&centerPoint];
	[appIconContentView unlockFocus];
	[appIconContentView display];

	return self;
}

- _animate
{
	//  This contains logic for the icon animation (image sequencing).  Three
	//  images are used (contained in imageList).  The animationPattern
	//  provides an index into that list, giving us the right image at the right
	//  time.  The icon will 'ring' twice, and leave the phone off-hook to indicate
	//  unanswered calls.
	
	static int	offset;
	
	[self _display: [imageList objectAt: animationPattern[patternIterator++]]];
	
	if (patternIterator == (_PATTERN_END - offset))
		{
		[self removeTimedEntry];
		patternIterator = 0;
		loopCount++;
		if (loopCount < 2)
			{
			offset = 1;
			if (animationPattern == newClientPattern)
				[self perform: @selector(newClient:) with:self
					afterDelay:500 cancelPrevious:YES];
			else
				[self perform: @selector(newRequest:) with:self
					afterDelay:500 cancelPrevious:YES];
			}
		else
			{
			loopCount = offset = 0;
			if (animationPattern == newClientPattern)
				[self _display:[imageList objectAt:0]];
			else
				if ([requestList count] == 0)
					[self _display:[imageList objectAt:0]];
				else
					[self _display:[imageList objectAt:3]];
			}			
		}
		
	return self;
}

void Animate (DPSTimedEntry timedEntry, double now, id self)
{	
	[(id)self _animate];
}

- removeTimedEntry
{
	if (timedEntry)  
	{
		DPSRemoveTimedEntry (timedEntry);
		timedEntry = 0;
	}
		
	return self;
}

- newClient:sender
{
	if (timedEntry)  return self;

	animationPattern = newClientPattern;
	timedEntry = DPSAddTimedEntry(0.2,
		(DPSTimedEntryProc)Animate, (void*)self, NX_MODALRESPTHRESHOLD);

	return self;
}

- newRequest:sender
{
	if (timedEntry) 
		[self removeTimedEntry];

	if (strcmp(NXGetDefaultValue(APPNAME, NTD_MUTEALARM), NTD_NO) == 0)
		[[[[Sound alloc]
			initFromSoundfile:NXGetDefaultValue(APPNAME, NTD_SOUNDNAME)]
			play: nil] free];
	animationPattern = newRequestPattern;
	timedEntry = DPSAddTimedEntry(0.2,
		(DPSTimedEntryProc)Animate, (void*)self, NX_MODALRESPTHRESHOLD);

	return self;
}

@end
