/*
SRSBDownloadController.m

Author: Makoto Kinoshita

Copyright 2004 The Shiira Project. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted 
provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions 
  and the following disclaimer.

  2. Redistributions in binary form must reproduce the above copyright notice, this list of 
  conditions and the following disclaimer in the documentation and/or other materials provided 
  with the distribution.

THIS SOFTWARE IS PROVIDED BY THE SHIIRA PROJECT ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE SHIIRA PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
POSSIBILITY OF SUCH DAMAGE.
*/

#import "SRDefaultsKey.h"

#import "SRMainWindowController.h"
#import "SRDownloadHistory.h"
#import "SRDownloadHistoryItem.h"
#import "SRDownloadViewController.h"
#import "SRSBDownloadController.h"

#import "SRImageTextCell.h"

#import "AppKitEx.h"

static NSString*   _SRDownloadHistoryTabIdentifier = @"history";
static NSString*   _SRDownloadFindResultsTabIdentifier = @"findResult";

@interface SRSBDownloadController (private)
- (void)_updateDownloadHistoryDetailView;
@end

#pragma mark -

@implementation SRSBDownloadController

//--------------------------------------------------------------//
#pragma mark -- Initialize --
//--------------------------------------------------------------//

- (id)initWithMainWindowController:(SRMainWindowController*)mainWindowController 
        sideBarController:(SRSideBarController*)sideBarController;
{
    self = [super init];
    if (!self) {
        return nil;
    }
    
    // Initialize instance variables
    _mainWindowController = mainWindowController;
    _sideBarController = sideBarController;
    
    _isUpperViewSizeInitialized = NO;
    
    return self;
}

static int  _historyTabPaddingTop = -1;
static int  _historyTabPaddingBottom = -1;

- (void)awakeFromNib
{
    NSUserDefaults* defaults;
    defaults = [NSUserDefaults standardUserDefaults];
    
    // Create download view controller
    _downloadViewController = [[SRDownloadViewController alloc] init];
    
    // Adjust view size
    NSView* scrollView;
    NSRect  scrollViewFrame;
    scrollView = [[_downloadViewController downloadTable] scrollView];
    scrollViewFrame = [scrollView frame];
    scrollViewFrame.origin.x = 0;
    scrollViewFrame.size.width -= 4;
    scrollViewFrame.size.height -= 1;
    [scrollView setFrame:scrollViewFrame];
    [_downloadViewController resetPaddings];
    
    // Add to subview
    NSView* downloadView;
    downloadView = [_downloadViewController downloadView];
    [_upperView addSubview:downloadView];
    
    // Coinfgure download history outline
    NSTableColumn*      column;
    NSCell*             oldCell;
    SRImageTextCell*    cell;
    column = [_historyOutline tableColumnWithIdentifier:@"history"];
    oldCell = [column dataCell];
    cell = [[SRImageTextCell alloc] init];
    [cell autorelease];
    [cell setFont:[oldCell font]];
    [column setDataCell:cell];
    
    [_historyOutline setTarget:self];
    [_historyOutline setAction:@selector(downloadHistorySelectedAction:)];
    [_historyOutline setDoubleAction:@selector(openDownloadHistoryItemAction:)];
    
    // Configure history find table
    column = [_historyFindTable tableColumnWithIdentifier:@"results"];
    oldCell = [column dataCell];
    cell = [[SRImageTextCell alloc] init];
    [cell autorelease];
    [cell setFont:[oldCell font]];
    [column setDataCell:cell];
    
    [_historyFindTable setTarget:self];
    [_historyFindTable setAction:@selector(downloadHistorySelectedAction:)];
    [_historyFindTable setDoubleAction:@selector(openDownloadHistoryItemAction:)];
    
    // Select tab item
    [_historyTab selectTabViewItemWithIdentifier:_SRDownloadHistoryTabIdentifier];
    
    // Update download history
    [_historyOutline reloadData];
    [self _updateDownloadHistoryDetailView];
    
    // Get paddings
    if (_historyTabPaddingTop < 0) {
        NSRect  historyTabFrame, lowerFrame;
        historyTabFrame = [_historyTab frame];
        lowerFrame = [_lowerView frame];
        lowerFrame.origin = NSZeroPoint;
        _historyTabPaddingTop = (lowerFrame.origin.y + lowerFrame.size.height) - 
                (historyTabFrame.origin.y + historyTabFrame.size.height);
        _historyTabPaddingBottom = historyTabFrame.origin.y - lowerFrame.origin.y;
    }
    
    // Set frame change notifications
    [_lowerView setPostsFrameChangedNotifications:YES];
    
    // Register notification
    NSNotificationCenter*   center;
    center = [NSNotificationCenter defaultCenter];
    [center addObserver:self 
            selector:@selector(downloadHistoryItemsUpdated:) 
            name:SRDownloadHistoryItemsAddedNotification 
            object:nil];
    [center addObserver:self 
            selector:@selector(downloadHistoryItemsUpdated:) 
            name:SRDownloadHistoryItemsRemovedNotification 
            object:nil];
    [center addObserver:self 
            selector:@selector(lowerViewFrameDidChange:) 
            name:NSViewFrameDidChangeNotification 
            object:_lowerView];
}

