//
//  MPDocumentSettingsWindowController.m
//  MacPass
//
//  Created by Michael Starke on 26.06.13.
//  Copyright (c) 2013 HicknHack Software GmbH. All rights reserved.
//

#import "MPDatabaseSettingsWindowController.h"
#import "MPDocument.h"
#import "MPDocumentWindowController.h"
#import "MPDatabaseVersion.h"
#import "MPIconHelper.h"
#import "MPSettingsHelper.h"
#import "MPNumericalInputFormatter.h"

#import "KPKXmlFormat.h"
#import "KPKGroup.h"
#import "KPKTree.h"
#import "KPKMetaData.h"
#import "KPKNode+IconImage.h"
#import "KPKCompositeKey.h"

#import "HNHRoundedTextField.h"
#import "HNHRoundedSecureTextField.h"

#import "NSString+Empty.h"


@interface MPDatabaseSettingsWindowController () {
  MPDocument *_document;
  NSString *_missingFeature;
}
@property (nonatomic,assign) BOOL trashEnabled;

@end

@implementation MPDatabaseSettingsWindowController

- (NSString *)windowNibName {
  return @"DatabaseSettingsWindow";
}

- (id)init {
  self = [self initWithDocument:nil];
  return self;
}

- (id)initWithDocument:(MPDocument *)document {
  self = [super initWithWindow:nil];
  if(self) {
    _document = document;
    _missingFeature = NSLocalizedString(@"KDBX_ONLY_FEATURE", "Feature only available in kdbx databases");
  }
  return self;
}

- (void)windowDidLoad {
  [super windowDidLoad];
  
  NSAssert(_document != nil, @"Document needs to be present");
    
  [self.sectionTabView setDelegate:self];
  [self.encryptionRoundsTextField setFormatter:[[MPNumericalInputFormatter alloc] init]];
}

#pragma mark Actions

- (IBAction)save:(id)sender {
  /* General */
  KPKMetaData *metaData = _document.tree.metaData;
  metaData.databaseDescription = [self.databaseDescriptionTextView string];
  metaData.databaseName = [self.databaseNameTextField stringValue];

  NSInteger compressionIndex = [self.databaseCompressionPopupButton indexOfSelectedItem];
  if(compressionIndex >= KPKCompressionNone && compressionIndex < KPKCompressionCount) {
    metaData.compressionAlgorithm = (uint32_t)compressionIndex;
  }
  NSColor *databaseColor = [self.databaseColorColorWell color];
  if([databaseColor isEqual:[NSColor clearColor]]) {
    metaData.color = nil;
  }
  else {
    metaData.color = databaseColor;
  }
    
  /* Advanced */
  metaData.recycleBinEnabled = self.trashEnabled;
  NSMenuItem *trashMenuItem = [self.selectRecycleBinGroupPopUpButton selectedItem];
  KPKGroup *trashGroup = [trashMenuItem representedObject];
  _document.trash  = trashGroup;
  
  NSMenuItem *templateMenuItem = [self.templateGroupPopUpButton selectedItem];
  KPKGroup *templateGroup = [templateMenuItem representedObject];
  _document.templates = templateGroup;
  
  BOOL protectNotes = [self.protectNotesCheckButton state] == NSOnState;
  BOOL protectPassword = [self.protectPasswortCheckButton state] == NSOnState;
  BOOL protectTitle = [self.protectTitleCheckButton state] == NSOnState;
  BOOL protectURL = [self.protectURLCheckButton state] == NSOnState;
  BOOL protectUsername = [self.protectUserNameCheckButton state] == NSOnState;
  
  metaData.protectNotes = protectNotes;
  metaData.protectPassword = protectPassword;
  metaData.protectTitle = protectTitle;
  metaData.protectUrl = protectURL;
  metaData.protectUserName = protectUsername;
  metaData.defaultUserName = [self.defaultUsernameTextField stringValue];
  
  /*
   NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setBool:protectNotes forKey:kMPSettingsKeyLegacyHideNotes];
    [defaults setBool:protectPassword forKey:kMPSettingsKeyLegacyHidePassword];
    [defaults setBool:protectTitle forKey:kMPSettingsKeyLegacyHideTitle];
    [defaults setBool:protectURL forKey:kMPSettingsKeyLegacyHideURL];
    [defaults setBool:protectUsername forKey:kMPSettingsKeyLegacyHideUsername];
    [defaults synchronize];
   */
  [self close:nil];
}

- (IBAction)close:(id)sender {
  [self dismissSheet:0];
}

- (IBAction)benchmarkRounds:(id)sender {
  [self.benchmarkButton setEnabled:NO];
  [KPKCompositeKey benchmarkTransformationRounds:1 completionHandler:^(NSUInteger rounds) {
    [self.encryptionRoundsTextField setIntegerValue:rounds];
    [self.benchmarkButton setEnabled:YES];
  }];
}

- (void)updateView {
  if(!self.isDirty) {
    return;
  }
  /* Update all stuff that might have changed */
  KPKMetaData *metaData = _document.tree.metaData;
  [self _setupDatabaseTab:metaData];
  [self _setupProtectionTab:metaData];
  [self _setupAdvancedTab:_document.tree];
  self.isDirty = NO;
}

- (void)showSettingsTab:(MPDatabaseSettingsTab)tab {
  /*
   We need to make sure the window is loaded
   so we just call the the getter and led the loading commence
   */
  if(![self window]) {
    return;
  }
  [self.sectionTabView selectTabViewItemAtIndex:tab];
}

