/*--------------------------------------------------------------------------
 *
 * 	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.
 *
 *	Catalog
 *
 *	Inherits From:		NSObject
 *
 *	Conforms To:		None
 *
 *	Declared In:		Catalog.h
 *
 *------------------------------------------------------------------------*/
#import "Catalog.h"
#import "AppController.h"


#define print_trace(arg,isSet) [[NXApp delegate] perform: \
		@selector(console:) withObject: \
		[NSArray arrayWithObjects:arg, \
			[NSValue value:&isSet withObjCType:"char"], nil]]
#define display(arg, isSet) [[NXApp delegate] perform: \
		@selector(display:) withObject: \
		[NSArray arrayWithObjects:arg, \
		[NSValue value:&isSet withObjCType:"char"], nil]]


#define ACCESSOR_SET_TEXT "\n\n\n\n\(1) takeValuesFromDictionary:\n\
(2) %s\n±±±±±±±±±±±±±±±±±±±±±±±±>"
#define ACCESSOR_GET_TEXT "\n\n\n\n(1) valuesForKeys:\n\
(2) %s\n<±±±±±±±±±±±±±±±±±±±±±±±±"
#define IVAR_SET_TEXT "(1) takeValuesFromDictionary:\n\
(2) matched instance variable\n±±±±±±±±±±±±±±±±±±±±±±±±>"
#define IVAR_GET_TEXT "(1) valuesForKeys:\n\
(2) matched instance variable\n<±±±±±±±±±±±±±±±±±±±±±±±±"
#define KVC_SET_TEXT "\n\n\n(1) takeValuesFromDictionary:\n\
±±±±±±±±±±±±±±±±±±±±±±±±>"
#define KVC_GET_TEXT "\n\n\n(1) valuesForKeys:\n\
<±±±±±±±±±±±±±±±±±±±±±±±±"




@implementation Catalog

/*--------------------------------------------------------------------------
 *	Initializing
 *------------------------------------------------------------------------*/
- (void) dealloc
{
	if (fullname) [fullname release];
	if (price) [price release];
	if (volumeTitle) [volumeTitle release];
	return [super dealloc];
}


/*--------------------------------------------------------------------------
 *	Accessor methods
 *------------------------------------------------------------------------*/
- authorName
{
	return fullname;
}


- volumeTitle
{
	return volumeTitle;
}


- price 
{
	id		newString, formatString;
	BOOL	isSet = NO;

	formatString = [NSString stringWithCString: ACCESSOR_GET_TEXT];	
	newString = [NSString stringWithFormat: formatString, sel_getName(_cmd)];

	print_trace(@"(1) valuesForKeys:\n(2) price\n", isSet);
	display(newString, isSet);

	return price; 
}


- setPrice: aPrice
{
	id		newString, formatString;
	BOOL	isSet = YES;

/*--------------------------------------------------------------------------
 *	the class check is to work around an association bug where different
 *	 objects are passed in when value is read from the dataStore vs. when it 
 *	 is read from the user interface.
 *------------------------------------------------------------------------*/	 
	if ([aPrice isKindOfClass: [NSNumber class]])
		price = [[NSNumber numberWithDouble:
					([aPrice doubleValue] + 10.0)] retain];
	else price = [[NSNumber numberWithFloat: [aPrice floatValue]] retain];


	formatString = [NSString stringWithCString: ACCESSOR_SET_TEXT];	
	newString = [NSString stringWithFormat: formatString, sel_getName(_cmd)];

	[[NXApp delegate] updateObjectView:self];
	print_trace(@"(1) takeValuesFromDictionary:\n(2) setPrice:\n", isSet);
	display(newString, isSet);

	return self;
}


/*--------------------------------------------------------------------------
 *	Key Value Coding protocol
 *------------------------------------------------------------------------*/
- (BOOL)takeValuesFromDictionary:(NSDictionary *)dictionary
{
	id 		object, newString;
	BOOL	isSet = YES;

 	[super takeValuesFromDictionary: dictionary];

/*--------------------------------------------------------------------------
 *	instance variables were set in the call to super, but could not be 
 *	displayed visually.  we'll do it now.
 *------------------------------------------------------------------------*/
	if (object = [dictionary objectForKey: @"fullname"]) {
		newString = [NSString stringWithCString: IVAR_SET_TEXT];	

		[[NXApp delegate] updateObjectView:self];
		print_trace(
			@"(1) takeValuesFromDictionary:\n(2) matched instance variable\n",
			isSet);
		display(newString, isSet);
	}

/*--------------------------------------------------------------------------
 *	any key/value pairs that are handled outside of the accessor / ivar
 * 	paradigm must be handled here.
 *------------------------------------------------------------------------*/
	if (object = [dictionary objectForKey: @"title"]) {
		volumeTitle = [object retain];

		newString = [NSString stringWithCString: KVC_SET_TEXT];	

		[[NXApp delegate] updateObjectView:self];
		print_trace(@"(1) takeValuesFromDictionary:\n",
						isSet);
		display(newString, isSet);
	}

	print_trace(@"±±±±±±±±±\n", isSet);
	return YES;
}


- (NSDictionary *)valuesForKeys:(NSArray *)keys
{
	id 	dictionary,	newString;
	BOOL	isSet = NO;


	dictionary = [super valuesForKeys:keys];	

/*--------------------------------------------------------------------------
 *	all instance variables were set in a call to super, but could not
 *	be displayed.  we'll do it now.
 *------------------------------------------------------------------------*/
	if ([keys containsObject: @"fullname"]) {
		newString = [NSString stringWithCString: IVAR_GET_TEXT];	
		print_trace(@"(1) valuesForKeys:\n(2) matched instance variable\n",
			isSet);
		display(newString, isSet);
	}
	

/*--------------------------------------------------------------------------
 *	any key / value pairs that are not handled via accessors or ivars
 *	can be specially handled here.  we'll display that now.
 *------------------------------------------------------------------------*/
	if ([keys containsObject: @"title"]) {
		[dictionary setObject: volumeTitle forKey: @"title"];

		newString = [NSString stringWithCString: KVC_GET_TEXT];	

		print_trace(@"(1) valuesForKeys:\n", isSet);
		display(newString, isSet);
	}

	print_trace(@"±±±±±±±±±\n", isSet);

	return dictionary;
}


@end