- (void)dealloc
{
    // Clear frame change notifications
    [_downloadView setPostsFrameChangedNotifications:NO];
    
    // Release outlets
    [_downloadView release];
    _downloadView = nil;
    
    // Release instance variables
    [_findResults release];
    
    // Remove notification
    NSNotificationCenter*   center;
    center = [NSNotificationCenter defaultCenter];
    [center removeObserver:self];
    
    [super dealloc];
}

//--------------------------------------------------------------//
#pragma mark -- First responder --
//--------------------------------------------------------------//

- (BOOL)acceptsFirstResponder
{
    return YES;
}

//--------------------------------------------------------------//
#pragma mark -- View --
//--------------------------------------------------------------//

- (NSView*)view
{
    return _downloadView;
}

- (void)_updateDownloadHistoryDetailView
{
    // Get selected download history item
    NSArray*    downloadHistoryItems;
    downloadHistoryItems = [self selectedDownloadHistoryItems];
    if (!downloadHistoryItems || [downloadHistoryItems count] == 0) {
        // Reset all
        NSString*   noSelectString;
        noSelectString = NSLocalizedString(@"No selection", nil);
        
        [_historyImage setImage:nil];
        [_historyNameTextField setStringValue:@""];
        [[_historyNameTextField cell] setPlaceholderString:noSelectString];
        [_historyURLTextField setStringValue:@""];
        [[_historyURLTextField cell] setPlaceholderString:noSelectString];
        [_historyRefURLTextField setStringValue:@""];
        [[_historyRefURLTextField cell] setPlaceholderString:noSelectString];
        [_historyRefURLButton setEnabled:NO];
        
        return;
    }
    
    // Multiple selection
    if ([downloadHistoryItems count] > 1) {
        NSString*   multiString;
        multiString = NSLocalizedString(@"Multiple selection", nil);
        
        [_historyImage setImage:nil];
        [_historyNameTextField setStringValue:@""];
        [[_historyNameTextField cell] setPlaceholderString:multiString];
        [_historyURLTextField setStringValue:@""];
        [[_historyURLTextField cell] setPlaceholderString:multiString];
        [_historyRefURLTextField setStringValue:@""];
        [[_historyRefURLTextField cell] setPlaceholderString:multiString];
        [_historyRefURLButton setEnabled:NO];
        
        return;
    }
    
    // Get download history item
    id  downloadHistoryItem;
    downloadHistoryItem = [downloadHistoryItems objectAtIndex:0];
    if (![downloadHistoryItem isKindOfClass:[SRDownloadHistoryItem class]]) {
        return;
    }
    
    // Set download history item property
    NSString*   URLString;
    NSString*   name;
    NSString*   relatedURLString;
    
    [_historyImage setImage:[downloadHistoryItem icon]];
    
    URLString = [downloadHistoryItem URLString];
    name = [URLString lastPathComponent];
    if (name) {
        [_historyNameTextField setStringValue:name];
    }
    else {
        [_historyNameTextField setStringValue:@""];
    }
    
    if (URLString) {
        [_historyURLTextField setStringValue:URLString];
    }
    else {
        [_historyURLTextField setStringValue:@""];
    }
    
    relatedURLString = [downloadHistoryItem relatedURLString];
    if (relatedURLString) {
        [_historyRefURLTextField setStringValue:relatedURLString];
        [_historyRefURLButton setEnabled:YES];
    }
    else {
        [_historyRefURLTextField setStringValue:@""];
        [_historyRefURLButton setEnabled:NO];
    }
}

