/*
** AqDownload
** 
** CHANGES:
** 0.2  (pozytron) Added isWaiting utility method.
*/

#import "AqDownload.h"
#import "AqDownloadsController.h"
#import "AqCoreController.h"
#import "DWByteSize.h"
#import "DWCachedString.h"


@implementation AqDownload

/* Initialization */

    + (id) downloadWithInfo: (id) theInfo; {
        return [[[AqDownload alloc] initWithInfo: theInfo] autorelease];
    }
    
    - (id) initWithInfo: (id) theInfo; 
    {
        
        self = [super init];

        /* alloc */
        
            amountRequested    = [[DWByteSize alloc] init];
            amountTransferred  = [[DWByteSize alloc] init];
            bandwidth          = [[DWByteSize alloc] init];

            [amountRequested setZeroValue: @""];
            [bandwidth setZeroValue: @""];
            [bandwidth setPostfix: @"B/s"];
    
        /* values */
        
            localIdentifier = [[theInfo objectAtIndex: 1] retain];
            name            = [[theInfo objectAtIndex: 2] retain];

            [amountRequested setValue: [[theInfo objectAtIndex: 4] intValue]];
            [amountTransferred setValue: [[theInfo objectAtIndex: 5] intValue]];
            
        return self;
    }


#pragma mark -
/* Update */

    - (void) updateStats: (id) theInfo; 
    {
        /* special case when the download is active, but there are zero downloads (this is a transition point between chunks).   we ignore it to avoid flickering of the ui */
        if ([[theInfo objectAtIndex: 7] intValue] < 1 && [[theInfo objectAtIndex: 2] intValue] == 2) {
            return;
        }
        
        [amountRequested   setValue: [[theInfo objectAtIndex: 3] intValue]];
        [amountTransferred setValue: [[theInfo objectAtIndex: 4] intValue]];
        [bandwidth         setValue: [[theInfo objectAtIndex: 5] floatValue]];
        
        state       = [[theInfo objectAtIndex: 2] intValue];
        downloaders = [[theInfo objectAtIndex: 7] intValue];
        threads     = [[theInfo objectAtIndex: 8] intValue];
        busy        = [[theInfo objectAtIndex: 9] intValue];
        files       = [[theInfo objectAtIndex: 10] intValue];
        queued      = [[theInfo objectAtIndex: 11] intValue];
        
        [path release];
        path        = [[theInfo objectAtIndex: 12] retain];
        queuePosition = [[theInfo objectAtIndex: 13] intValue];

        [hosts release];
        hosts = [[theInfo objectAtIndex: 14] retain];

        //NSLog(@"%@", path);
                
        //NSLog(@"%@", theInfo);
        //NSLog(@"dlr: %@, thd: %@, bsy: %@, fls: %@, que: %@ (%@)", [theInfo objectAtIndex: 7], [theInfo objectAtIndex: 8], [theInfo objectAtIndex: 9], [theInfo objectAtIndex: 10], [theInfo objectAtIndex: 11], [self stateAsString]);
        //NSLog(@"%@, %@, %@", amountRequested, amountTransferred, bandwidth);
    }

    - (void) remove; {
        [[AqCoreController instance] writeString: [NSString stringWithFormat: @"cancelDownload|%@\n", localIdentifier]];
    }
        
    - (NSArray*) browseableHosts; {
        return [hosts componentsSeparatedByString: @","];
    }

   
#pragma mark -
/* User Interface Accessors */

    - (id) stateAsString; 
    {
        switch (state) 
        {
            case 0:	return @"Queued";
            case 1:	return @"Connecting...";
            case 2:	return (downloaders == 1) ? @"1 host" : [NSString stringWithFormat: @"%i hosts", downloaders];
            case 3:	return @"Host(s) busy";				/* Waiting to retry */
            case 4:	return @"Complete";
            case 5:	return @"Aborted";
            case 6:	return @"Host(s) offline";
            case 7:	return @"Error: Unable to move to download folder";
            case 8:	return @"Host(s) busy";				/* Waiting for sources */
            case 9:	return @"Possibly Corrupt";
            case 10:	return [NSString stringWithFormat: @"Remotely Queued (%i)", queuePosition];
            case 11:    return @"Verifying...";
            case 12:    return @"Saving...";
            case 13:    return @"Waiting for manual retry";
            case 14:    return @"Waiting for stable connections";

            default:	return [NSString stringWithFormat: @"%i", state];
        }
    }

    - (BOOL) canRetry; {
        return ![self isComplete];
    }
    
    - (BOOL) isActive; {
        return (state == 2);
    }

    - (BOOL) isComplete; {
        return (state == 4 || state == 9);
    }
    
    - (BOOL) isCorrupt; {
        return (state == 9);
    }

    - (BOOL) isOffline; {
        return (state == 3 || state == 8 || state == 6);
    }

    - (BOOL) isWaiting; {
        return (state == 1 || state == 10 || state == 14);
    }
    
    - (id) pName; {
        if (!pName) pName = DWTableStringCreate(name, [DWText normalAttributes]);
        return pName;
    }
    
    - (id) sName; {
        if (!sName) sName = DWTableStringCreate([self stateAsString], [DWText normalGrayAttributes]);
        return sName;
    }
    
    - (id) sBandwidth; {
        if (!sBandwidth) {
            if ([self isComplete] || !amountTransferred->value)
                sBandwidth = DWTableStringCreateCached([amountRequested description], [DWText normalGrayAttributes]);
            else
                sBandwidth = DWTableStringCreateCached([NSString stringWithFormat: @"%@/%@", amountTransferred, amountRequested], [DWText normalGrayAttributes]);
        }
        return sBandwidth;
    }
    
@end