//
//  PithosPreferencesController.m
//  pithos-macos
//
// Copyright 2011-2012 GRNET S.A. 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 GRNET S.A. ``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 GRNET S.A 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.
// 
// The views and conclusions contained in the software and
// documentation are those of the authors and should not be
// interpreted as representing official policies, either expressed
// or implied, of GRNET S.A.

#import "PithosPreferencesController.h"
#import "PithosBrowserController.h"
#import "PithosAccountNode.h"
#import "PithosAccount.h"
#import "pithos_macosAppDelegate.h"

@implementation PithosPreferencesController
@synthesize pithosBrowserController, selectedPithosAccount;
@synthesize accountsArrayController;
@synthesize accountRemoveEnable;
@synthesize serverURL, authUser, authToken, manual, loginEnable, loginCancelEnable;
@synthesize groupsDictionaryController, selectedGroupMembersDictionaryController;
@synthesize syncActive, syncDirectoryPath, syncApplyEnable, syncCancelEnable;

#pragma mark -
#pragma mark Object Lifecycle

- (id)init {
    return [super initWithWindowNibName:@"PithosPreferencesController"];
}

- (void)windowDidLoad {
    [super windowDidLoad];
    
    NSWindow *window = [self window];
    [window setHidesOnDeactivate:NO];
    [window setExcludedFromWindowsMenu:YES];
    
//	// Select the first tab when the window is loaded for the first time.
//	[[window valueForKeyPath:@"toolbar"] setSelectedItemIdentifier:@"0"];

    [groupsDictionaryController setInitialKey:@"group"];
    [groupsDictionaryController setInitialValue:@"user"];
    [selectedGroupMembersDictionaryController setInitialKey:@"user"];
    [selectedGroupMembersDictionaryController setInitialValue:@""];

    [window setDelegate:self];
    
    self.selectedPithosAccount = [[accountsArrayController selectedObjects] objectAtIndex:0];
    [accountsArrayController addObserver:self forKeyPath:@"selection" options:NSKeyValueObservingOptionNew context:NULL];
}

- (BOOL)windowShouldClose:(id)sender {
    return [(pithos_macosAppDelegate *)[[NSApplication sharedApplication] delegate] activated];
}

//- (void)windowWillClose:(NSNotification *)notification {
//}

//- (IBAction)toolbarItemSelected:(id)sender {
//}

#pragma mark -
#pragma Observers

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if ([object isEqualTo:accountsArrayController] && 
        [keyPath isEqualToString:@"selection"] && 
        [[accountsArrayController selectedObjects] count]) {
        self.selectedPithosAccount = [[accountsArrayController selectedObjects] objectAtIndex:0];
    }
}

#pragma mark -
#pragma Update

- (void)updateAccounts {
    pithos_macosAppDelegate *delegate = (pithos_macosAppDelegate *)[[NSApplication sharedApplication] delegate];
    self.accountRemoveEnable = (delegate.activated && ([delegate.pithosAccounts count] > 1));
}

- (void)updateLogin {
    self.loginEnable = ([selectedPithosAccount urlIsValid:serverURL] && (!manual || ([authUser length] && [authToken length])));
    self.loginCancelEnable = (![selectedPithosAccount.serverURL isEqualToString:serverURL] || 
                              (selectedPithosAccount.authUser && ![selectedPithosAccount.authUser isEqualToString:authUser]) || 
                              (selectedPithosAccount.authToken && ![selectedPithosAccount.authToken isEqualToString:authToken]));
}

- (void)updateSync {
    BOOL isDirectory;
    self.syncApplyEnable = (selectedPithosAccount.active && 
                            ((selectedPithosAccount.syncActive != syncActive) || 
                             (![selectedPithosAccount.syncDirectoryPath isEqualToString:syncDirectoryPath] && 
                              (![[NSFileManager defaultManager] fileExistsAtPath:syncDirectoryPath isDirectory:&isDirectory] || 
                               isDirectory))));
    self.syncCancelEnable = (selectedPithosAccount.active && 
                             ((selectedPithosAccount.syncActive != syncActive) || 
                              ![selectedPithosAccount.syncDirectoryPath isEqualToString:syncDirectoryPath]));
}

#pragma mark -
#pragma Properties

- (void)setSelectedPithosAccount:(PithosAccount *)aSelectedPithosAccount {
    if (aSelectedPithosAccount && ![aSelectedPithosAccount isEqualTo:selectedPithosAccount]) {
        [selectedPithosAccount release];
        selectedPithosAccount = [aSelectedPithosAccount retain];
        
        [self updateAccounts];
        [self loginCancel:self];
        [self syncCancel:self];
        [self groupsRevert:self];
    }
}

#pragma Login Properties

- (void)setServerURL:(NSString *)aServerURL {
    [serverURL release];
    serverURL = [aServerURL copy];
    [self updateLogin];
}

