//
//  Person.m
//  Person
//
//  Created by Chuck Pisula on 2/19/10.
//

#import "Person.h"

#define kDictionaryRepFirstNameKey  @"firstName"
#define kDictionaryRepLastNameKey	@"lastName"
#define kDictionaryRepIsEnrolledKey @"isEnrolled"

@implementation Person

@synthesize lastName = lastName_;
@synthesize isEnrolled = isEnrolled_;

// FIX: @synthesize for firstName was missing and needed to be added.
@synthesize firstName = firstName_;

+ (Person *)personWithDictionaryRepresentation:(NSDictionary *)dictionaryRep {
    NSString *firstName = [dictionaryRep objectForKey:kDictionaryRepFirstNameKey];
    NSString *lastName = [dictionaryRep objectForKey:kDictionaryRepLastNameKey];

// FIX: Old code was -> BOOL isEnrolled = [dictionaryRep objectForKey:kDictionaryRepIsEnrolledKey];
    BOOL isEnrolled = [[dictionaryRep objectForKey:kDictionaryRepIsEnrolledKey] boolValue];
    
    Person *person = [[Person alloc] initWithFirstName:firstName lastName:lastName];
    [person setIsEnrolled: isEnrolled];
    
// FIX: old code was missing an autorelease, and would lead to a leaked person object
    return [person autorelease];
}

- (id)initWithFirstName:(NSString *)firstName lastName:(NSString *)lastName {
    if ((self = [super init])) {
// FIX: old code did this [self setFirstName:[firstName copy]], but copy is already done by the property implementation
        [self setFirstName:firstName];
        [self setLastName:lastName];
    }
    
// FIX: old code did this: return [self autorelease], but init should not mess with the retain count
    return self;
}

- (void)dealloc {
    [firstName_ release];
    firstName_ = nil; // optional setting ivars to nil was missing
    [lastName_ release];
    lastName_ = nil; // optional setting ivars to nil was missing

// FIX: Remove this since BOOL is not an object: [isEnrolled_ release]; 

// FIX: Call to super was missing
    [super dealloc];
}

- (void)setFirstName:(NSString *)firstName {
// FIX: Old code did not check 'if (firstName != firstName_)'.  The code below will release the old object first and then copy the new object.  However, if the old and new object are the same object, this *could* lead to a crash since the -release could cause the object to be deallocated immediately.
    
    if (firstName != firstName_) {
        [firstName_ release];
        firstName_ = [firstName copy]; // Also, normally want to copy strings.
    }
}

- (NSString *)description {
    // This method was fine.  No changes needed.
    NSString *superDescription = [super description];
    return [superDescription stringByAppendingFormat:@"name = '%@'", [self fullName]];
}

- (NSString *)fullName {
// FIX: was missing an "autorelease"
    return [[[NSString alloc] initWithFormat:@"%@ %@", [self firstName], [self lastName]] autorelease];
}

- (NSDictionary *)dictionaryRepresentation {
    NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
    
// FIX: Original code did this: [dictionary setObject:[[self firstName] copy] forKey:kDictionaryRepFirstNameKey]
// FIX: NSDictionary retains its values.  If you really, really want to give the dictionary a copy, it should 
// FIX: be done as: [dictionary setObject:[[[self firstName] copy] autorelease] forKey:kDictionaryRepFirstNameKey]
    [dictionary setObject:[self firstName] forKey:kDictionaryRepFirstNameKey];
    [dictionary setObject:[self lastName] forKey:kDictionaryRepLastNameKey];
    
    [dictionary setObject:[NSNumber numberWithBool:[self isEnrolled]]
                   forKey:kDictionaryRepIsEnrolledKey];
    
// FIX: Removed an extra autorelease since [NSMutableDictionary dictionary] is already an autoreleased value.
    return dictionary;
}

@end