//--------------------------------------------------------------//
#pragma mark -- Controller --
//--------------------------------------------------------------//

- (SRMainWindowController*)mainWindowController
{
    return _mainWindowController;
}

- (void)setMainWindowController:(SRMainWindowController*)mainWindowController
{
    _mainWindowController = mainWindowController;
}

- (SRSideBarController*)sideBarController
{
    return _sideBarController;
}

- (void)setSidebarController:(SRSideBarController*)sideBarController
{
    _sideBarController = sideBarController;
}

//--------------------------------------------------------------//
#pragma mark -- Download --
//--------------------------------------------------------------//

- (NSArray*)selectedDownloadHistoryItems
{
    // Get tab item identifier
    id  identifier;
    identifier = [[_historyTab selectedTabViewItem] identifier];
    
    // Get selected history
    // For history outlie
    if ([identifier isEqualToString:_SRDownloadHistoryTabIdentifier]) {
        // Get selected rows
        NSIndexSet* indexSet;
        indexSet = [_historyOutline selectedRowIndexes];
        if (!indexSet || [indexSet count] == 0) {
            return nil;
        }
        
        // Get selected rows
        NSMutableArray* historyItems;
        unsigned int    size, count;
        unsigned int*   buffer;
        historyItems = [NSMutableArray array];
        size = [indexSet count];
        buffer = malloc(sizeof(unsigned int) * size);
        count = [indexSet getIndexes:buffer maxCount:size inIndexRange:NULL];
        unsigned int i;
        for (i = 0; i < count; i++) {
            // Get selected history item
            id  selectedObject;
            selectedObject = [_historyOutline itemAtRow:*(buffer + i)];
            
            [historyItems addObject:selectedObject];
        }
        free(buffer);
        
        return historyItems;
    }
    // For find table
    if ([identifier isEqualToString:_SRDownloadFindResultsTabIdentifier]) {
        // Get selected rows
        NSIndexSet* indexSet;
        indexSet = [_historyFindTable selectedRowIndexes];
        if (!indexSet || [indexSet count] == 0) {
            return nil;
        }
        
        // Get selected rows
        NSMutableArray* historyItems;
        unsigned int    size, count;
        unsigned int*   buffer;
        historyItems = [NSMutableArray array];
        size = [indexSet count];
        buffer = malloc(sizeof(unsigned int) * size);
        count = [indexSet getIndexes:buffer maxCount:size inIndexRange:NULL];
        unsigned int i;
        for (i = 0; i < count; i++) {
            // Get selected history item
            id  selectedObject;
            selectedObject = [_findResults objectAtIndex:*(buffer + i)];
            
            if ([selectedObject isKindOfClass:[SRDownloadHistoryItem class]]) {
                [historyItems addObject:selectedObject];
            }
        }
        free(buffer);
        
        return historyItems;
    }
    
    return nil;
}

- (void)selectDownloadHistoryItemAtRow:(int)row
{
    // Select row
    [_historyOutline selectRowIndexes:[NSIndexSet indexSetWithIndex:row] 
            byExtendingSelection:NO];
    
    // Update detail view
    [self _updateDownloadHistoryDetailView];
}