- (void)setAuthUser:(NSString *)anAuthUser {
    [authUser release];
    authUser = [anAuthUser copy];
    [self updateLogin];
}

- (void)setAuthToken:(NSString *)anAuthToken {
    [authToken release];
    authToken = [anAuthToken copy];
    [self updateLogin];
}

- (void)setManual:(BOOL)aManual {
    manual = aManual;
    [self updateLogin];
    if (!manual) {
        self.authUser = [[selectedPithosAccount.authUser copy] autorelease];
        self.authToken = [[selectedPithosAccount.authToken copy] autorelease];
    }
}

#pragma Sync Properties

- (void)setSyncActive:(BOOL)aSyncActive {
    syncActive = aSyncActive;
    [self updateSync];
}

- (void)setSyncDirectoryPath:(NSString *)aSyncDirectoryPath {
    [syncDirectoryPath release];
    syncDirectoryPath = [aSyncDirectoryPath copy];
    [self updateSync];
}

#pragma mark -
#pragma Actions

- (IBAction)addAccount:(id)sender {
    [accountsArrayController addObject:[PithosAccount pithosAccount]];
    [self updateAccounts];
    pithos_macosAppDelegate *delegate = (pithos_macosAppDelegate *)[[NSApplication sharedApplication] delegate];
    [delegate.pithosAccountsDictionary setObject:selectedPithosAccount forKey:selectedPithosAccount.name];
    [delegate savePithosAccounts:self];
}

- (IBAction)removeAccount:(id)sender {
    [self updateAccounts];
    if (!accountRemoveEnable)
        return;
    PithosAccount *removedPithosAccount = [selectedPithosAccount retain];
    pithos_macosAppDelegate *delegate = (pithos_macosAppDelegate *)[[NSApplication sharedApplication] delegate];
    if ([delegate.currentPithosAccount isEqualTo:removedPithosAccount] && [delegate.pithosBrowserController operationsPending]) {
        NSAlert *alert = [[[NSAlert alloc] init] autorelease];
        [alert setMessageText:@"Operations Pending"];
        [alert setInformativeText:@"There are pending operations in the browser, do you want to remove the account and cancel them?"];
        [alert addButtonWithTitle:@"OK"];
        [alert addButtonWithTitle:@"Cancel"];
        NSInteger choice = [alert runModal];
        if (choice == NSAlertSecondButtonReturn) {
            [removedPithosAccount release];
            return;
        }
    }
    [accountsArrayController removeObject:selectedPithosAccount];
    [delegate.pithosAccountsDictionary removeObjectForKey:removedPithosAccount.name];
    [delegate removedPithosAccount:removedPithosAccount];
    [delegate savePithosAccounts:self];
    [removedPithosAccount release];
    [self updateAccounts];
}

#pragma Login Actions

- (IBAction)login:(id)sender {
    if (!manual) {
        [selectedPithosAccount loginWithServerURL:serverURL];
    } else {
        [selectedPithosAccount authenticateWithServerURL:serverURL authUser:authUser authToken:authToken];
        self.manual = NO;
        pithos_macosAppDelegate *delegate = (pithos_macosAppDelegate *)[[NSApplication sharedApplication] delegate];
        [delegate savePithosAccounts:self];
        if (!delegate.activated) {
            delegate.activated = YES;
            [delegate showPithosBrowser:self];
        }
        if ([selectedPithosAccount isEqualTo:delegate.currentPithosAccount])
            delegate.pithosBrowserController.pithos = selectedPithosAccount.pithos;
    }
}

- (IBAction)loginCancel:(id)server {
    self.serverURL = [[selectedPithosAccount.serverURL copy] autorelease];
    self.authUser = [[selectedPithosAccount.authUser copy] autorelease];
    self.authToken = [[selectedPithosAccount.authToken copy] autorelease];
}

#pragma Sync Actions

- (IBAction)syncApply:(id)sender {
    [selectedPithosAccount updateSyncWithSyncActive:syncActive syncDirectoryPath:syncDirectoryPath];
    [self updateSync];
    pithos_macosAppDelegate *delegate = (pithos_macosAppDelegate *)[[NSApplication sharedApplication] delegate];
    [delegate savePithosAccounts:self];
}

- (IBAction)syncCancel:(id)sender {
    self.syncActive = selectedPithosAccount.syncActive;
    self.syncDirectoryPath = [[selectedPithosAccount.syncDirectoryPath copy] autorelease];
}

#pragma mark Groups Actions

- (IBAction)groupsApply:(id)sender {
    [[self window] makeFirstResponder:nil];
    if (selectedPithosAccount.active)
        [selectedPithosAccount.accountNode applyInfo];
}

- (IBAction)groupsRevert:(id)sender {
    if (selectedPithosAccount.active && selectedPithosAccount.accountNode)
        [selectedPithosAccount.accountNode refreshInfo];
}

@end
