//
//  PithosNode.m
//  pithos-macos
//
// Copyright 2011 GRNET S.A. All rights reserved.
//
// Redistribution and use in source and binary forms, with or
// without modification, are permitted provided that the following
// conditions are met:
// 
//   1. Redistributions of source code must retain the above
//      copyright notice, this list of conditions and the following
//      disclaimer.
// 
//   2. Redistributions in binary form must reproduce the above
//      copyright notice, this list of conditions and the following
//      disclaimer in the documentation and/or other materials
//      provided with the distribution.
// 
// THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
// USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
// 
// The views and conclusions contained in the software and
// documentation are those of the authors and should not be
// interpreted as representing official policies, either expressed
// or implied, of GRNET S.A.

#import "PithosNode.h"
#import "PithosNodeInfoController.h"
#import "ASIDownloadCache.h"
#import "ASIPithosRequest.h"

@implementation PithosNode
@synthesize forcedRefresh, parent, shared, sharingAccount, childrenUpdatedNotificationName, displayName, isLeafItem, icon;
@dynamic url, children, pithos, pithosAccount, pithosContainer, pithosObject;

#pragma mark -
#pragma mark Object Lifecycle

- (id)init {
    if ((self = [super init])) {
        freshness = PithosNodeStateRefreshNeeded;
        forcedRefresh = NO;
        shared = NO;
        isLeafItem = NO;
    }
    return self;
}

- (void)dealloc {
    [pithosNodeInfoController release];
    [sharingAccount release];
    [icon release];
    [displayName release];
    [childrenUpdatedNotificationName release];
    [newChildren release];
    [children release];
    [url release];
    [super dealloc];
}

- (BOOL)isEqual:(id)anObject {
    return ([anObject isKindOfClass:[self class]] && [((PithosNode *)anObject).url isEqual:self.url]);
}

- (NSUInteger)hash {
    return self.url.hash;
}

#pragma mark -
#pragma mark Properties

- (void)setShared:(BOOL)aShared {
    if (shared != aShared) {
        shared = aShared;
        [url release];
        url = nil;
    }
}

- (void)setSharingAccount:(NSString *)aSharingAccount {
    if (![sharingAccount isEqualToString:aSharingAccount]) {
        [sharingAccount release];
        sharingAccount = [aSharingAccount retain];
        [url release];
        url = nil;
    }
}

#pragma mark -
#pragma mark Actions

- (void)invalidateChildren {
    if (freshness == PithosNodeStateFresh)
        freshness = PithosNodeStateRefreshNeeded;
}

- (void)invalidateChildrenRecursive {    
    if (freshness == PithosNodeStateFresh) {
        for (PithosNode *child in children) {
            [child invalidateChildrenRecursive];
        }
        freshness = PithosNodeStateRefreshNeeded;
    }
}

- (void)refresh {
    [self invalidateChildren];
    self.children;
}

- (void)forceRefresh {
    forcedRefresh = YES;
    [self refresh];
}

- (void)showPithosNodeInfo:(id)sender {
    // Abstract method
}

- (void)pithosNodeInfoWillClose:(id)sender {
    if (pithosNodeInfoController) {
        [pithosNodeInfoController release];
        pithosNodeInfoController = nil;
    }
}

- (void)pithosNodeWillBeRemoved {
    if (pithosNodeInfoController) {
        pithosNodeInfoController.node = nil;
        [[pithosNodeInfoController window] close];
    }
    for (PithosNode *child in children) {
        [child pithosNodeWillBeRemoved];
    }
}

#pragma mark -
#pragma mark ASIHTTPRequestDelegate

- (void)performRequestFinishedDelegateInBackground:(ASIPithosRequest *)request {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        [self performSelector:NSSelectorFromString([request.userInfo objectForKey:@"didFinishSelector"]) withObject:request];
    });
}

- (void)performRequestFailedDelegateInBackground:(ASIPithosRequest *)request {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        [self performSelector:NSSelectorFromString([request.userInfo objectForKey:@"didFailSelector"]) withObject:request];
    });
}

@end