/*
        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 "InventoryEntry.h"
#import <EOInterface/EOInterface.h>
#import <EOControl/EOControl.h>
#import <BusinessLogic/BusinessLogic.h>

@implementation InventoryEntry

// This method is called when the window change size.
- (void)_winResize:(NSNotification *)notification
{
    NSRect frame;

    frame = [currentView frame];

    [gamePlayerView setFrame:frame];
    [gameMediaView setFrame:frame];
    [movieMediaView setFrame:frame];
}

- (void)awakeFromNib
{

    // Remove the datasource on the details controllers
    // It will be replaced by a detailDatasource when
    // we connect the association
    //
    [gamePlayerController setDataSource:nil];
    [gameMediaController setDataSource:nil];
    [movieMediaController setDataSource:nil];

    // Reset all the view positions
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_winResize:) name: NSWindowDidResizeNotification object:[currentView window]];

    // sort all this stuff
    [productController setSortOrdering:[NSArray arrayWithObjects:[EOSortOrdering sortOrderingWithKey:@"name" selector:EOCompareAscending], nil]];
    [movieController setSortOrdering:[NSArray arrayWithObjects:[EOSortOrdering sortOrderingWithKey:@"title" selector:EOCompareAscending], nil]];
}

- (void)dealloc
{
    [gamePlayerView release];
    [gameMediaView release];
    [movieMediaView release];
    [currentAssociation release];
    [super dealloc];
}

- (void)_swapToController:(EODisplayGroup *)aController view:(NSView *)aView firstKey:(NSView *)o
{

    if (!didInitViews) {
        // Setup
        [self _winResize:nil];
        superView = [currentView superview];
        currentView = nil;

        // Retain the views
        [gamePlayerView retain];
        [gameMediaView retain];
        [movieMediaView retain];

        // Remove those from their current superview
        [gamePlayerView removeFromSuperview];
        [gameMediaView removeFromSuperview];
        [movieMediaView removeFromSuperview];
        didInitViews = YES;
    }

    // Swap the views
    if(aView != currentView) {
        [currentView removeFromSuperview];
        currentView = aView;
        if(aView) {
            [superView addSubview:aView];
        }
    }

    // Swap the controllers
    if(aController != currentController) {
        // clear currentController
        [currentController setDataSource:nil];
        
        currentController = aController;
        [currentAssociation breakConnection];
        [currentAssociation release];

        if(aController) {
            currentAssociation = [[EOMasterDetailAssociation alloc] initWithObject:aController];
            [currentAssociation bindAspect:@"parent" displayGroup:productController key:@"self"];
            [currentAssociation establishConnection];
        }
    }

    // Set the nextKey
    [attachKeyFrom setNextKeyView:o];
    
}

static BOOL needResort = YES;

// EOController delegate
- (BOOL)displayGroup:(EODisplayGroup *)displayGroup shouldChangeSelectionToIndexes:(NSArray *)newIndexes;
{
    NSArray *allObj;
    NSNumber *newIndex;
    id newObj;
    
    if(displayGroup != productController)
        return YES;

    if(needResort) {
        [displayGroup updateDisplayedObjects];
        needResort = NO;
    }
    
    if(newIndexes && [newIndexes count]) {
        newIndex = [newIndexes objectAtIndex:0];
    } else {
        return YES;
    }
    allObj = [displayGroup displayedObjects];
    newObj = [allObj objectAtIndex:[newIndex intValue]];
    
    if([newObj isKindOfClass:[GamePlayer class]]) {
        [self _swapToController:gamePlayerController view:gamePlayerView firstKey:gamePlayerFirstKey];
    } else if([newObj isKindOfClass:[GameMedia class]]) {
        [self _swapToController:gameMediaController view:gameMediaView firstKey:gameMediaFirstKey];
    } else if([newObj isKindOfClass:[MovieMedia class]]) {
        [self _swapToController:movieMediaController view:movieMediaView firstKey:movieMediaFirstKey];
    } else {
        [NSException raise:NSInvalidArgumentException format:@"*** Unknown class !"];
    }
    return YES;
}

// Target/action
- (unsigned)_newIndex
{
    NSArray * selection = [productController selectionIndexes];

    if (![selection count])
        return 0;

    return [[selection objectAtIndex:0] unsignedIntValue] + 1;
}


- (void)insertVideoTape:sender
{
    id new = [[VideoTape new] autorelease];

    [[[productController dataSource] editingContext] insertObject:new];
    [productController insertObject:new atIndex:[self _newIndex]];
    needResort = YES;
}

- (void)insertVideoDisc:sender
{
    id new = [[LaserDisc new] autorelease];

    [[[productController dataSource] editingContext] insertObject:new];
    [productController insertObject:new atIndex:[self _newIndex]];
    needResort = YES;
}

- (void)insertGamePlayer:sender
{
    id new = [[GamePlayer new] autorelease];

    [[[productController dataSource] editingContext] insertObject:new];
    [productController insertObject:new atIndex:[self _newIndex]];
    needResort = YES;
}

- (void)insertGameMedia:sender
{
    id new = [[GameMedia new] autorelease];

    [[[productController dataSource] editingContext] insertObject:new];
    [productController insertObject:new atIndex:[self _newIndex]];
    needResort = YES;
}

@end


// The application menu items are wired up directly to the EditingContext
// so we can handle enabling and disabling by implementing
// validateMenuItem:.
// For multi-document apps this scheme is not appropriate.  In that case,
// the menu items would be wired up to the application object which in turn
// would implement validateMenuItem: to check the editing context of the 
// foreground document.
@implementation EOEditingContext(menuUpdate)

- (BOOL)validateMenuItem:(NSMenuItem *)menuItem
{
    SEL action = [menuItem action];

    if(action == @selector(saveChanges:))
        return [self hasChanges];
    else if(action == @selector(undo:))
        return [[self undoManager] canUndo];
    else if(action == @selector(redo:))
        return [[self undoManager] canRedo];
    else if(action == @selector(revert:))
        return [self hasChanges];
    else if(action == @selector(refetch:))
        return YES;
    else
        return YES;
}

@end


