/*--------------------------------------------------------------------------
 *
 * 	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.
 *
 *
 *	RealMutableArray
 *
 *	Inherits From:		NSMutableArray
 *
 *	Conforms To:		NSCopying, NSMutableCopying, NSCoding
 *
 *	Declared In:		RealMutableArray.h
 *
 *
 *------------------------------------------------------------------------*/
#import "RealMutableArray.h"

#define ARRAY_DEFAULT_CAPACITY 10



@implementation RealMutableArray

/*--------------------------------------------------------------------------
 *	Allocing, initing, and deallocing
 *------------------------------------------------------------------------*/
+ array
{
	return [self arrayWithCapacity:(unsigned)ARRAY_DEFAULT_CAPACITY];
}


+ arrayWithCapacity: (unsigned)aNumItems
{
	return [[[self alloc] initWithCapacity: aNumItems] autorelease];
}


- initWithCapacity:(unsigned)aNumItems
{
	unsigned iterator;

	array = [[NSMutableArray arrayWithCapacity:aNumItems] retain];
	count = 0;
	capacity = aNumItems;
	
	for (iterator = 0; iterator < aNumItems; iterator++)
		[array addObject: [[Null alloc] init]];
	
	return self;
}


- (void) dealloc
{
	[array release];
	return [super dealloc];
}


/*--------------------------------------------------------------------------
 *	Immutable array primitives
 *------------------------------------------------------------------------*/
- (unsigned)count
{
	return [array count];
}

   
- objectAtIndex:(unsigned)index
{
	id	current;

	if (index > capacity) return nil;

	current = [array objectAtIndex: index];

	if ([current isKindOfClass: [Null class]])
		return nil;
	else return current;
}	


/*--------------------------------------------------------------------------
 *	Mutable array primitives
 *------------------------------------------------------------------------*/
- (void)addObject:object
{
	unsigned	iterator = 0;

	if (count == capacity) {
		NSLog(@"RealMutable: Array full -- cannot addObject %s",
			[[object description] cString]);
		return;
	}

	while ([[array objectAtIndex: iterator]
				isKindOfClass: [Null class]] == NO)
		iterator++;

	[array replaceObjectAtIndex:iterator withObject:object];
	count++;

	return;
}


- (void)replaceObjectAtIndex:(unsigned)index withObject:object
{
	id	current = [array objectAtIndex:index];

	if ([current isKindOfClass: [Null class]] == YES)
		count++;

	return [array replaceObjectAtIndex:index withObject:object];
}


- (void)removeLastObject
{
	unsigned	iterator = capacity-1;

	if (count == 0) {
		NSLog(@"RemoveLastObject: RealMutableArray empty.");
		return;
	}

	while ([[array objectAtIndex: iterator]
			isKindOfClass: [Null class]] == YES) {
			iterator--;
	}

	[array replaceObjectAtIndex:iterator
			withObject:[[Null alloc] init]];
	count--;
	return;
}


- (void)insertObject:object atIndex:(unsigned)index
{
	id current = [array objectAtIndex: index];

	if ([current isKindOfClass: [Null class]] == YES)
		count++;

	return [array replaceObjectAtIndex:index withObject:object];
}


- (void)removeObjectAtIndex:(unsigned)index
{
	id current = [array objectAtIndex: index];

	if ([current isKindOfClass: [Null class]] == NO) {
		count--;
		[array replaceObjectAtIndex:index 
			withObject:[[Null alloc] init]];
	}

	return;
}


@end


@implementation Null : NSObject
{
}

@end
