#import "AqBrowserView.h"
#import "AqDrawerController.h"
#import "AqQueryDataSource.h"
#import "DWTableScrollView.h"
#import "NSObjectExtensions.h"


@implementation NSSplitView (DocumentView)

    - (id) documentView; {
        return [[[self subviews] objectAtIndex: 1] documentView];
    }

@end


@implementation AqBrowserView

/* Drawing */

    - (id) initWithFrame: (NSRect) theFrame; 
    {
        self = [super initWithFrame: theFrame];
        
        int i;
        for (i=0; i<3; i++)
        {
            /* setup */
            
                id tableView;
                id scrollView;
                id tableColumn;
    
                tableColumn = [[NSTableColumn alloc] initWithIdentifier: @""];
                    [tableColumn setEditable: NO];
                
                tableView = [[AqMetaTableView alloc] init];
                    [tableView addTableColumn: tableColumn];
                    [tableView setAllowsColumnReordering: NO];
                    [tableView setBrowserView: self];
                
                scrollView = [[DWTableScrollView alloc] initWithFrame: theFrame];
                    [scrollView setHasVerticalScroller: YES];
                    [[scrollView verticalScroller] setControlSize: NSSmallControlSize];
                    [scrollView setDocumentView: tableView];
                            
                [self addSubview: scrollView];
    
                views[i] = scrollView;
                metaviews[i] = tableView;
            
            /* notifications */

                [self listenForNotification: NSTableViewSelectionDidChangeNotification selector: @selector(selectionIsChanging:) object: tableView];
                [self listenForNotification: NSTableViewSelectionIsChangingNotification selector: @selector(selectionIsChanging:) object: tableView];
        
            /* optimize */

                [scrollView setPostsFrameChangedNotifications: NO];
                [scrollView setPostsBoundsChangedNotifications: NO];
    
                [[scrollView verticalScroller] setPostsFrameChangedNotifications: NO];
                [[scrollView verticalScroller] setPostsBoundsChangedNotifications: NO];
    
                [[scrollView horizontalScroller] setPostsFrameChangedNotifications: NO];
                [[scrollView horizontalScroller] setPostsBoundsChangedNotifications: NO];
        }

        [self setPostsFrameChangedNotifications: NO];
        [self setPostsBoundsChangedNotifications: NO];
    
        return self;
    }

    - (void) dealloc; {
        [self stopListening];
        int i;
        for (i=0; i<3; i++) {
            [views[i] release];
            [metaviews[i] release];
        }
        [super dealloc];
    }
    

#pragma mark -
    
    - (BOOL) isOpaque; {
        return YES;
    }

    - (void) drawRect: (NSRect) theRect; {
        [[DWColor grayColor80] set];
        NSRectFill(theRect);
    }
    
    - (void) resizeSubviewsWithOldSize: (NSSize) oldBoundsSize;
    {
        NSRect frame = [self frame];
        NSRect f1, f2, f3;
        
        int width = frame.size.width / 3;
        int mod = (int)frame.size.width % 3;
        
        f1.origin.y = f2.origin.y = f3.origin.y = frame.origin.y;
        f1.size.height = f2.size.height = f3.size.height = frame.size.height;
    
        f1.origin.x = frame.origin.x;
        f1.size.width = width + ((mod > 0) ? 1 : 0);
        
        f2.origin.x = f1.origin.x + f1.size.width;
        f2.size.width = width + ((mod > 1) ? 1 : 0);
        
        f3.origin.x = f2.origin.x + f2.size.width;
        f3.size.width = width;
        
        f1.size.width--;
        f2.size.width--;
        
        [views[0] setFrame: f1];
        [views[1] setFrame: f2];
        [views[2] setFrame: f3];
    }

    - (void) setDataSource: (id) theDataSource; {
        dataSource = theDataSource;
    }


#pragma mark -

    - (void) updateTables; {
        [metaviews[1] setRootNode: [metaviews[0] selectedNode]];
        [metaviews[2] setRootNode: [metaviews[1] selectedNode]];
        [metaviews[1] noteNumberOfRowsChanged];
        [metaviews[2] noteNumberOfRowsChanged];
    }

    - (void) selectionIsChanging: (id) notification; {
        [self setRootNode: [metaviews[0] selectedNode] inColumn: 1];
        [self setRootNode: [metaviews[1] selectedNode] inColumn: 2];
        [metaviews[1] noteNumberOfRowsChanged];
        [metaviews[2] noteNumberOfRowsChanged];

        id selectedNode = nil;
        if (!selectedNode) selectedNode = [metaviews[2] selectedNode];
        if (!selectedNode) selectedNode = [metaviews[1] selectedNode];
        if (!selectedNode) selectedNode = [metaviews[0] selectedNode];

        [dataSource setCurrentNode: selectedNode];
    }
    
    - (void) setRootNode: (AqMetaNode*) theNode inColumn: (int) theColumn; {
        if ([metaviews[theColumn] rootNode] != theNode) {
            [metaviews[theColumn] setRootNode: theNode];
            [metaviews[theColumn] selectRow: 0 byExtendingSelection: NO];
        }
    }
    

#pragma mark -

    - (void) leftKeyPressed: (id) sender; {
        if (sender == metaviews[0]) [[self window] makeFirstResponder: metaviews[2]];
        if (sender == metaviews[1]) [[self window] makeFirstResponder: metaviews[0]];
        if (sender == metaviews[2]) [[self window] makeFirstResponder: metaviews[1]];
    }

    - (void) rightKeyPressed: (id) sender; {
        if (sender == metaviews[0]) [[self window] makeFirstResponder: metaviews[1]];
        if (sender == metaviews[1]) [[self window] makeFirstResponder: metaviews[2]];
        if (sender == metaviews[2]) [[self window] makeFirstResponder: metaviews[0]];
    }

    - (NSView*) nextValidKeyView: (id) sender; {
        if (sender == metaviews[0]) return metaviews[1];
        if (sender == metaviews[1]) return metaviews[2];
        if (sender == metaviews[2]) return [[[self superview] subviews] objectAtIndex: 1];
        return nil;
    }

    - (NSView*) previousValidKeyView: (id) sender; {
        if (sender == metaviews[0]) return [AqDrawerController instance]->queryView;
        if (sender == metaviews[1]) return metaviews[0];
        if (sender == metaviews[2]) return metaviews[1];
        return nil;
    }

    - (id) firstView; {
        return metaviews[0];
    }
    
    - (id) lastView; {
        return metaviews[2];
    }

@end