//
//  CSTheme.m
//  XSchemeEncoder
//
//  Created by Colin Cornaby on Mon Jan 27 2003.
//  Copyright (c) 2003 Conundrum Software. All rights reserved.
//

#import "CSTheme.h"


@implementation CSTheme

+(id)theme{
    return [[[[self class] alloc] init] autorelease];
}

+(id)themeWithDLTAFromFile:(NSString *)thePath theTags:(NSArray *)tags{
    return [[[[self class] alloc] initWithDLTAFromFile:thePath theTags:tags] autorelease];
}

+(id)themeWithThemeFromFile:(NSString *)thePath{
    return [[[[self class] alloc] initWithContentsOfFile:thePath] autorelease];
}

+(id)themeWithXMLBundle:(NSString *)thePath forLanguage:(NSString *)theLanguage{
    return [[[[self class] alloc] initWithXMLBundle:thePath forLanguage:theLanguage] autorelease];
}

-(id)initWithNewAquaTheme{
    //fill the dictionary with a fresh empty one
    theFiles = [[NSMutableDictionary alloc] init];
    theUncompressedFiles = [[NSMutableDictionary alloc] init];
    theThemeNames = [[NSMutableDictionary alloc] init];
    theLinkedFiles = [[NSMutableDictionary alloc] init];
    runOptimized = NO;
    //set ourself to be an Aqua backup
    theCurrentType = CSBackupStyleTheme;
    [self CSNicelySetupTheme];
    return self;
}


-(void)dealloc{
    [theUncompressedFiles release];
    [theFiles release];
    [theLinkedFiles release];
    [theThemeNames release];
	[super dealloc];
}

-(id)init{

    runOptimized = NO;
    //fill the dictionary with a fresh empty one
    theUncompressedFiles = [[NSMutableDictionary alloc] init];
    theFiles = [[NSMutableDictionary alloc] init];
    theLinkedFiles = [[NSMutableDictionary alloc] init];
    theThemeNames = [[NSMutableDictionary alloc] init];
    //set ourself to be an normal theme
    theCurrentType = CSDeploymentStyleTheme;
    [self CSNicelySetupTheme];
    return self;
}

-(NSString *)theName{
    return theCollectionName;
}

-(void)setName:(NSString *)theName{
    theCollectionName = theName;
}

-(id)initWithContentsOfFile:(NSString *)thePath{
    int i,j;
    runOptimized = NO;
    NSDictionary *themeContents = [[NSDictionary alloc] initWithContentsOfFile:thePath];
    NSDictionary *variationFiles;
    if([themeContents objectForKey:@"name"]!=nil){
    theCollectionName = [[themeContents objectForKey:@"name"] retain];
    }else{
    theCollectionName = [[thePath lastPathComponent] retain];
    }
    theFiles = [[NSMutableDictionary alloc] initWithDictionary:[themeContents objectForKey:@"files"]];
    theLinkedFiles = [[NSMutableDictionary alloc] init];
    theUncompressedFiles = [[NSMutableDictionary alloc] init];
    theThemeNames = [[NSMutableDictionary alloc] initWithDictionary:[themeContents objectForKey:@"variations"]];
    theCurrentType = [[themeContents objectForKey:@"themeContents"] intValue];
    for(i=0; i<[theThemeNames count]; i++){
        variationFiles = [[theThemeNames objectForKey:[[theThemeNames allKeys] objectAtIndex:i]] objectForKey:@"links"];
        for(j=0; j<[variationFiles count]; j++){
            [[[theThemeNames objectForKey:[[theThemeNames allKeys] objectAtIndex:i]] objectForKey:@"links"] setObject:[[variationFiles objectForKey:[[variationFiles allKeys] objectAtIndex:j]] stringByResolvingSymlinksInPath] forKey:[[variationFiles allKeys] objectAtIndex:j]];
        }
    }
    
    [themeContents release];
    return self;
}

+ (id)getFirstDLTAArgument:(id)line{
    char * str;
    char * pch;
    NSString *temp;
    NSString *linevar;

    str=calloc(1024,1);
    linevar = line;
    [linevar getCString:str];
    pch=strstr(str," -");
    temp = [line substringWithRange:NSMakeRange(pch-str+2, [linevar length]-(pch-str+2))];
    [temp getCString:str];
    pch=strstr(str," -");
    temp = [temp substringWithRange:NSMakeRange(0, (pch-str))];
    free(str);
    return temp;
}

