#import "PBDHCController.h"

@implementation PBDHCController
- (void)addButtonClicked:(id)sender
{
    int result;
    static NSString *lastDirectory = nil;
    static NSArray *fileTypes = nil;
    NSOpenPanel *openPanel = [NSOpenPanel openPanel];

    // static initialization
    if (fileTypes == nil)
        fileTypes = [[NSArray arrayWithObject:@"bundle"] retain];

    // configure open panel
    //b [openPanel setCanChooseDirectories: YES]; -- this causes a bug
    [openPanel setAllowsMultipleSelection: YES];
    [openPanel setCanChooseFiles: NO];

    // run the panel
    result = [openPanel runModalForDirectory: lastDirectory
                                        file: nil
                                       types: fileTypes];

    // check the result
    if (result == NSOKButton) {
        NSString *theDirectory = [openPanel directory];
        NSArray *filenames = [openPanel filenames];
        NSEnumerator *fileEnumerator;
        NSString *filePath;

        // enumerate files to be opened
        fileEnumerator = [filenames objectEnumerator];
        while ( (filePath = [fileEnumerator nextObject]) != nil)
            if([currentBundlesLoadedAtLaunch containsObject: filePath] == NO)
                [currentBundlesLoadedAtLaunch addObject: filePath];

        // set last directory
        if (lastDirectory != theDirectory)
            [lastDirectory release];
        lastDirectory = [theDirectory retain];
    }

    [self setDefaultObject: currentBundlesLoadedAtLaunch forKey: @"BundlesLoadedAtLaunch"];
    [self synchronizeWithProjectBuilder: nil];
}

- (void)removeButtonClicked:(id)sender
{
    [currentBundlesLoadedAtLaunch removeObjectAtIndex: [bundleTable selectedRow]];
    [self setDefaultObject: currentBundlesLoadedAtLaunch forKey: @"BundlesLoadedAtLaunch"];
    [self synchronizeWithProjectBuilder: nil];
}

- (void)installDHCButtonClicked: (id)sender
{
    [currentBundlesLoadedAtLaunch addObject: [[NSBundle mainBundle] pathForResource: @"PBDHColorBundle" ofType: @"bundle"]];
    [self setDefaultObject: currentBundlesLoadedAtLaunch forKey: @"BundlesLoadedAtLaunch"];
    [self synchronizeWithProjectBuilder: nil];
}

- (void)uninstallDHCButtonClicked: (id)sender
{
    int i,max;

    for (i = 0, max = [currentBundlesLoadedAtLaunch count]; i < max; i++)
        if ([@"PBDHColorBundle" isEqualToString: [[[currentBundlesLoadedAtLaunch objectAtIndex: i] lastPathComponent] stringByDeletingPathExtension]]) {
            [currentBundlesLoadedAtLaunch removeObjectAtIndex: i];
            [self setDefaultObject: currentBundlesLoadedAtLaunch forKey: @"BundlesLoadedAtLaunch"];
            [self synchronizeWithProjectBuilder: nil];
            break;
        }
}

- (void)setDHCColor:(id)sender
{
    [self setCurrentDebuggingHighlightColor: [debugColorWell color]];
}

- (void) setInfoText: aTextObject
{
    infoText = [aTextObject retain]; // is the retain necessary?

    [infoText readRTFDFromFile: [[NSBundle mainBundle] pathForResource: @"PBDHColor_README" ofType: @"rtf"]];
    [infoText setBackgroundColor: [NSColor colorWithCalibratedRed: 0.0 green: 0.0 blue: 17.0 / 255.0 alpha: 1.0]];
    [infoText setTextColor: [NSColor whiteColor]];
}

- (void)showInfoPanel:(id)sender;
{
    if (infoPanel == nil)
        [NSBundle loadNibNamed: @"PBDHInfoPanel" owner: self];

    [infoPanel makeKeyAndOrderFront: self];
}

// defaults
- (void) setCurrentDebuggingHighlightColor: (NSColor *) aColor;
{
    [self setDefaultObject: aColor forKey: @"PBDebugHighlightColor"];
    [self synchronizeWithProjectBuilder: nil];
}

- (void) synchronizeWithProjectBuilder: sender
{
    id pbDefaultsDictionary;

    [[NSUserDefaults standardUserDefaults] synchronize];

    pbDefaultsDictionary = [[NSUserDefaults standardUserDefaults] persistentDomainForName: @"ProjectBuilder"];

//    NSColor *currentPBDebugHighlightColor;
//    NSArray *currentBundlesLoadedAtLaunch;

    if (currentBundlesLoadedAtLaunch != nil)
        [currentBundlesLoadedAtLaunch release];
    currentBundlesLoadedAtLaunch = [[pbDefaultsDictionary objectForKey: @"BundlesLoadedAtLaunch"] mutableCopy];
    if ([currentBundlesLoadedAtLaunch count] == 0)
        currentBundlesIsEmpty = YES;

    if (currentPBDebugHighlightColor != nil)
        [currentPBDebugHighlightColor release];

    currentPBDebugHighlightColor = [[self colorFromRGBString: [pbDefaultsDictionary objectForKey: @"PBDebugHighlightColor"]] retain];

    if ([self isBundleLoaded: @"PBDHColorBundle"] == YES) {
        [debugAddRemoveButton setTitle: @"Uninstall DHC Bundle"];
        [debugAddRemoveButton setAction: @selector(uninstallDHCButtonClicked:)];
    } else {
        [debugAddRemoveButton setTitle: @"Install DHC Bundle"];
        [debugAddRemoveButton setAction: @selector(installDHCButtonClicked:)];
    }

    [debugColorWell setColor: currentPBDebugHighlightColor];
    [bundleTable reloadData];
}

