/*
 * Copyright (c) 2010 David McIntosh <dmcintosh@df12.net>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#import "GanttTask.h"

@implementation GanttTask

+ (GanttTask *)taskWithTag:(NSInteger)tag
                 startDate:(NSDate *)startDate
                   endDate:(NSDate *)endDate
                completion:(float)completion
{
    id task = [[GanttTask alloc] 
      initWithTag:tag
        startDate:startDate
          endDate:endDate
       completion:completion];
    return AUTORELEASE(task);
}

- (id)init
{
    return [self initWithTag:0
                   startDate:nil
                     endDate:nil
                  completion:0.0];
}

- (id)initWithTag:(NSInteger)tag 
        startDate:(NSDate *)startDate 
          endDate:(NSDate *)endDate 
       completion:(float)completion
{
    if ((self = [super init]))
    {
        [self setTag:tag];
        [self setStartDate:startDate];
        [self setEndDate:endDate];
        [self setCompletion:completion];
        _children = [[NSMutableArray alloc] init];
        [self setName:[NSString stringWithFormat:@"Task %d", tag]];
    }
    return self;
}

- (void) encodeWithCoder: (NSCoder *) encoder {
    [encoder encodeInt:[self tag] forKey:@"tag"];
    [encoder encodeObject:[self startDate] forKey:@"startDate"];
    [encoder encodeObject:[self endDate] forKey:@"endDate"];
    [encoder encodeFloat:[self completion] forKey:@"completion"];
    [encoder encodeObject:[self name] forKey:@"name"];
    [encoder encodeObject:[self children] forKey:@"children"];
}

- (id) initWithCoder: (NSCoder *) decoder {
    GanttTask *task = [self initWithTag:[decoder decodeIntForKey:@"tag"]
        startDate:[decoder decodeObjectForKey:@"startDate"]
        endDate:[decoder decodeObjectForKey:@"endDate"]
        completion:[decoder decodeFloatForKey:@"completion"]];
    [task setName:[decoder decodeObjectForKey:@"name"]];
    [task addChildren:[decoder decodeObjectForKey:@"children"]];
    return task;
}

- (BOOL)isEqualToTask:(GanttTask *)aTask
{
    if ( [self tag] != [aTask tag] )
        return NO;
    if ( ! [[self startDate] isEqualToDate:[aTask startDate]] )
        return NO;
    if ( ! [[self endDate] isEqualToDate:[aTask endDate]] )
        return NO;
    if ( [self completion] != [aTask completion] )
        return NO;
    return YES;
}

- (NSInteger)tag
{
    return _tag;
}

- (void)setTag:(NSInteger)val
{
    _tag = val;
}

- (NSDate *)startDate
{
    return _startDate;
}

- (void)setStartDate:(NSDate *)val
{
    GanttTask *parent;
    NSDate *newStart;
    if ((parent = [self parent]))
    {
        newStart = [val max:[parent startDate]];
        ASSIGNCOPY(_startDate, newStart);
    } else { 
        ASSIGNCOPY(_startDate, val);
    }
}

- (NSDate *)endDate
{
    return _endDate;
}

- (void)setEndDate:(NSDate *)val
{
    GanttTask *parent;
    NSDate *newEnd;
    if ((parent = [self parent]))
    {
        newEnd = [val min:[parent endDate]];
        ASSIGNCOPY(_endDate, newEnd);
    } else { 
        ASSIGNCOPY(_endDate, val);
    }
    UKLog(@"Set end date: %@", _endDate);
}

- (float)completion
{
    return _completion;
}

- (void)setCompletion:(float)val
{
    _completion = val;
}

- (NSString *)name
{
    return _name;
}

- (void)setName:(NSString *)val
{
    ASSIGNCOPY(_name, val);
}

- (NSArray *)children
{
    return [NSArray arrayWithArray:_children];
}

- (NSInteger)childCount
{
    return [_children count];
}

- (void)addChild:(GanttTask *)task
{
    [task setParent:self];
    [_children addObject:task];
}

- (void)addChildren:(NSArray *)tasks
{
    NSEnumerator *e = [tasks objectEnumerator];
    GanttTask *task;
    while ((task = [e nextObject]))
        [task setParent:self];
    [_children addObjectsFromArray:tasks];
}

- (void)removeChild:(GanttTask *)task
{
    [task setParent:nil];
    [_children removeObjectIdenticalTo:task];
}

- (GanttTask *)childAtIndex:(NSInteger)index
{
    return [_children objectAtIndex:index];
}

- (void)setParent:(GanttTask *)task
{
    _parent = task;
}

- (GanttTask *)parent
{
    return _parent;
}

- (void)dealloc
{
    DESTROY(_startDate);
    DESTROY(_endDate);
    DESTROY(_name);
    DESTROY(_children);
    [super dealloc];
}

@end