+ (id)getSecondDLTAArgument:(id)line{
    char * str;
    char * pch;
    NSString *temp;
    NSString *linevar;

    str=calloc(1024,1);
    linevar = line;
    [linevar getCString:str];
    pch=strstr(str," -");
    temp = [line substringWithRange:NSMakeRange(pch-str+2, [linevar length]-(pch-str+2))];
    [temp getCString:str];
    pch=strstr(str," -");
    temp = [temp substringWithRange:NSMakeRange(pch-str+2, [temp length]-(pch-str+2))];
    free(str);
    return temp;
}

+ (id)getDynamicLink:(id)link{
    NSString *linkvar;
    linkvar = link;
    if([[link substringWithRange:NSMakeRange(0,9)] isEqualToString:@"@carbonhr"]==YES){
        linkvar =[NSString stringWithFormat:@"/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HiToolbox.framework/Versions/A/Resources/%@", [linkvar substringWithRange:NSMakeRange(10,[linkvar length]-10)]];
    }
    if([[link substringWithRange:NSMakeRange(0,4)] isEqualToString:@"@sys"]==YES){
        linkvar =[NSString stringWithFormat:@"/System/Library/%@", [linkvar substringWithRange:NSMakeRange(4,[linkvar length]-4)]];
    }
    if([[link substringWithRange:NSMakeRange(0,10)] isEqualToString:@"@coreserve"]==YES){
        linkvar =[NSString stringWithFormat:@"/System/Library/CoreServices/%@", [linkvar substringWithRange:NSMakeRange(10,[linkvar length]-10)]];
    }
    if([[link substringWithRange:NSMakeRange(0,5)] isEqualToString:@"@dock"]==YES){
        linkvar =[NSString stringWithFormat:@"/System/Library/CoreServices/Dock.app/Contents/%@", [linkvar substringWithRange:NSMakeRange(5,[linkvar length]-5)]];
    }
    if([[link substringWithRange:NSMakeRange(0,9)] isEqualToString:@"@loginwin"]==YES){
        linkvar =[NSString stringWithFormat:@"/System/Library/CoreServices/loginwindow.app/Resources/%@", [linkvar substringWithRange:NSMakeRange(9,[linkvar length]-9)]];
    }
    return linkvar;
}

