/*
SRAddressBookShelf.m

Author: Makoto Kinoshita

Copyright 2004-2006 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 "SRBrowserControllerProxy.h"

#import "SRAddressBookContextMenu.h"

#import "SRPrefDefaultKeys.h"

#import "SRAddressBookShelf.h"
#import "SRPersonInfo.h"

@interface SRAddressBookShelf (private)
// Address book management
- (void)_updatePersons;

// Appearance
- (void)_updateLowerView;

@end

@implementation SRAddressBookShelf

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

- (id)initWithBundle:(NSBundle*)bundle
{
    self = [super initWithBundle:bundle];
    if (!self) {
        return nil;
    }
    
    return self;
}

- (void)didLoad
{
    // Create buttons
    _contextButton = [[NSClassFromString(@"HMMenuButton") alloc] initWithFrame:NSMakeRect(0, 0, 31, 19)];
    [_contextButton setButtonType:NSMomentaryChangeButton];
    [_contextButton setBezelStyle:NSRegularSquareBezelStyle];
    [_contextButton setBordered:NO];
    [_contextButton setImage:[NSImage imageNamed:@"shelfContext"]];
    [_contextButton setSelectedImage:[NSImage imageNamed:@"shelfPressedBackgroundL"]];
    [_contextButton setFont:[NSFont systemFontOfSize:[NSFont systemFontSize]]];
    [_contextButton setTarget:self];
    [_contextButton setDelegate:self];
    
    // Configure split view
    [_splitView setSplitType:HMSplitWide];
    
    // Prepare persons
    [self _updatePersons];
    
    // Update appearance
    [self _updateLowerView];
}

- (void)dealloc
{
    [_contextButton release], _contextButton = nil;
    
    [super dealloc];
}

//--------------------------------------------------------------//
#pragma mark -- Bar buttons --
//--------------------------------------------------------------//

- (NSArray*)rightBarButtons
{
    return [NSArray arrayWithObjects:_contextButton, nil];
}

//--------------------------------------------------------------//
#pragma mark -- Address book management --
//--------------------------------------------------------------//

- (NSArray*)selectedPersonInfos
{
    // Get selected objects
    return [_personArrayController selectedObjects];
}

- (void)_updatePersons
{
    // Remove old persons
    [_personArrayController removeObjects:[_personArrayController arrangedObjects]];
    
    // Add persons
    NSMutableArray* persons;
    NSEnumerator*   enumerator;
    ABPerson*       person;
    persons = [NSMutableArray array];
    enumerator = [[[ABAddressBook sharedAddressBook] people] objectEnumerator];
    while (person = [enumerator nextObject]) {
        // Create pserson info
        SRPersonInfo*   personInfo;
        personInfo = [[SRPersonInfo alloc] initWithPerson:person];
        [persons addObject:personInfo];
    }
    
    // Set persons
    [_personArrayController addObjects:persons];
}

- (NSMenu*)_contextMenuForView:(id)view 
        event:(NSEvent*)event
{
    NSUserDefaults* defaults;
    defaults = [NSUserDefaults standardUserDefaults];
    
    // Get modifier key flag
    unsigned int    modifierFlags;
    unsigned int    cmdFlag, optionFlag, shiftFlag;
    modifierFlags = [event modifierFlags];
    cmdFlag = modifierFlags & NSCommandKeyMask;
    optionFlag = modifierFlags & NSAlternateKeyMask;
    shiftFlag = modifierFlags & NSShiftKeyMask;
    
    // Create array for tags
    NSMutableArray* tags;
    tags = [NSMutableArray array];
    
    // Select bookmark under the cursor
    NSPoint point;
    int     rowUnderPoint;
    point = [view convertPoint:[event locationInWindow] 
            fromView:nil];
    rowUnderPoint = [view rowAtPoint:point];
    if (rowUnderPoint >=0) {
        if (![[view selectedRowIndexes] containsIndex:rowUnderPoint]) {
            [view selectRowIndexes:[NSIndexSet indexSetWithIndex:rowUnderPoint] 
                    byExtendingSelection:NO];
        }
    }
    
    // Get selected rows
    NSIndexSet* indexSet;
    indexSet = [view selectedRowIndexes];
    
    SRPersonInfo*   personInfo = nil;
    NSArray*        personInfos = nil;
    
    // Just one bookmark is selected
    if ([indexSet count] == 1) {
        // Get bookmark
        personInfo = [[self selectedPersonInfos] objectAtIndex:0];
    }
    else {
        // Get bookmarks
        personInfos = [self selectedPersonInfos];
    }
    
    // Check tab availability
    BOOL    selectNewTabs;
    selectNewTabs = [defaults boolForKey:SRTabSelectNewTabs];
    
    // Case of one person
    if (personInfo && [personInfo urlString]) {
        // Create tag array
        [tags addObject:[NSNumber numberWithInt:SROpenPersonTag]];
        
        if ((selectNewTabs && !shiftFlag) || 
            (!selectNewTabs && shiftFlag))
        {
            [tags addObject:[NSNumber numberWithInt:SROpenPersonInNewWindowTag]];
            [tags addObject:[NSNumber numberWithInt:SROpenPersonInNewTabTag]];
        }
        else {
            [tags addObject:[NSNumber numberWithInt:SROpenPersonInNewBackgroundWindowTag]];
            [tags addObject:[NSNumber numberWithInt:SROpenPersonInNewBackgroundTabTag]];
        }
        [tags addObject:[NSNumber numberWithInt:SROpenPersonInNewWindowTag]];
    }
    // Case of multiple person
    if (personInfos) {
        // Create tag array
        [tags addObject:[NSNumber numberWithInt:SROpenPersonInTabsTag]];
    }
    
    if ([tags count] > 0) {
        // Copy menu
        NSMenu* menu;
        menu = HMCopyMenuWithTags([SRAddressBookContextMenu contextMenu], tags, self);
        
        // Set represented object
        if (personInfo) {
            [[menu itemArray] makeObjectsPerformSelector:@selector(setRepresentedObject:) 
                    withObject:personInfo];
        }
        else {
            [[menu itemArray] makeObjectsPerformSelector:@selector(setRepresentedObject:) 
                    withObject:personInfos];
        }
        
        return menu;
    }
    
    return nil;
}

//--------------------------------------------------------------//
#pragma mark -- Appearance --
//--------------------------------------------------------------//

- (void)_updateLowerView
{
#if 0
    // Get selected persons
    NSArray*        persons;
    SRPersonInfo*   person;
    persons = 
#endif
    
    NSView* subview = nil;
    if ([_personView superview] != _lowerView) {
        subview = _personView;
    }
    if (!subview) {
        return;
    }
    
    [[_lowerView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
    
    NSRect  bounds;
    bounds = [_lowerView bounds];
    [subview setFrame:bounds];
    [_lowerView addSubview:subview];
}

//--------------------------------------------------------------//
#pragma mark -- Action --
//--------------------------------------------------------------//

- (void)openPersonAction:(id)sender
{
    // Get selected person info
    NSArray*        personInfos;
    SRPersonInfo*   personInfo;
    personInfos = [self selectedPersonInfos];
    if (!personInfos || [personInfos count] == 0) {
        return;
    }
    personInfo = [personInfos objectAtIndex:0];
    
    // Get URL string
    NSString*   URLString;
    URLString = [personInfo urlString];
    if (!URLString) {
        return;
    }
    
    // Open URL string
    [[self browserController] openInNewTabURLString:URLString];
}

- (void)openPersonInNewWindowAction:(id)sender
{
    // Get selected person info
    NSArray*        personInfos;
    SRPersonInfo*   personInfo;
    personInfos = [self selectedPersonInfos];
    if (!personInfos || [personInfos count] == 0) {
        return;
    }
    personInfo = [personInfos objectAtIndex:0];
    
    // Get URL string
    NSString*   URLString;
    URLString = [personInfo urlString];
    if (!URLString) {
        return;
    }
    
    // Open URL string
    [[self browserController] openInNewWindowURLString:URLString];
}

- (void)openPersonInNewBackgroundWindowAction:(id)sender
{
    // Get selected person info
    NSArray*        personInfos;
    SRPersonInfo*   personInfo;
    personInfos = [self selectedPersonInfos];
    if (!personInfos || [personInfos count] == 0) {
        return;
    }
    personInfo = [personInfos objectAtIndex:0];
    
    // Get URL string
    NSString*   URLString;
    URLString = [personInfo urlString];
    if (!URLString) {
        return;
    }
    
    // Open URL string
    [[self browserController] openInNewBackgroundWindowURLString:URLString];
}

- (void)openPersonInNewTabAction:(id)sender
{
    // Get selected person info
    NSArray*        personInfos;
    SRPersonInfo*   personInfo;
    personInfos = [self selectedPersonInfos];
    if (!personInfos || [personInfos count] == 0) {
        return;
    }
    personInfo = [personInfos objectAtIndex:0];
    
    // Get URL string
    NSString*   URLString;
    URLString = [personInfo urlString];
    if (!URLString) {
        return;
    }
    
    // Open URL string
    [[self browserController] openInNewTabURLString:URLString];
}

- (void)openPersonInNewBackgroundTabAction:(id)sender
{
    // Get selected person info
    NSArray*        personInfos;
    SRPersonInfo*   personInfo;
    personInfos = [self selectedPersonInfos];
    if (!personInfos || [personInfos count] == 0) {
        return;
    }
    personInfo = [personInfos objectAtIndex:0];
    
    // Get URL string
    NSString*   URLString;
    URLString = [personInfo urlString];
    if (!URLString) {
        return;
    }
    
    // Open URL string
    [[self browserController] openInNewTabURLString:URLString select:NO];
}

- (void)openPersonInTabsAction:(id)sender
{
    // Get selected person info
    NSArray*    personInfos;
    personInfos = [self selectedPersonInfos];
    if (!personInfos || [personInfos count] == 0) {
        return;
    }
    
    // Get URL strings
    NSMutableArray* URLStrings;
    NSEnumerator*   enumerator;
    SRPersonInfo*   personInfo;
    URLStrings = [NSMutableArray array];
    enumerator = [personInfos objectEnumerator];
    while (personInfo = [enumerator nextObject]) {
        NSString*   URLString;
        URLString = [personInfo urlString];
        if (URLString) {
            [URLStrings addObject:URLString];
        }
    }
    
    if ([URLStrings count] == 0) {
        return;
    }
    
    // Open URL strings
    [[self browserController] openInNewTabsURLStrings:URLStrings select:YES];
}

//--------------------------------------------------------------//
#pragma mark -- NSTableViewEx delegate --
//--------------------------------------------------------------//

- (NSMenu*)tableView:(NSOutlineView*)tableView menuForEvent:(NSEvent*)event
{
    return [self _contextMenuForView:tableView event:event];
}

//--------------------------------------------------------------//
#pragma mark -- HMMenuButton delegate --
//--------------------------------------------------------------//

- (NSMenu*)menuButton:(HMMenuButton*)menuButton menuForEvent:(NSEvent*)event
{
    return [self _contextMenuForView:_tableView event:event];
}

@end