- (void)reloadDownloadHistoryFindTable
{
    // Get find string
    NSString*   findString;
    findString = [_historySearchField stringValue];
    
    // Find history
    NSMutableArray* results;
    results = [NSMutableArray array];
    
    // Get web history and last visited days
    SRDownloadHistory*  history;
    NSArray*            lastVisitedDays;
    history = [SRDownloadHistory sharedInstance];
    lastVisitedDays = [history orderedLastVisitedDays];
    
    // Enumerate calendar date
    NSEnumerator*   enumerator;
    NSCalendarDate* calendarDate;
    enumerator = [lastVisitedDays objectEnumerator];
    while (calendarDate = [enumerator nextObject]) {
        // Get items
        NSArray*    items;
        items = [history orderedItemsLastVisitedOnDay:calendarDate];
        if (!items || [items count] == 0) {
            continue;
        }
        
        // Enumerate history itmes
        NSEnumerator*           itemEnum;
        SRDownloadHistoryItem*  item;
        itemEnum = [items objectEnumerator];
        while (item = [itemEnum nextObject]) {
            // Check file name
            if ([[item fileName] 
                    rangeOfString:findString 
                    options:NSCaseInsensitiveSearch].location != NSNotFound)
            {
                [results addObject:item];
            }
        }
    }
    
    // Reload table
    [_findResults release];
    _findResults = [results retain];
    [_historyFindTable reloadData];
}

//--------------------------------------------------------------//
#pragma mark -- Actions --
//--------------------------------------------------------------//

- (void)downloadHistorySelectedAction:(id)sender
{
    [self _updateDownloadHistoryDetailView];
}

- (void)openDownloadHistoryItemAction:(id)sender
{
    // Get selected download history
    id  downloadHistory;
    downloadHistory = [[self selectedDownloadHistoryItems] objectAtIndex:0];
    
    // For NSCalnderDate
    if ([downloadHistory isKindOfClass:[NSCalendarDate class]]) {
        // Get row
        int row;
        row = [_historyOutline rowForItem:downloadHistory];
        if (row == -1) {
            return;
        }
        
        // Toogle expansion
        if ([_historyOutline isItemExpanded:downloadHistory]) {
            [_historyOutline collapseItem:downloadHistory];
        }
        else {
            [_historyOutline expandItem:downloadHistory];
        }
    }
    // For WebHistory
    if ([downloadHistory isKindOfClass:[SRDownloadHistoryItem class]]) {
        // Open download history
        [_mainWindowController openURLString:[downloadHistory URLString]];
    }
}

- (void)findDownloadHistoryAction:(id)sender
{
    // Get find string
    NSString*   findString;
    findString = [_historySearchField stringValue];
    
    // Switch tab item
    if ([findString length] == 0) {
        [_historyTab selectTabViewItemWithIdentifier:_SRDownloadHistoryTabIdentifier];
        return;
    }
    else {
        [_historyTab selectTabViewItemWithIdentifier:_SRDownloadFindResultsTabIdentifier];
    }
    
    // Reload table
    [self reloadDownloadHistoryFindTable];
}

- (void)goRelatedURLAction:(id)sender
{
    // Get selected ref URL
    NSString*   URLString;
    URLString = [_historyRefURLTextField stringValue];
    if (!URLString || [URLString length] == 0) {
        return;
    }
    
    // Open URL
    [_mainWindowController openURLString:URLString];
}

//--------------------------------------------------------------//
#pragma mark -- NSTableDataSource --
//--------------------------------------------------------------//

- (int)numberOfRowsInTableView:(NSTableView*)tableView
{
    // For find table
    if (tableView == _historyFindTable) {
        return [_findResults count];
    }
    
    return 0;
}

- (id)tableView:(NSTableView*)tableView 
        objectValueForTableColumn:(NSTableColumn*)tableColumn 
        row:(int)rowIndex
{
    // Get identifier
    id  identifier;
    identifier = [tableColumn identifier];
    
    // For find table
    if (tableView == _historyFindTable) {
        if ([identifier isEqualToString:@"results"]) {
            SRDownloadHistoryItem*  historyItem;
            historyItem = [_findResults objectAtIndex:rowIndex];
            return [historyItem fileName];
        }
    }
    
    return nil;
}

//--------------------------------------------------------------//
#pragma mark -- NSTableView delegate --
//--------------------------------------------------------------//