- (NSString *) rgbStringFromColor: (NSColor *) aColor
{
    NSColor *convertedColor = [aColor colorUsingColorSpaceName: NSCalibratedRGBColorSpace];
    return [NSString stringWithFormat: @"%0.3f %0.3f %0.3f",
        [convertedColor redComponent],
        [convertedColor greenComponent],
        [convertedColor blueComponent]];
}

- (NSColor *) colorFromRGBString: (NSString *) aString
{
    NSScanner *floatScanner = [NSScanner scannerWithString: aString];
    float red, green, blue;

    if (aString == nil)
        return [NSColor yellowColor];

    [floatScanner scanFloat: &red];
    [floatScanner scanFloat: &green];
    [floatScanner scanFloat: &blue];

    return [NSColor colorWithCalibratedRed: red green: green blue: blue alpha: 1.0];
}

- (BOOL) isBundleLoaded: (NSString *) aBundleNamed;
{
    NSEnumerator *pathEnum;
    NSString *nextObject;

    pathEnum = [currentBundlesLoadedAtLaunch objectEnumerator];
    while ( (nextObject = [pathEnum nextObject]) != nil )
        if ([aBundleNamed isEqualToString: [[nextObject lastPathComponent] stringByDeletingPathExtension]] == YES)
            return YES;

    return NO;
}

//table stuff
- (int)numberOfRowsInTableView:(NSTableView *)aTableView
{
    return [currentBundlesLoadedAtLaunch count];
}

- tableView:(NSTableView *)aTableView
objectValueForTableColumn:(NSTableColumn *)aTableColumn
        row:(int)rowIndex
{
    NSString *identifier = [aTableColumn identifier];

    if ([identifier isEqualToString: @"NAME"]) {
        return [[[currentBundlesLoadedAtLaunch objectAtIndex: rowIndex] lastPathComponent] stringByDeletingPathExtension];
    } else if ([identifier isEqualToString: @"PATH"]) {
        return [currentBundlesLoadedAtLaunch objectAtIndex: rowIndex];
    }

    return nil;
}

- (void) updateRemoveButton
{
    if ( [bundleTable numberOfSelectedRows] == 0 )
        [removeButton setEnabled: NO];
    else
        [removeButton setEnabled: YES];
}

- (void)tableViewSelectionDidChange:(NSNotification *)aNotification
{
    [self updateRemoveButton];
}

// default stuff
- (void) setDefaultObject: anObject forKey: (NSString *) aKey
{
    NSTask *setTask = nil;
    NSString *launchPath = nil;
    NSArray *arguments;

    if ([anObject isKindOfClass: [NSColor class]])
        anObject = [self rgbStringFromColor: anObject];

#ifdef WIN32
    launchPath = [NSString stringWithFormat: @"%@/NextLibrary/Executables/defaults.exe", NSOpenStepRootDirectory()];;
#else MACH
    launchPath = @"/usr/bin/defaults";
#endif
    if ( ([aKey isEqualToString: @"BundlesLoadedAtLaunch"] == YES) && (currentBundlesIsEmpty == YES)) {
        NSTask *bogus;
        // this seems to be necessary...  i don't know why
        bogus = [[NSTask alloc] init];
        [bogus setLaunchPath: launchPath];
        [bogus setArguments: [NSArray arrayWithObjects: @"write", @"ProjectBuilder", @"BundlesLoadedAtLaunch", @"()", nil]];
        [bogus launch];
        [bogus waitUntilExit];
    }

    arguments = [NSArray arrayWithObjects: @"write", @"ProjectBuilder", aKey, [anObject description], nil];

    setTask = [[NSTask alloc] init];
    [setTask setLaunchPath: launchPath];
    [setTask setArguments: arguments];
    [setTask launch];

    [setTask waitUntilExit];
}

// delegate/NIB stuff
- (void) applicationDidFinishLaunching: (NSNotification *) aNotification
{
    [NSBundle loadNibNamed: @"PDHColorEditor" owner: self];
    if (window == nil) {
        NSLog(@"Failed to find 'PDHColorEditor'.");
        exit(1);
    }

    [self synchronizeWithProjectBuilder: nil];
    [self updateRemoveButton];

    [window makeKeyAndOrderFront: self];
}

- (void) setDebugColorWell: anObject
{
    debugColorWell = [anObject retain];

    [debugColorWell setColor: currentPBDebugHighlightColor];
}

- (void)windowWillClose:(NSNotification *)aNotification
{
    if (window == [aNotification object]) {
        [NSApp performSelector: @selector(terminate:)
                    withObject: nil
                    afterDelay: 0.1];
    }
}
@end