-(id)initWithDLTAFromFile:(NSString *)thePath theTags:(NSArray *)tags{
    runOptimized = NO;
    int i;
    int j;
    BOOL exe;
    NSString *themescode;
    NSString *currline;
    NSString *currtag = @"";
    NSString *name = @"";
    NSString *descrip = @"";
    NSString *preview = @"";
    NSString *temp;
    NSMutableDictionary *filesToAdd = [[NSMutableDictionary alloc] init];
    theLinkedFiles = [[NSMutableDictionary alloc] init];
    int currIndex;
    //NSLog(thePath);
    theFiles = [[NSMutableDictionary alloc] init];
    theUncompressedFiles = [[NSMutableDictionary alloc] init];
    theLinkedFiles = [[NSMutableDictionary alloc] init];
    theThemeNames = [[NSMutableDictionary alloc] init];
    theCurrentType = CSDeploymentStyleTheme;
    [self CSNicelySetupTheme];
    theCollectionName = [thePath lastPathComponent];
    currIndex = 0;
    themescode = [NSString stringWithContentsOfFile:[NSString stringWithFormat:@"%@/Main.themescript", thePath]];
    exe = YES;
    int x = [CSTextReader linetotal:themescode];
    for(i=0; i<x; i++){
        currline = [CSTextReader getLine:themescode:i];
        if([currline isEqualToString:@"}{"]){
            if([name isEqualToString:@""]==NO)
                [self addVariationWithName:name];
            if([preview isEqualToString:@""]==NO)
                [self addPreviewFromFile:[NSString stringWithFormat:@"%@/%@", thePath, preview] forVariation:name];
            if([descrip isEqualToString:@""]==NO)
                [self setVariationDescriptionWithString:descrip forVariation:name];
            for(j=0; j<[[filesToAdd allValues] count]; j++){
			if([[self files] containsObject:[[[filesToAdd allKeys] objectAtIndex:j] lastPathComponent]]==NO){
                [self addFileFromFile:[NSString stringWithFormat:@"%@/%@", thePath, [[filesToAdd allKeys] objectAtIndex:j] ] fileName:[[[filesToAdd allKeys] objectAtIndex:j] lastPathComponent]];
			}
                if([[[filesToAdd allValues] objectAtIndex:j] hasSuffix:@"/"]){
                    [self addLinkForVariation:name forFile:[[filesToAdd allKeys] objectAtIndex:j] forDestination:[NSString stringWithFormat:@"%@/%@", [[filesToAdd allValues] objectAtIndex:j], [[[filesToAdd allKeys] objectAtIndex:j] lastPathComponent]]];
                }else{
                    [self addLinkForVariation:name forFile:[[filesToAdd allKeys] objectAtIndex:j] forDestination:[[filesToAdd allValues] objectAtIndex:j]];
                }
            }
            name = @"";
            preview = @"";
            descrip = @"";
            [filesToAdd removeAllObjects];
        }
        if(exe == NO){
        if([[currline substringWithRange:NSMakeRange(0,2)] isEqualToString:@"</"]==YES){
            if(currtag != nil){
            temp=[currline substringWithRange:NSMakeRange(2,[currline length]-2)];
            temp=[temp substringWithRange:NSMakeRange(0,[temp length]-1)];
            if([currtag isEqualToString:temp]==YES){
                exe = YES;
            }
            }
        }
        }
        if(exe==YES){
                if([[currline substringWithRange:NSMakeRange(0,1)] isEqualToString:@"<"]==YES && [[currline substringWithRange:NSMakeRange(0,2)] isEqualToString:@"</"]==NO){
                    temp=[currline substringWithRange:NSMakeRange(1,[currline length]-1)];
                    temp=[temp substringWithRange:NSMakeRange(0,[temp length]-1)];
                    if([tags containsObject:temp]==NO){
                        exe = NO;
                        currtag = [currline substringWithRange:NSMakeRange(1,[currline length]-1)];
                        currtag = [currtag substringWithRange:NSMakeRange(0,[currline length]-2)];
                    }
                }
                if([currline length]>=10){
                    if([[currline substringWithRange:NSMakeRange(0,9)] isEqualToString:@"thename ="]){
                        name = [currline substringWithRange:NSMakeRange(10,[currline length]-10)];
                    }
                }
                if([currline length]>=13){
                    if([[currline substringWithRange:NSMakeRange(0,12)] isEqualToString:@"thedescrip ="]){
                        descrip = [currline substringWithRange:NSMakeRange(13,[currline length]-13)];
                    }
                }
                if([currline length]>=9){
                    if([[currline substringWithRange:NSMakeRange(0,9)] isEqualToString:@"preview ="]){
                        preview = [currline substringWithRange:NSMakeRange(10,[currline length]-10)];
                    }
                }
                if([currline length]>=3){
                    if([[currline substringWithRange:NSMakeRange(0,3)] isEqualToString:@"%sf"]==YES){
                        [filesToAdd setObject:[CSTheme getDynamicLink:[CSTheme getSecondDLTAArgument:currline]] forKey:[CSTheme getFirstDLTAArgument:currline]];
                    }
                }
        }
    }

    if([name isEqualToString:@""]==NO)
        [self addVariationWithName:name];
    if([preview isEqualToString:@""]==NO)
        [self addPreviewFromFile:[NSString stringWithFormat:@"%@/%@", thePath, preview] forVariation:name];
    if([descrip isEqualToString:@""]==NO)
        [self setVariationDescriptionWithString:descrip forVariation:name];
    for(i=0; i<[[filesToAdd allValues] count]; i++){
        [self addFileFromFile:[NSString stringWithFormat:@"%@/%@", thePath, [[filesToAdd allKeys] objectAtIndex:i] ] fileName:[[filesToAdd allKeys] objectAtIndex:i]];
        if([[[filesToAdd allValues] objectAtIndex:i] hasSuffix:@"/"]){
            [self addLinkForVariation:name forFile:[[filesToAdd allKeys] objectAtIndex:i] forDestination:[NSString stringWithFormat:@"%@/%@", [[filesToAdd allValues] objectAtIndex:i], [[[filesToAdd allKeys] objectAtIndex:i] lastPathComponent]]];
        }else{
        [self addLinkForVariation:name forFile:[[filesToAdd allKeys] objectAtIndex:i] forDestination:[[filesToAdd allValues] objectAtIndex:i]];
        }
    }
    [filesToAdd release];
	[self compressFiles];
	[theCollectionName retain];
    return self;
}