- (void)tableView:(NSTableView*)tableView 
        willDisplayCell:(id)cell 
        forTableColumn:(NSTableColumn*)tableColumn 
        row:(int)rowIndex
{
    NSUserDefaults* defaults;
    defaults = [NSUserDefaults standardUserDefaults];
    
    // Check favicon availability
    BOOL    isFaviconUsed;
    isFaviconUsed = [defaults boolForKey:SRIconUseFavicon];
    
    // Get column identifier
    id  identifier;
    identifier = [tableColumn identifier];
    
    // For find table
    if (tableView == _historyFindTable) {
        // For results column
        if ([identifier isEqualToString:@"results"]) {
            if (isFaviconUsed) {
                // Set image
                [cell setImage:[[_findResults objectAtIndex:rowIndex] icon]];
            }
            else {
                [cell setImage:nil];
            }
            return;
        }
    }
}

- (void)tableViewSelectionDidChange:(NSNotification*)notification
{
    if ([notification object] == _historyFindTable) {
        // Update detail view
        [self _updateDownloadHistoryDetailView];
    }
}

// SRTableView delegate
- (void)tableViewDeleteSelectedItem:(NSTableView*)tableView
{
    // For find table
    if (tableView == _historyFindTable) {
        // Get selected download history items
        NSArray*    downloadHistoryItems;
        downloadHistoryItems = [self selectedDownloadHistoryItems];
        if (!downloadHistoryItems || [downloadHistoryItems count] == 0) {
            return;
        }
        
        // Get fisrt download history item
        SRDownloadHistoryItem*  downloadHistoryItem;
        downloadHistoryItem = [downloadHistoryItems objectAtIndex:0];
        if (!downloadHistoryItem) {
            return;
        }
        
        // Get selected index
        int row;
        row = [[_historyFindTable selectedRowIndexes] firstIndex];
        
        // Delete download history items
        [[SRDownloadHistory sharedInstance] removeItems:downloadHistoryItems];
        
        // Select previous one
        if (row > 0) {
            [_historyFindTable selectRowIndexes:[NSIndexSet indexSetWithIndex:row - 1] 
                    byExtendingSelection:NO];
        }
        
        // Reload table
        [self reloadDownloadHistoryFindTable];
    }
}

//--------------------------------------------------------------//
#pragma mark -- NSOutlineViewDataSource --
//--------------------------------------------------------------//

- (id)outlineView:(NSOutlineView*)outlineView 
        child:(int)index 
        ofItem:(id)item
{
    // Dwonload history outline
    if (outlineView == _historyOutline) {
        // Get download history
        SRDownloadHistory*  history;
        history = [SRDownloadHistory sharedInstance];
        
        // For root
        if (!item) {
            return [[history orderedLastVisitedDays] objectAtIndex:index];
        }
        // For NSCalenderDate
        if ([item isKindOfClass:[NSCalendarDate class]]) {
            NSArray*    items;
            items = [history orderedItemsLastVisitedOnDay:item];
            return [items objectAtIndex:index];
        }
        return nil;
    }
    
    return nil;
}

- (BOOL)outlineView:(NSOutlineView*)outlineView 
        isItemExpandable:(id)item
{
    // Download history outline
    if (outlineView == _historyOutline) {
        // For root
        if (!item) {
            return YES;
        }
        // For NSCalenderDate
        if ([item isKindOfClass:[NSCalendarDate class]]) {
            return YES;
        }
        return NO;
    }
    
    return NO;
}

- (int)outlineView:(NSOutlineView*)outlineView 
        numberOfChildrenOfItem:(id)item
{
    // Download history outline
    if (outlineView == _historyOutline) {
        // Get download history
        SRDownloadHistory*  history;
        history = [SRDownloadHistory sharedInstance];
        
        // For root
        if (!item) {
            return [[history orderedLastVisitedDays] count];
        }
        // For NSCalenderDate
        if ([item isKindOfClass:[NSCalendarDate class]]) {
            NSArray*    items;
            items = [history orderedItemsLastVisitedOnDay:item];
            return [items count];
        }
        return 0;
    }
    
    return 0;
}