#pragma mark NSTableViewDelegate
- (BOOL)tabView:(NSTabView *)tabView shouldSelectTabViewItem:(NSTabViewItem *)tabViewItem {
  NSUInteger index = [tabView indexOfTabViewItem:tabViewItem];
  switch ((MPDatabaseSettingsTab)index) {
    case MPDatabaseSettingsTabSecurity:
    case MPDatabaseSettingsTabAdvanced:
    case MPDatabaseSettingsTabGeneral:
      return YES;
      
    default:
      return NO;
  }
}

#pragma mark Private Helper
- (void)_setupDatabaseTab:(KPKMetaData *)metaData {
  [self.databaseNameTextField setStringValue:metaData.databaseName];
  [self.databaseDescriptionTextView setString:metaData.databaseDescription];
  [self.databaseCompressionPopupButton selectItemAtIndex:metaData.compressionAlgorithm];
  NSColor *databaseColor = metaData.color ? metaData.color : [NSColor clearColor];
  [self.databaseColorColorWell setColor:databaseColor];
}

- (void)_setupProtectionTab:(KPKMetaData *)metaData {
  [self.protectNotesCheckButton setState:metaData.protectNotes ? NSOnState : NSOffState ];
  [self.protectPasswortCheckButton setState:metaData.protectPassword ? NSOnState : NSOffState];
  [self.protectTitleCheckButton setState:metaData.protectTitle ? NSOnState : NSOffState];
  [self.protectURLCheckButton setState:metaData.protectUrl ? NSOnState : NSOffState];
  [self.protectUserNameCheckButton setState:metaData.protectUserName ? NSOnState : NSOffState];
  [self.encryptionRoundsTextField setIntegerValue:metaData.rounds];
  [self.benchmarkButton setEnabled:YES];
}

- (void)_setupAdvancedTab:(KPKTree *)tree {
  [self bind:@"trashEnabled" toObject:tree.metaData withKeyPath:@"recycleBinEnabled" options:nil];
  [self.enableRecycleBinCheckButton bind:NSValueBinding toObject:self withKeyPath:@"trashEnabled" options:nil];
  [self.selectRecycleBinGroupPopUpButton bind:NSEnabledBinding toObject:self withKeyPath:@"trashEnabled" options:nil];
  [self _updateTrashFolders:tree];
  
  [self.defaultUsernameTextField setStringValue:tree.metaData.defaultUserName];
  [self.defaultUsernameTextField setEditable:YES];
  [self _updateTemplateGroup:tree];
}

- (void)_updateFirstResponder {
  NSTabViewItem *selected = [self.sectionTabView selectedTabViewItem];
  MPDatabaseSettingsTab tab = [[self.sectionTabView tabViewItems] indexOfObject:selected];
  
  switch(tab) {
    case MPDatabaseSettingsTabAdvanced:
      [[self window] makeFirstResponder:self.defaultUsernameTextField];
      break;
      
    case MPDatabaseSettingsTabSecurity:
      [[self window] makeFirstResponder:self.protectTitleCheckButton];
      break;
      
    case MPDatabaseSettingsTabGeneral:
      [[self window] makeFirstResponder:self.databaseNameTextField];
      break;
  }
}

- (void)_updateTrashFolders:(KPKTree *)tree {
  NSMenu *menu = [self _buildTrashTreeMenu:tree];
  [self.selectRecycleBinGroupPopUpButton setMenu:menu];
}

- (void)_updateTemplateGroup:(KPKTree *)tree {
  NSMenu *menu = [self _buildTemplateTreeMenu:tree];
  [self.templateGroupPopUpButton setMenu:menu];
}

- (NSMenu *)_buildTrashTreeMenu:(KPKTree *)tree {
  NSMenu *menu = [self _buildTreeMenu:tree preselect:tree.metaData.recycleBinUuid];
  
  NSMenuItem *selectItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"AUTOCREATE_TRASH_FOLDER", @"Menu item for automatic trash creation")
                                                      action:NULL
                                               keyEquivalent:@""];
  [selectItem setEnabled:YES];
  [menu insertItem:selectItem atIndex:0];
  
  return menu;
}

- (NSMenu *)_buildTemplateTreeMenu:(KPKTree *)tree {
  NSMenu *menu = [self _buildTreeMenu:tree preselect:tree.metaData.entryTemplatesGroup];
  
  NSMenuItem *selectItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"NO_TEMPLATE_GROUP", @"Menu item to reset the template groups")
                                                      action:NULL
                                               keyEquivalent:@""];
  [selectItem setEnabled:YES];
  [menu insertItem:selectItem atIndex:0];
  
  return menu;
}


- (NSMenu *)_buildTreeMenu:(KPKTree *)tree preselect:(NSUUID *)uuid {
  NSMenu *menu = [[NSMenu alloc] init];
  [menu setAutoenablesItems:NO];
  for(KPKGroup *group in tree.root.groups) {
    [self _insertMenuItemsForGroup:group atLevel:0 inMenu:menu preselect:uuid];
  }
  return menu;
}

- (void)_insertMenuItemsForGroup:(KPKGroup *)group atLevel:(NSUInteger)level inMenu:(NSMenu *)menu preselect:(NSUUID *)uuid{
  NSMenuItem *groupItem = [[NSMenuItem alloc] init];
  [groupItem setImage:group.iconImage];
  [groupItem setTitle:group.name];
  [groupItem setRepresentedObject:group];
  [groupItem setEnabled:YES];
  if(uuid && [group.uuid isEqual:uuid]) {
    [groupItem setState:NSOnState];
  }
  [groupItem setIndentationLevel:level];
  [menu addItem:groupItem];
  for(KPKGroup *childGroup in group.groups) {
    [self _insertMenuItemsForGroup:childGroup atLevel:level + 1 inMenu:menu preselect:uuid];
  }
}

@end
