//
//  OxArrayControllerAddOn.h
//
//  Copyright 2008 Nicholas Matsakis. 
//  The code in thie file is released to the public under the
//  terms of the MIT License as described here:
//  http://www.opensource.org/licenses/mit-license.php
//


#import "OxArrayControllerAddOn.h"


@implementation OxArrayControllerAddOn

- (void) awakeFromNib
{
    [m_controller addObserver:self
                   forKeyPath:@"arrangedObjects"
                      options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew
                      context:NULL];
}

- (void) selectAndEdit:(NSIndexSet*)inserted
{
    int firstIndex = [inserted firstIndex];
    [m_controller setSelectionIndexes:inserted];
    [m_table scrollRowToVisible:firstIndex];
    [m_table editColumn:0 
                    row:firstIndex
              withEvent:nil 
                 select:YES];    
}

- (void) observeValueForKeyPath:(NSString *)keyPath 
                       ofObject:(id)object 
                         change:(NSDictionary *)change
                        context:(void *)context
{
    id changeKind = [change objectForKey:NSKeyValueChangeKindKey];
    NSInteger changeKindInt = [changeKind intValue];
    int arrangedObjectsCount = [[m_controller arrangedObjects] count];
    if (m_addFlag) {
        NSIndexSet *inserted = nil;
        if (changeKindInt == NSKeyValueChangeInsertion)
            inserted = [change objectForKey:NSKeyValueChangeIndexesKey];
        else if (changeKindInt == NSKeyValueChangeSetting)
            // annoyingly, NSArrayController doens't provide good "metadata"
            // about its changes, so we have to add this hack:
            if (m_oldCount == arrangedObjectsCount - 1)
                // assume that the new one is the last one!
                inserted = [NSIndexSet indexSetWithIndex:arrangedObjectsCount-1];
        
        // we insert this into the run loop to run as late as possible: this
        // gives time for all other changes to propagate, the table to update
        // its number of rows, etc.  Otherwise it doesn't seem to work, my theory
        // is because we are asking the table to select rows it doesn't know about
        // yet.
        if (inserted != nil) {
            NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
            [runLoop performSelector:@selector(selectAndEdit:)
                              target:self
                            argument:inserted
                               order:INT_MAX
                               modes:[NSArray arrayWithObject:NSDefaultRunLoopMode]];
        }
        
        m_addFlag = NO;
    }
                
    m_oldCount = arrangedObjectsCount;
}

- (IBAction) add:(id)sender {
    [self awaitAdd];
    [m_controller add:sender];
}

- (void) awaitAdd {
    m_addFlag = YES;
}

@end
