//
//  ChannelInfo.m
//  CyTV
//
//  Created by Andreas Junghans on 14.01.08.
//  Copyright 2008 __MyCompanyName__. All rights reserved.
//

#import "ChannelInfo.h"
#import "AppleScript.h"
#import "JSON.h"


static NSMutableArray *_channelInfosSortedByNumber = nil;
static NSMutableArray *_channelInfosSortedByName = nil;

@implementation ChannelInfo

+ (void)initialize {
    if (self == [ChannelInfo class]) {
        _channelInfosSortedByNumber = [[NSMutableArray alloc] init];
        _channelInfosSortedByName = [[NSMutableArray alloc] init];
    }
}

- (void)dealloc {
    [_name release];
    [super dealloc];
}

- (void)setNumber:(long)number {
    _number = number;
}
- (long)getNumber {
    return _number;
}

- (void)setName:(NSString *)name {
    if (name == nil) {
        name = @"";
    }
    [_name autorelease];
    _name = [name retain];
}
- (NSString *)getName {
    return _name;
}

- (NSComparisonResult)compareToByNumber:(ChannelInfo *)anotherObject {
    long otherNumber = [anotherObject getNumber];
    if (_number < otherNumber) {
        return NSOrderedAscending;
    }
    if (_number > otherNumber) {
        return NSOrderedDescending;
    }
    return NSOrderedSame;
}

- (NSComparisonResult)compareToByName:(ChannelInfo *)anotherObject {
    return [_name localizedCompare:[anotherObject getName]];
}

- (NSDictionary *)toDictionary {
    return [NSDictionary dictionaryWithObjectsAndKeys:
        [NSNumber numberWithInt:_number], @"number", _name, @"name",
        nil];
}

+ (void)collectChannelInfo {
    NSAppleEventDescriptor *desc;
    
    [_channelInfosSortedByNumber removeAllObjects];
    [_channelInfosSortedByName removeAllObjects];
    
    @try {
        // first get the number of channels
        // (because if we access "every channel" later on, it will fail if there are no channels)
        desc = [AppleScript executeScript:@"tell application \"EyeTV\" to return count of channels"];
        SInt32 channelCount = [desc int32Value];
        
        // now get the recording info we want
        // TODO: add error checking
        if (channelCount > 0) {
            desc = [AppleScript executeScript:@"tell application \"EyeTV\" to return {channel number, name} of every channel"];
            NSAppleEventDescriptor* numberList = [desc descriptorAtIndex:1];
            NSAppleEventDescriptor* nameList = [desc descriptorAtIndex:2];
            ChannelInfo *channelInfo;
            int i;
            for (i = 1; i <= channelCount; ++i) {
                channelInfo = [[[ChannelInfo alloc] init] autorelease];
                [channelInfo setNumber:[[numberList descriptorAtIndex:i] int32Value]];
                [channelInfo setName:[[nameList descriptorAtIndex:i] stringValue]];
                [_channelInfosSortedByNumber addObject:channelInfo];
                [_channelInfosSortedByName addObject:channelInfo];
            }
            [_channelInfosSortedByNumber sortUsingSelector:@selector(compareToByNumber:)];
            [_channelInfosSortedByName sortUsingSelector:@selector(compareToByName:)];
        }
    } @catch (NSException *e) {
        [_channelInfosSortedByNumber removeAllObjects];
        [_channelInfosSortedByName removeAllObjects];
    }
}

+ (NSString *)getJSONForChannelsFrom:(unsigned long)fromIndex to:(unsigned long)toIndex sortedBy:(SortChannelsBy)sortedBy ascending:(BOOL)ascending {
    // TODO: Introduce a shared method for channels and recordings (and a shared superclass)
    NSArray *source = _channelInfosSortedByNumber;
    switch (sortedBy) {
        case SortByName:
            source = _channelInfosSortedByName;
            break;
    }
    unsigned long totalCount = [source count];
    NSMutableArray *results = [[NSMutableArray alloc] init];
    if (totalCount > 0) {
        if (fromIndex < 0) {
            fromIndex = 0;
        }
        if (toIndex >= totalCount) {
            toIndex = totalCount - 1;
        }
        if (fromIndex <= toIndex) {
            unsigned long i;
            if (ascending) {
                for (i = fromIndex; i <= toIndex; ++i) {
                    [results addObject:[[source objectAtIndex:i] toDictionary]];
                }
            } else {
                fromIndex = totalCount - fromIndex - 1;
                toIndex = totalCount - toIndex - 1;
                for (i = fromIndex; i >= toIndex; --i) {
                    [results addObject:[[source objectAtIndex:i] toDictionary]];
                }
            }
        }
    }
    SInt32 currentChannel = 0;
    @try {
        NSAppleEventDescriptor *desc = [AppleScript executeScript:@"tell application \"EyeTV\" to return current channel"];
        currentChannel = [desc int32Value];
    } @catch (NSException *e) {
    }
    NSDictionary *resultContainer = [NSDictionary dictionaryWithObjectsAndKeys:
        [NSNumber numberWithUnsignedLong:totalCount], @"totalCount",
        results, @"results",
        [NSNumber numberWithInt:currentChannel], @"currentChannel",
        nil];
    return [resultContainer JSONRepresentation];
}

@end