- (id)CSGetMMXPath:(id)line{
    char * str;
    char * pch;
    NSString *temp;
    NSString *linevar;

    str=calloc(1024,1);
    linevar = line;
    [linevar getCString:str];
    pch=strstr(str,".theme/");
    temp = [line substringWithRange:NSMakeRange(pch-str+7, [linevar length]-(pch-str+7))];
    free(str);
    return temp;
}

-(id)initWithXMLBundle:(NSString *)thePath forLanguage:(NSString *)theLanguage{
    runOptimized = YES;
    NSDictionary *plistReader;
    NSString *themeName = @"";
    int i;
    //NSLog(thePath);
    plistReader = [[NSDictionary alloc] initWithContentsOfFile:[NSString stringWithFormat:@"%@/Info.plist", thePath]];
    theFiles = [[NSMutableDictionary alloc] init];
    theUncompressedFiles = [[NSMutableDictionary alloc] init];
    theLinkedFiles = [[NSMutableDictionary alloc] init];
    theThemeNames = [[NSMutableDictionary alloc] init];
    theCurrentType = CSDeploymentStyleTheme;
    [self CSNicelySetupTheme];
    theCollectionName = [thePath lastPathComponent];
    if([plistReader objectForKey:@"name"] != nil){
        //[self addVariationWithName:[plistReader objectForKey:@"name"]];
        if([[plistReader objectForKey:@"name"] objectForKey:theLanguage] != nil){
            [self addVariationWithName:[[plistReader objectForKey:@"name"] objectForKey:theLanguage]];
            if([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"%@/preview/%@.tiff", thePath, theLanguage]]){
				[self addPreviewFromFile:[NSString stringWithFormat:@"%@/preview/%@.tiff", thePath, theLanguage] forVariation:[[plistReader objectForKey:@"name"] objectForKey:theLanguage]];
            }
			[self setVariationDescriptionWithString:[[plistReader objectForKey:@"description"] objectForKey:theLanguage] forVariation:[[plistReader objectForKey:@"name"] objectForKey:theLanguage]];
            [self setOSTag:[plistReader objectForKey:@"os"] forVariation:[[plistReader objectForKey:@"name"] objectForKey:theLanguage]];
            themeName = [[plistReader objectForKey:@"name"] objectForKey:theLanguage];
        }
    }
    for(i=0; i<[[plistReader objectForKey:@"objects"] count]; i++){
        //NSLog([NSString stringWithFormat:@"%@/%@", thePath, [self CSGetMMXPath:[[[plistReader objectForKey:@"objects"] objectAtIndex:i] objectForKey:@"name"]]]);
        [self addFileFromFile:[NSString stringWithFormat:@"%@/%@", thePath, [self CSGetMMXPath:[[[plistReader objectForKey:@"objects"] objectAtIndex:i] objectForKey:@"name"]]] fileName:[[[[plistReader objectForKey:@"objects"] objectAtIndex:i] objectForKey:@"name"] lastPathComponent]];
        //NSLog([[[[plistReader objectForKey:@"objects"] objectAtIndex:i] objectForKey:@"name"] rangeOfString:@".theme"
        if([[[[plistReader objectForKey:@"objects"] objectAtIndex:i] objectForKey:@"prospectivePath"] hasSuffix:@"/"]){
            [self addLinkForVariation:themeName forFile:[[[[plistReader objectForKey:@"objects"] objectAtIndex:i] objectForKey:@"name"] lastPathComponent] forDestination:[NSString stringWithFormat:@"%@/%@", [[[plistReader objectForKey:@"objects"] objectAtIndex:i] objectForKey:@"prospectivePath"], [[[[plistReader objectForKey:@"objects"] objectAtIndex:i] objectForKey:@"name"] lastPathComponent]]];
        }else{
            [self addLinkForVariation:themeName forFile:[[[[plistReader objectForKey:@"objects"] objectAtIndex:i] objectForKey:@"name"] lastPathComponent] forDestination:[[[plistReader objectForKey:@"objects"] objectAtIndex:i] objectForKey:@"prospectivePath"]];
        }
    }
    [plistReader release];
	[self compressFiles];
	[theCollectionName retain];
    return self;
}

