/*
        Copyright (c) 1996, NeXT Software, Inc.
        All rights reserved.

        You may freely copy, distribute and reuse the code in this example.
        NeXT disclaims any warranty of any kind, expressed or implied,
        as to its fitness for any particular use.
*/
#import <EOInterface/EOInterface.h>
#import <EOExtensions/EOBrowserAssociation.h>

#define NOF_SUPPORTED_LEVELS   8
#define SUPPRESS_AUTOSELECTION YES

static NSString *EOName1 	    = @"key1";
static NSString *EOName2 	    = @"key2";
static NSString *EOName3 	    = @"key3";
static NSString *EOName4 	    = @"key4";
static NSString *EOName5 	    = @"key5";
static NSString *EOName6 	    = @"key6";
static NSString *EOName7 	    = @"key7";
static NSString *EOName8 	    = @"key8";
static NSString *EOEnabledAspect    = @"enabled";

@implementation EOBrowserAssociation

+ (NSString *)displayName {
    return @"EOBrowserAssoc";
}

+ (BOOL)isUsableWithObject:(id)object
{
    return [object isKindOfClass:[NSBrowser class]];
}

+ (NSArray *)aspects
{
    static NSArray *array = nil;

    if (!array)
        array = [[NSArray alloc] initWithObjects:EOName1, EOName2, EOName3, EOName4, EOName5, EOName6, EOName7, EOName8, EOEnabledAspect, nil];

    return array;
}

+ (NSArray *)aspectSignatures
{
    static NSArray *array = nil;
    if (!array)
        array = [[NSArray alloc] initWithObjects:@"A", @"A", @"A", @"A", @"A", @"A", @"A", @"A", @"A", nil];
    return array;
}

+ (NSString *)primaryAspect {
    return EOName1;
}

+ (NSArray *)objectKeysTaken {
    static NSArray *array = nil;

    if (!array)
        array = [[NSArray alloc] initWithObjects:@"target", nil];

    return array;
}

+ (NSArray *)associationClassesSuperseded
{
    return [NSArray arrayWithObject:[EOControlAssociation class]];
}

- (NSString *)nameOfAspectForColumn:(int)column
{
    if (column >= NOF_SUPPORTED_LEVELS)
        return nil;

    return [NSString stringWithFormat:@"key%d", column+1];
}

- (EODisplayGroup *)displayGroupForColumn:(int)column
{
    NSString *aspectName = [self nameOfAspectForColumn:column];

    if (column >= NOF_SUPPORTED_LEVELS)
        return nil;

    return [self displayGroupForAspect:aspectName];
}

- (BOOL)suppressAutoSelection
{
    return flags.suppressAutoSelection;
}

- (void)setSuppressAutoSelection:(BOOL)flag
{
    flags.suppressAutoSelection = flag;

    if (flag) {
        EODisplayGroup *displayGroup;
        int 	       column = 0;

        while (displayGroup = [self displayGroupForColumn:column]) {
            [displayGroup setSelectsFirstObjectAfterFetch:NO];
            column++;
        }
    }   
}

- initWithObject:object			
    // this is the designated initializer 
{
    [super initWithObject:object];
    flags.suppressAutoSelection = SUPPRESS_AUTOSELECTION;

    return self;
}

- (void)establishConnection
{
    NSBrowser *browser = [self object];

    [super establishConnection];

    [browser setTarget:self];
    [browser setAction:@selector(controlActed:)];
    [browser setDelegate:self];
    [browser setTitle:@"" ofColumn:0];
    
    // we don't have archiving
    [self setSuppressAutoSelection:[self suppressAutoSelection]];
}

- (int)browser:(NSBrowser *)sender numberOfRowsInColumn:(int)column
{
    EODisplayGroup *displayGroup  = [self displayGroupForColumn:column];

    if (displayGroup)
        return [[displayGroup displayedObjects] count];
    else
        return 0;
}

- (void)browser:(NSBrowser *)sender willDisplayCell:(id)cell atRow:(int)row column:(int)column
{
    NSString 		*nameOfAspect = [self nameOfAspectForColumn:column];
    NSString		*detailKey = @"";
    EODetailDataSource  *detailDataSource;
    NSArray             *objectList =  [[self displayGroupForColumn:column] displayedObjects];

    if ([[[self displayGroupForColumn:column+1] dataSource] isKindOfClass:[EODetailDataSource class]]) {
        detailDataSource = (EODetailDataSource *)[[self displayGroupForColumn:column+1] dataSource];
        detailKey = [detailDataSource detailKey];
    }

    [cell setStringValue:[self valueForAspect:nameOfAspect atIndex:row]];
    if ([detailKey isEqual:@""])
        [cell setLeaf:YES];
    else {
        id valueForDetailKey = [[objectList objectAtIndex:row] valueForKey:detailKey];

        if ([valueForDetailKey isKindOfClass:[NSArray class]]) {
            if ([[[objectList objectAtIndex:row] valueForKey:detailKey] count] > 0)
                [cell setLeaf:NO];
            else
                [cell setLeaf:YES];
        } else if (valueForDetailKey)
            [cell setLeaf:NO];
    }
}

- (NSString *)pathOfDisplayGroupSelection
{
    NSMutableString 	*path = [NSMutableString stringWithString:@""];
    EODisplayGroup 	*displayGroup;
    int 		column = 0;

    while (displayGroup = [self displayGroupForColumn:column]) {
        if ([[displayGroup displayedObjects] count]) {
            NSString *part = [self valueForAspect:[self nameOfAspectForColumn:column]];

            if ([part length] > 0) {
                [path appendFormat:@"/%@", part];
            }
        } else {
            column = NOF_SUPPORTED_LEVELS;
        }
        column++;
    }
    if ([path length] == 0) 
        [path appendString:@"/"];

    return path;
}

- (void)controlActed:(id)sender
{
    EODisplayGroup *affectedDisplayGroup  = [self displayGroupForColumn:[sender selectedColumn]];
    EODisplayGroup *displayGroup;
    NSNumber       *number = [NSNumber numberWithInt:[sender selectedRowInColumn:[sender selectedColumn]]];
    int 	   column = [sender selectedColumn]+1;

    [affectedDisplayGroup setSelectionIndexes:[NSArray arrayWithObject:number]];
    while (displayGroup = [self displayGroupForColumn:column]) {
        [displayGroup clearSelection];
        column++;
    }
}

- (void)subjectChanged // change in the displaygroups so update browser
{
    BOOL      enabled = NO;
    NSBrowser *browser = [self object];
    NSString  *path;
    
    if (![browser isKindOfClass:[NSBrowser class]])
        return;
    path = [self pathOfDisplayGroupSelection];

    [browser loadColumnZero];
    if ([path length] > 0)
        [browser setPath:path];
    
    // enabling/disabling
    if (![path isEqual:@""]) { // do we have something to show?
        id enabledVal = [self valueForAspect:EOEnabledAspect];

        enabled = (!enabledVal || ([enabledVal intValue] != 0));
    }
    if (enabled != [browser isEnabled])
        [browser setEnabled:enabled];
}

@end