- (id)outlineView:(NSOutlineView*)outlineView 
        objectValueForTableColumn:(NSTableColumn*)column 
        byItem:(id)item
{
    // Download history outline
    if (outlineView == _historyOutline) {
        // Get column identifier
        id  identifier;
        identifier = [column identifier];
        
        // For history column
        if ([identifier isEqualToString:@"history"]) {
            if ([item isKindOfClass:[NSCalendarDate class]]) {
                NSDictionary*   locale;
                locale = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation];
                return [item descriptionWithCalendarFormat:NSLocalizedString(@"%a, %B %e", nil) 
                        locale:locale];
            }
            if ([item isKindOfClass:[SRDownloadHistoryItem class]]) {
                return [item fileName];
            }
        }
    }
    
    return nil;
}

// - outlineView:setObjectValue:forTableColumn:byItem:
// - outlineView:acceptDrop:item:childIndex:
// - outlineView:validateDrop:proposedItem:proposedChildIndex:

- (id)outlineView:(NSOutlineView*)outlineView 
        itemForPersistentObject:(id)object
{
    // Download history outline
    if (outlineView == _historyOutline) {
        // Return unarchived history
        return [NSUnarchiver unarchiveObjectWithData:object];
    }
    
    return nil;
}

- (id)outlineView:(NSOutlineView*)outlineView 
        persistentObjectForItem:(id)item
{
    // Download history outline
    if (outlineView == _historyOutline) {
        // Return archived history
        return [NSArchiver archivedDataWithRootObject:item];
    }
    
    return nil;
}

// - outlineView:writeItems:toPasteboard:pboard
// - outlineView:sortDescriptorsDidChange:

//--------------------------------------------------------------//
#pragma mark -- NSOutlineView delegate --
//--------------------------------------------------------------//

- (void)outlineView:(NSOutlineView*)outlineView 
        willDisplayCell:(id)cell 
        forTableColumn:(NSTableColumn*)column 
        item:(id)item
{
    NSUserDefaults* defaults;
    defaults = [NSUserDefaults standardUserDefaults];
    
    // Check favicon availability
    BOOL    isFaviconUsed;
    isFaviconUsed = [defaults boolForKey:SRIconUseFavicon];
    
    // History outline
    if (outlineView == _historyOutline) {
        // Get column identifier
        id  identifier;
        identifier = [column identifier];
        
        // For history column
        if ([identifier isEqualToString:@"history"]) {
            // For NSCaledarDate
            if ([item isKindOfClass:[NSCalendarDate class]]) {
                if (isFaviconUsed) {
                    // Set image
                    [cell setImage:[NSImage imageNamed:@"shiiraFolder"]];
                }
                else {
                    [cell setImage:nil];
                }
                return;
            }
            if ([item isKindOfClass:[SRDownloadHistoryItem class]]) {
                if (isFaviconUsed) {
                    // Set image
                    [cell setImage:[item icon]];
                }
                else {
                    [cell setImage:nil];
                }
                return;
            }
        }
    }
}

- (void)outlineViewSelectionDidChange:(NSNotification*)notification
{
    if ([notification object] == _historyOutline) {
        // Update download history detail view
        [self _updateDownloadHistoryDetailView];
    }
}

// Extention method
//- outlineView:menuForEvent:

// SROutlineView delegate
- (void)outlineViewDeleteSelectedItem:(NSOutlineView*)outlineView
{
    // Get selected download history items
    NSArray*    downloadHistoryItems;
    downloadHistoryItems = [self selectedDownloadHistoryItems];
    if (!downloadHistoryItems || [downloadHistoryItems count] == 0) {
        return;
    }
    
    // Get fisrt download history item
    SRDownloadHistoryItem*  downloadHistoryItem;
    downloadHistoryItem = [downloadHistoryItems objectAtIndex:0];
    if (!downloadHistoryItem) {
        return;
    }
    
    // Get row of first download history item
    int row;
    row = [_historyOutline rowForItem:downloadHistoryItem];
    
    // Delete download history items
    [[SRDownloadHistory sharedInstance] removeItems:downloadHistoryItems];
    
    // Select previous one
    if (row > 0) {
        [self selectDownloadHistoryItemAtRow:row - 1];
    }
}

