//
//  ToDoEvent.m
//  ToDo-week1
//
//  Author: Chuck Pisula
//

#import "ToDoEvent.h"

@implementation ToDoEvent

// Use @synthesize to "implement" setter and getters for dueDate and completed properties.
@synthesize dueDate=dueDate_;
@synthesize completed=completed_;

+ (ToDoEvent *)eventWithTitle:(NSString *)title dueDate:(NSDate *)dueDate {
    /* Convenience constructor 
        - Since there is no copy/new/alloc in the method name, returned value should be autoreleased
        - Note that instead of hard-coding [ToDoEvent alloc], we use [[self class] alloc] so that we
          play nicely with anyone that decides to subclass ToDoEvent
     */
    return [[[[self class] alloc] initWithTitle:title dueDate:dueDate] autorelease];
}

- (id)initWithTitle:(NSString *)title dueDate:(NSDate *)dueDate {
    /* Default initializer
        - All init methods should funnel down to this method.
        - Only the default constructor should call "super"
     */
    if ((self = [super init])) {
        /* Using setters, or directly assigning to the instance variable is fine
           so long as the memory management calls are all correct.  The retain/copy is done inside
           setTitle:, and setDueDate:, so all we need to do is call the setters and they will take
           care of the memory management for us.
         */
        [self setTitle:title];
        [self setDueDate:dueDate];
        [self setCompleted:NO];
    }
    return self;
}

- (id)initWithTitle:(NSString *)title {
    return [self initWithTitle:title dueDate:nil];
}

- (NSString *)description {
    // Not required, but nice for debugging!
    NSString *tdeDesc = [NSString stringWithFormat:@"title=%@, dueDate=%@, completed=%@", 
                            [self title], [self dueDate], ([self isCompleted] ? @"YES" : @"NO")];
    return [NSString stringWithFormat:@"%@ %@", [super description], tdeDesc];
}

- (void)dealloc {
    // Release any retained (or copied) objects, to be safe also clear their values.
    [title_ release];
    title_ = nil;
    [dueDate_ release];
    dueDate_ = nil;
    [super dealloc];
}

- (id)copyWithZone:(NSZone *)zone {
    /* Use the designated initializer to do the heavy lifting and do most of the initialization 
       of the copy.  Fill out the rest of the object using setCompleted:, since it makes sense for the
       copy to start out with all the same values.
     */
    ToDoEvent *copy = [[[self class] alloc] initWithTitle:[self title] dueDate:[self dueDate]];
    [copy setCompleted:[self isCompleted]];
    
    // Return value is a "copy" with a retain count of 1 since "copy" is in the method name copyWithZone:
    return copy;
}

- (BOOL)isEqual:(id)other {
    /* We'll assume two events are equal if their titles, and dueDates are the same.  Note that it is okay
       if you additionally said the completed property needs to be the same since we didn't specify what 
       we wanted you to use for equality.  In a more real world application, you would probably have some
       sort of unique-identifer that you could use to identify ToDoEvents, and then all you would need to 
       do is compare the unique-identifiers.
     */
    BOOL isEqual = NO;
    if ([other isKindOfClass:[self class]]) {
        ToDoEvent *oToDo = (ToDoEvent *)other;
        isEqual = [[self title] isEqual:[oToDo title]] && [[self dueDate] isEqual:[oToDo dueDate]];
    }
    return isEqual;
}

- (NSUInteger)hash {
    // not expected or needed for Lab #1, but here for completeness
    // If two objects are equal, their hash should be the same.
    return [[self title] hash];
}

- (void)setTitle:(NSString *)title {
    // If the dates are different, then....
    if (![title_ isEqual:title]) {
        // release the old string since we are done using it.  If no one else is using this string
        // it will be deallocated and have its memory freed up for the rest of the system to use...
        [title_ release];
        
        /* Assign title_ to be a copy of title.  You could also use [title retain], but typically
           it is a good idea to copy strings, unless this is really performance sensitive code.
        
           copy returns an object that will be retained (+1 reference count) for us.  All instance variables
           should always be retained....
         */
        title_ = [title copy];
    }
}

- (NSString *)title {
    // It would also be fine to just do: return title_;
    // We'll later that sometimes doing return [[title_ retain] autorelease] can be better since it 
    // helps "extend the lifetime of the object"
    return [[title_ retain] autorelease];
}

@end