-(int)currentThemeType;
{
    return theCurrentType;
}

-(void)addVariationWithName:(NSString *)theName{
    [theThemeNames setObject:[NSMutableDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"", @"themestep", [NSMutableDictionary dictionary], [NSData data], nil] forKeys:[NSArray arrayWithObjects:@"description", @"legacyOSTag", @"links", @"preview", nil]] forKey:theName];
}

-(void)addPreviewFromFile:(NSString *)thePath forVariation:(NSString *)theVariationName{
    [[theThemeNames objectForKey:theVariationName] setObject:[RAZipper compressedDataForData:[NSData dataWithContentsOfFile:thePath]] forKey:@"preview"];
}

-(void)addPreviewFromData:(NSData *)theData forVariation:(NSString *)theVariationName{
    [[theThemeNames objectForKey:theVariationName] setObject:[RAZipper compressedDataForData:theData] forKey:@"preview"];
}

-(NSDictionary *)dictionaryForVariation:(NSString *)theVariationName{
    return [theThemeNames objectForKey:theVariationName];
}

-(void)removeVariationWithName:(NSString *)theName{
    [theThemeNames removeObjectForKey:theName];
}

-(void)removeFileWithName:(NSString *)theName{
    [self compressFiles];
    [theFiles removeObjectForKey:theName];
}

-(void)setVariationDescriptionWithString:(NSString *)theDescription forVariation:(NSString *)theVariationName{
    [[theThemeNames objectForKey:theVariationName] setObject:theDescription forKey:@"description"];
}

-(NSString *)descriptionForVariation:(NSString *)theVariationName{
    return [[theThemeNames objectForKey:theVariationName] objectForKey:@"description"];
}

-(NSData *)previewForVariation:(NSString *)theVariationName{
    if([(NSData *)[[theThemeNames objectForKey:theVariationName] objectForKey:@"preview"] length]>0){
    return [RAZipper dataForCompressedData:[[theThemeNames objectForKey:theVariationName] objectForKey:@"preview"]];
    }else{
    return nil;
    }
}

-(void)addLinkForVariation:(NSString *)theVariationName forFile:(NSString *)fileName forDestination:(NSString *)theDestination{
    [[[theThemeNames objectForKey:theVariationName] objectForKey:@"links"] setObject:fileName forKey:[theDestination stringByResolvingSymlinksInPath]];
}

-(NSArray *)allDestinationsForVariation:(NSString *)theVariationName{
    return [[[theThemeNames objectForKey:theVariationName] objectForKey:@"links"] allKeys];
}

-(NSArray *)allFilesForVariation:(NSString *)theVariationName{
    return [[[theThemeNames objectForKey:theVariationName] objectForKey:@"links"] allValues];
}

-(void)removeLinkForVariation:(NSString *)theVariationName forDestination:(NSString *)theDestination{
    [[[theThemeNames objectForKey:theVariationName] objectForKey:@"links"] removeObjectForKey:theDestination];
}

-(void)CSNicelySetupTheme{
    theCollectionName = @"New Theme";
    theFiles = [[NSMutableDictionary alloc] init];
}

-(void)addFileFromFile:(NSString *)theLocation fileName:(NSString *)theName{
    BOOL isDir;
    //if([self currentThemeType] != CSBackupStyleTheme){
    if([[NSFileManager defaultManager] fileExistsAtPath:theLocation]){
        if([[NSFileManager defaultManager] fileExistsAtPath:theLocation isDirectory:&isDir] && isDir==NO){
            if(runOptimized == YES){
                [theLinkedFiles setObject:[NSMutableDictionary dictionaryWithObjects:[NSArray arrayWithObjects:theLocation, [NSMutableData data], nil] forKeys:[NSArray arrayWithObjects:@"link", @"hash", nil]] forKey:theName];
        }else{
            [theUncompressedFiles setObject:[NSMutableDictionary dictionaryWithObjects:[NSArray arrayWithObjects:[NSData dataWithContentsOfFile:theLocation], [NSMutableData data], nil] forKeys:[NSArray arrayWithObjects:@"data", @"hash", nil]] forKey:theName];
        }
        }else{
            NSLog(@"addFileFromFile: File %@ is a directory, not added", theLocation);
        }
    }else{
        NSLog(@"addFileFromFile: File %@ does not exist", theLocation);
    }
    //}else{
        //NSLog(@"CSBackupThemes must use hashes when adding files, file not added");
    //}
}

