//
//  PreferencesWindowController.m
//  Cog
//
//  Created by Vincent Spader on 3/7/09.
//  Copyright 2009 __MyCompanyName__. All rights reserved.
//

#import "PreferencesWindow.h"
#import "PreferencePanePlugin.h"

#import "Logging.h"

@interface PreferencesWindow ()

- (NSString *)lastPaneDefaultsKey;
- (BOOL)loadPaneNamed:(NSString *)name display:(BOOL)display;
- (void)createToolbar;

@end

@implementation PreferencesWindow {
	NSMutableArray<NSToolbarItemIdentifier> *preferencePaneOrder;
	NSMutableDictionary<NSToolbarItemIdentifier, id<PreferencePane>> *preferencePanes;
	NSMutableDictionary<NSToolbarItemIdentifier, NSToolbarItem *> *toolbarItems;
}

- (instancetype)initWithPreferencePanes:(NSArray<id<PreferencePane>> *)panes {
	NSWindowStyleMask windowStyleMask =
	(NSWindowStyleMaskClosable | NSWindowStyleMaskTitled);
	self = [super initWithContentRect:NSMakeRect(0, 0, 530, 300)
	                        styleMask:windowStyleMask
	                          backing:NSBackingStoreBuffered
	                            defer:NO];
	if(self) {
		preferencePaneOrder = [[NSMutableArray alloc] init];
		preferencePanes = [[NSMutableDictionary alloc] init];

		for(id<PreferencePane> pane in panes) {
			[preferencePaneOrder addObject:[pane title]];
			[preferencePanes setObject:pane forKey:[pane title]];
		}

		[self setReleasedWhenClosed:NO];
		[self setTitle:NSLocalizedString(@"PreferencesTitle", @"")];
		[self center];

		if(@available(macOS 11, *)) {
			[self setToolbarStyle:NSWindowToolbarStylePreference];
		}

		[self createToolbar];
	}

	return self;
}

- (NSString *)lastPaneDefaultsKey {
	return @"LastPreferencePane";
}

- (void)setContentView:(NSView *)view animate:(BOOL)animate {
	NSSize newSize = view.bounds.size;
	NSSize oldSize = [self contentView].bounds.size;

	CGFloat diff = newSize.height - oldSize.height;
	NSRect newFrame = [self frame];
	newFrame.size.height += diff;
	newFrame.origin.y -= diff;

	if(animate) {
		[self setContentView:nil];
	}
	[self setFrame:newFrame display:animate animate:animate];

	[self setContentView:view];
	[self setContentSize:newSize];
}

- (BOOL)loadPaneNamed:(NSString *)name display:(BOOL)display {
	id<PreferencePane> paneController = preferencePanes[name];
	if(!paneController) {
		return NO;
	}

	NSView *paneView = [paneController view];
	if(!paneView || [self contentView] == paneView) {
		return NO;
	}

	[self setContentView:paneView animate:display];

	// Update defaults
	[[NSUserDefaults standardUserDefaults] setObject:name forKey:[self lastPaneDefaultsKey]];

	[[self toolbar] setSelectedItemIdentifier:name];

	return YES;
}

- (void)createToolbar {
	toolbarItems = [[NSMutableDictionary alloc] init];
	for(NSString *name in preferencePaneOrder) {
		id<PreferencePane> pane = preferencePanes[name];

		NSToolbarItem *item = [[NSToolbarItem alloc] initWithItemIdentifier:name];
		[item setPaletteLabel:name]; // item's label in the "Customize Toolbar" sheet (not relevant here, but we set it anyway)
		[item setLabel:name]; // item's label in the toolbar

		[item setToolTip:name];
		[item setImage:[pane icon]];

		[item setTarget:self];
		[item setAction:@selector(toolbarItemClicked:)]; // action called when item is clicked

		toolbarItems[name] = item;
	}

	NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
	NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:[bundleIdentifier stringByAppendingString:@" Preferences Toolbar"]];
	[toolbar setDelegate:self];
	[toolbar setAllowsUserCustomization:NO];
	[toolbar setAutosavesConfiguration:NO];
	[toolbar setDisplayMode:NSToolbarDisplayModeIconAndLabel];

	[toolbar setSizeMode:NSToolbarSizeModeDefault];

	[self setToolbar:toolbar];
}

- (void)show {
	NSString *lastPane = [[NSUserDefaults standardUserDefaults] objectForKey:[self lastPaneDefaultsKey]];
	// Previous pane names migrations.
	if([lastPane isEqualToString:NSLocalizedPrefString(@"Growl")]) {
		lastPane = NSLocalizedPrefString(@"Notifications");
	}
	if([lastPane isEqualToString:NSLocalizedPrefString(@"Last.fm")]) {
		lastPane = NSLocalizedPrefString(@"Scrobble");
	}
	if(nil == lastPane) {
		if(0 >= [preferencePaneOrder count]) {
			ALog(@"Error: Preference panes not found!");
		}

		lastPane = preferencePaneOrder[0];
	}

	[self loadPaneNamed:lastPane display:NO];

	[self makeKeyAndOrderFront:self];
}

// Close on Esc pressed.
- (void)cancelOperation:(id)sender {
	[self close];
}

#pragma mark Delegate methods

- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar {
	return preferencePaneOrder;
}

- (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar {
	return preferencePaneOrder;
}

- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar {
	return preferencePaneOrder;
}

- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag {
	return toolbarItems[itemIdentifier];
}

- (void)toolbarItemClicked:(NSToolbarItem *)item {
	[self loadPaneNamed:[item itemIdentifier] display:YES];
}

@end
