/*--------------------------------------------------------------------------
 *
 * 	You may freely copy, distribute, and reuse the code in this example.
 * 	SHL Systemhouse disclaims any warranty of any kind, expressed or  
 *	implied, as to its fitness for any particular use.
 *
 *
 *	AppController
 *
 *	Inherits From:		NSObject
 *
 *	Conforms To:		None
 *
 *	Declared In:		AppController.h
 *
 *
 *------------------------------------------------------------------------*/
#import "AppController.h"
#import "MyObject.h"
#import "ScrollViewExtensions.h"
#import <foundation/NSObject.h>
#import <foundation/NSString.h>
#import <foundation/NSAutoreleasePool.h>
#import <appkit/appkit.h>

#define allocButton				[buttons1 findCellWithTag: 0]
#define deallocButton			[buttons1 findCellWithTag: 1]
#define retainButton			[buttons1 findCellWithTag: 2]
#define releaseButton			[buttons1 findCellWithTag: 3]
#define copyButton				[buttons1 findCellWithTag: 4]
#define autoreleaseButton		[buttons2 findCellWithTag: 5]
#define releasePoolButton		[buttons2 findCellWithTag: 6]


@interface AppController (Private)
- (void) _updateButtons;
- (void) _animatePool:(DPSTimedEntry)timedEntry;
@end





@implementation AppController

/*--------------------------------------------------------------------------
 *	Action Methods
 *------------------------------------------------------------------------*/
- alloc: sender
{
	NSString *text;
	
	object = [[MyObject alloc] init];
	text = [NSString stringWithFormat:@"%x", object];
	[objectText setStringValue: [text cString]];
	[objectRetainCount setIntValue: [object retainCount]];
	[self _updateButtons];
	return self;
}


- copy: sender
{
	NSString *text;

	copy = [object copy];
	[copyRetainCount setIntValue:[copy retainCount]];
	text = [NSString stringWithFormat:@"%x", copy];
	[copyText setStringValue: [text cString]];
	[copyButton setEnabled:NO];
	return self;
}


- retain: sender
{
	[object retain];
	[objectRetainCount setIntValue: [object retainCount]];
	[self _updateButtons];
	return self;
}


- release: sender
{
	[object release];
	
	if ([objectRetainCount intValue] == 1)
		{
		[objectText setStringValue: "FREED(id)"];
		[objectRetainCount setIntValue: 0];
		object = nil;
		}
	else
		{
		[objectRetainCount setIntValue: [object retainCount]];
		}
			
	[self _updateButtons];
	return self;
}


- dealloc: sender
{
	switch (NXRunAlertPanel (NULL, 
		"Deallocing an object with references !\n%s", 
		"OK", "Cancel", NULL, "(Should never send dealloc directly.)"))
		{
		case NX_ALERTALTERNATE:
			break;
		case NX_ALERTDEFAULT:
		default:
			[object dealloc];
			[objectText setStringValue: "FREED(id)"];
			[objectRetainCount setIntValue: 0];
			object = nil;
			break;
		}
		
	[self _updateButtons];
	return self;
}


- allocPool: sender
{
	NSString *text;
	
	pool = [NSAutoreleasePool new];
	text = [NSString stringWithFormat:@"%x", pool];
	[poolText setStringValue: [text cString]];
	[poolObjectCount setIntValue: 0];
	return self;
}


- autorelease: sender
{
	id	myObject;
	
	if (pool == nil) [self allocPool:nil];
	myObject = [[MyObject alloc] init];
	[self _animatePool: NULL];
	[poolObjectCount setIntValue: [poolObjectCount intValue] + 1];
	[self _updateButtons];
	return [myObject autorelease];
}


- releasePool: sender
{
	[pool release];
	[poolButton setIcon: "pool_0"];
	[poolText setStringValue: "FREED(id)"];
	[poolObjectCount setIntValue: 0];
	pool = nil;
	[self _updateButtons];
	return self;
}
	

/*--------------------------------------------------------------------------
 *	Printing Trace Information
 *------------------------------------------------------------------------*/
- console: (NSString *) aString
{
	[console sprintf: "%s", [aString cString]];
	return self;
}


@end




@implementation AppController (Private)

/*--------------------------------------------------------------------------
 *	Private
 *------------------------------------------------------------------------*/
void _animate (timedEntry, now, self)
	DPSTimedEntry	timedEntry;
	double			now;
	void*			self;
{
	[(id)self _animatePool: timedEntry];
}


- (void) _animatePool:(DPSTimedEntry)timedEntry
{

#define MAX_SEQUENCE	3
#define MAX_LOOP		3

	static int 	sequence = 0, loop = 0;
	NSString	*icon = [NSString stringWithFormat:@"pool_%d", sequence];
	
	if (timedEntry) DPSRemoveTimedEntry (timedEntry);

	[poolButton setIcon: [icon cString]];
    
	loop = (sequence == MAX_SEQUENCE ? loop + 1 : loop);
	sequence = (sequence == MAX_SEQUENCE ? 0 : sequence + 1);

	if (loop < MAX_LOOP)
		DPSAddTimedEntry (0.1, _animate, (void*)self, NX_MODALRESPTHRESHOLD);
	else
		{ loop = 0; [poolButton setIcon: "pool_4"]; }
}


- (void) _updateButtons
 {
 	BOOL enabled = object ? YES : NO;
 
	[allocButton setEnabled: !enabled];
	[copyButton setEnabled: enabled];
	[retainButton setEnabled: enabled];
	[releaseButton setEnabled: enabled];
	[deallocButton setEnabled: enabled];
	[releasePoolButton setEnabled: pool ? YES : NO];
}	


@end