-(void)addFileFromData:(NSData *)theData fileName:(NSString *)theName{
    [theUncompressedFiles setObject:[NSMutableDictionary dictionaryWithObjects:[NSArray arrayWithObjects:theData, [NSMutableData data], nil] forKeys:[NSArray arrayWithObjects:@"data", @"hash", nil]] forKey:theName];

}

- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)flag{
    [self writeAsThemeToPath:path atomically:flag];
    return YES;
}

-(void)writeAsThemeToPath:(NSString *)thePath atomically:(BOOL)atomYN{
    NSMutableDictionary *finalDict = [[NSMutableDictionary alloc] init];
    [self compressFiles];
    [finalDict setObject:theFiles forKey:@"files"];
    [finalDict setObject:theCollectionName forKey:@"name"];
    [finalDict setObject:theThemeNames forKey:@"variations"];
    [finalDict setObject:[NSNumber numberWithInt:theCurrentType] forKey:@"themeContents"];
    if([finalDict writeToFile:thePath atomically:atomYN]){
}else{
    NSLog(@"There was a problem saving the theme");
}
    [finalDict release];
}

-(NSData *)dataForFile:(NSString *)theName{
    id returnValue;
    if([[theFiles allKeys] containsObject:theName]){
        returnValue = [RAZipper dataForCompressedData:[[theFiles objectForKey:theName] objectForKey:@"data"]];
    } else if([[theUncompressedFiles allKeys] containsObject:theName]){
        returnValue = [[theUncompressedFiles objectForKey:theName] objectForKey:@"data"];
    } else if([[theLinkedFiles allKeys] containsObject:theName]){
        returnValue = [NSData dataWithContentsOfFile:[[theLinkedFiles objectForKey:theName] objectForKey:@"link"]];
    } else {
        NSLog(@"dataForFile: File %@ was not found within CSTheme", theName);
        returnValue= nil;
    }
    return returnValue;
}

-(void)changeNameOfVariation:(NSString *)variationName toName:(NSString*)newName{
    [theThemeNames setObject:[theThemeNames objectForKey:variationName] forKey:newName];
    if([variationName isEqualToString:newName]==NO){
    [theThemeNames removeObjectForKey:variationName];
    }
}

-(NSArray *)variations{
    return [theThemeNames allKeys];
}

-(void)addFileFromFile:(NSString *)thePath fileName:(NSString *)theName withHashForFile:(NSString *)hashFile{
    if([[NSFileManager defaultManager] fileExistsAtPath:hashFile]){
    [self addFileFromFile:thePath fileName:theName];
    [self setHashForThemeFile:theName forFile:hashFile];
    }
}
-(void)addFileFromFile:(NSString *)thePath fileName:(NSString *)theName withHashForData:(NSData *)hashFile{
        [self addFileFromFile:thePath fileName:theName];
        [self setHashForThemeFile:theName forData:hashFile];
}



-(void)setHashForThemeFile:(NSString *)theThemeFile forFile:(NSString *)thePath{
    [self compressFiles];
    [[theFiles objectForKey:theThemeFile] setObject:[CSCheckSum hashForFile:thePath] forKey:@"hash"];
}

-(BOOL)fileHasHash:(NSString *)theThemeFile{
    BOOL returnValue;
    [self compressFiles];
    //NSLog([[[theFiles objectForKey:theThemeFile] objectForKey:@"hash"] description]);
    if([[[theFiles objectForKey:theThemeFile] objectForKey:@"hash"] isEqualToData:[NSData data]]){
        returnValue = NO;
    }else{
        returnValue = YES;
    }
    return returnValue;
}

-(void)setHashForThemeFile:(NSString *)theThemeFile forData:(NSData *)thePath{
    [self compressFiles];
    [[theFiles objectForKey:theThemeFile] setObject:[CSCheckSum hashForData:thePath] forKey:@"hash"];
}