//--------------------------------------------------------------//
#pragma mark -- NSSplitView delegate --
//--------------------------------------------------------------//

static const int    _upperViewMinHeight = 76;
static const int    _lowerViewMinHeight = 89;

#if 0
- (void)splitView:(NSSplitView*)splitView 
        resizeSubviewsWithOldSize:(NSSize)oldSize
{
    if (!_isUpperViewSizeInitialized) {
        NSUserDefaults* defaults;
        defaults = [NSUserDefaults standardUserDefaults];
        
        // Update upper view size
        if ([defaults objectForKey:SRSideBarDownloadUpperViewHeight]) {
            NSRect  upperFrame;
            float   upperViewHeight;
            upperViewHeight = [defaults floatForKey:SRSideBarDownloadUpperViewHeight];
            upperFrame = [_upperView frame];
            upperFrame.size.height = upperViewHeight;
            [_upperView setFrame:upperFrame];
        }
        
        _isUpperViewSizeInitialized = YES;
        return;
    }
    
    // Use default behaviour
    [splitView adjustSubviews];
}
#endif

// - splitView:resizeSubviewsWithOldSize:
// - splitViewWillResizeSubviews:

#if 0
- (void)splitViewDidResizeSubviews:(NSNotification*)notification
{
    NSUserDefaults* defaults;
    defaults = [NSUserDefaults standardUserDefaults];
    
    // Store upper view size
    NSRect  upperFrame;
    upperFrame = [_upperView frame];
    [defaults setFloat:upperFrame.size.height forKey:SRSideBarDownloadUpperViewHeight];
}
#endif

- (float)splitView:(NSSplitView*)splitView 
        constrainMaxCoordinate:(float)proposedMax 
        ofSubviewAt:(int)offset
{
    return [splitView frame].size.height - _lowerViewMinHeight - [splitView dividerThickness];
}

- (float)splitView:(NSSplitView*)splitView 
        constrainMinCoordinate:(float)proposedMin 
        ofSubviewAt:(int)offset
{
    return _upperViewMinHeight;
}

// - splitView:constrainSplitPosition:ofSubViewAt:

- (BOOL)splitView:(NSSplitView*)splitView 
        canCollapseSubview:(NSView*)subview
{
    return YES;
}

//--------------------------------------------------------------//
#pragma mark -- NSView notification --
//--------------------------------------------------------------//

- (void)lowerViewFrameDidChange:(NSNotification*)notification
{
    // Get history tab frame and check padding
    NSRect  historyTabFrame, lowerFrame;
    int     historyTabPaddingTop, historyTabPaddingBottom;
    historyTabFrame = [_historyTab frame];
    lowerFrame = [_lowerView frame];
    lowerFrame.origin = NSZeroPoint;
    historyTabPaddingTop = (lowerFrame.origin.y + lowerFrame.size.height) - 
            (historyTabFrame.origin.y + historyTabFrame.size.height);
    historyTabPaddingBottom = historyTabFrame.origin.y - lowerFrame.origin.y;
    
    if (historyTabPaddingTop != _historyTabPaddingTop || 
        historyTabPaddingBottom != _historyTabPaddingBottom)
    {
        // Reset padding
        NSRect  newFrame;
        newFrame.origin.x = historyTabFrame.origin.x;
        newFrame.origin.y = lowerFrame.origin.y + _historyTabPaddingBottom;
        newFrame.size.width = historyTabFrame.size.width;
        newFrame.size.height = lowerFrame.size.height - _historyTabPaddingBottom - _historyTabPaddingTop;
        
        if (newFrame.origin.y > 0 && newFrame.size.height > 0) {
            [_historyTab setFrame:newFrame];
        }
    }
}

//--------------------------------------------------------------//
#pragma mark -- SRDownloadHistory notification --
//--------------------------------------------------------------//

- (void)downloadHistoryItemsUpdated:(NSNotification*)notification
{
    // Reload data
    [_historyOutline reloadData];
}

@end