-(BOOL)compareHashForThemeFile:(NSString *)theThemeFile forFile:(NSString *)thePath{
    BOOL returnValue;
    [self compressFiles];
    //NSLog(@"External hash: %@", [[CSCheckSum hashForFile:thePath] description]);
    //NSLog(@"Submitted hash: %@", [[[theFiles objectForKey:theThemeFile] objectForKey:@"hash"] description]);
    if([[CSCheckSum hashForFile:thePath] isEqualToData:[[theFiles objectForKey:theThemeFile] objectForKey:@"hash"]]){
        returnValue = YES;
    }else{
        returnValue = NO;
    }
    return returnValue;
}

-(void)compressFiles{
    int i;
    [self compressLinkedFiles];
    for(i=0; i<[theUncompressedFiles count]; i++){
        [theFiles setObject:[NSMutableDictionary dictionaryWithObjects:[NSArray arrayWithObjects:[RAZipper compressedDataForData:[[[theUncompressedFiles allValues] objectAtIndex:i] objectForKey:@"data"]], [[[theUncompressedFiles allValues] objectAtIndex:i] objectForKey:@"hash"], nil]  forKeys:[NSArray arrayWithObjects:@"data", @"hash", nil]] forKey:[[theUncompressedFiles allKeys] objectAtIndex:i]];
    }
    [theUncompressedFiles removeAllObjects];
}

-(void)compressLinkedFiles{
    int i;
    for(i=0; i<[theLinkedFiles count]; i++){
        [theUncompressedFiles setObject:[NSMutableDictionary dictionaryWithObjects:[NSArray arrayWithObjects:[NSData dataWithContentsOfFile:[[[theLinkedFiles allValues] objectAtIndex:i] objectForKey:@"link"]], [[[theLinkedFiles allValues] objectAtIndex:i] objectForKey:@"hash"], nil]  forKeys:[NSArray arrayWithObjects:@"data", @"hash", nil]] forKey:[[theLinkedFiles allKeys] objectAtIndex:i]];
    }
    [theLinkedFiles removeAllObjects];
}

-(void)setOSTag:(NSString *)theTag forVariation:(NSString *)theVariation{
    [[theThemeNames objectForKey:theVariation] setObject:theTag forKey:@"legacyOSTag"];
}

-(NSString *)getOSTagForVariation:(NSString *)theVariation{
    return [[theThemeNames objectForKey:theVariation] objectForKey:@"legacyOSTag"];
}

-(void)runOptimized:(BOOL)ryn{
    runOptimized = ryn;
}

-(NSArray *)files{
    return [theFiles allKeys];
}

- (void)encodeWithCoder:(NSCoder *)coder
{
    //[super encodeWithCoder:coder];
	
    [coder encodeObject:theFiles forKey:@"files"];
    [coder encodeObject:theCollectionName forKey:@"name"];
    [coder encodeObject:theThemeNames forKey:@"variations"];
    [coder encodeObject:[NSNumber numberWithInt:theCurrentType] forKey:@"themeContents"];
}

- (id)initWithCoder:(NSCoder *)coder
{   int i,j;
    //self = [super initWithCoder:coder];
	NSDictionary *variationFiles;
    if([coder decodeObjectForKey:@"name"]!=nil){
    theCollectionName = [[coder decodeObjectForKey:@"name"] retain];
    }else{
    theCollectionName = @"Unknown Name";
    }
    theFiles = [[[NSMutableDictionary alloc] initWithDictionary:[coder decodeObjectForKey:@"files"]] retain];
    theLinkedFiles = [[[NSMutableDictionary alloc] init] retain];
    theUncompressedFiles = [[[NSMutableDictionary alloc] init] retain];
    theThemeNames = [[[NSMutableDictionary alloc] initWithDictionary:[coder decodeObjectForKey:@"variations"]] retain];
    theCurrentType = [[coder decodeObjectForKey:@"themeContents"] intValue];
    for(i=0; i<[theThemeNames count]; i++){
        variationFiles = [[theThemeNames objectForKey:[[theThemeNames allKeys] objectAtIndex:i]] objectForKey:@"links"];
        for(j=0; j<[variationFiles count]; j++){
            [[[theThemeNames objectForKey:[[theThemeNames allKeys] objectAtIndex:i]] objectForKey:@"links"] setObject:[[variationFiles objectForKey:[[variationFiles allKeys] objectAtIndex:j]] stringByResolvingSymlinksInPath] forKey:[[variationFiles allKeys] objectAtIndex:j]];
        }
    }
	return self;
}

    
@end
