/* Copyright (c) 2004, Noah Sorscher
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 	¥ 	Redistributions of source code must retain the above copyright
 * 	notice, this list of conditions and the following disclaimer.
 * 	¥ 	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.
 * 	¥ 	Neither the name of the Noah Sorscher nor the names of its
 * 	contributors may be used to endorse or promote products derived from
 * 	this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER 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 "tInit.h"
#include "defaults.h"
//#include "tModel.h"
#import "tPlaylist.h"
#include "tController.h"
//#import "tPathFormatter.h"
#import "MHMovie.h"

@implementation tInit

    float hlR = 0.938;
    float hlG = 0.962;
    float hlB = 1.0;
    float hlA = 1.0;
    
    id tInitNibInstance;

+ (void)initialize
{
    //NSLog(@"tInit initialize");
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSMutableDictionary *appDefs = [NSMutableDictionary dictionary];
    NSString *saveDir = [NSString stringWithFormat:@"%@/Movies", NSHomeDirectory()];
    BOOL isDir;
    if (![[NSFileManager defaultManager] fileExistsAtPath:saveDir isDirectory:&isDir] || !isDir)
        saveDir = NSHomeDirectory();
        
    // Preferences
    NSDictionary *controlSpeeds = [NSDictionary dictionaryWithObjectsAndKeys:@"2", @"FF Speed", @"2", @"RW Speed", @"10", @"Reverse Jump", @"30", @"Forward Jump", @".3", @"SloMo Speed", @".5", @"Snap Back", nil];
    [appDefs setObject:controlSpeeds forKey:@"controlSpeeds"];
    
    // Bools
    NSArray *yeses = [NSArray arrayWithObjects:t_remember, t_toSize, t_album, t_author, t_copy, t_credate, t_fname, t_desc, t_dir, t_info, t_perf, t_prod, t_writ, t_saveBeep, @"merge", @"rowColoring", @"hides", @"warn", @"optIcon", @"exitMouse", @"chapWin", @"brushed", @"optReduce", @"doubleClick", @"addSeparateAudio", nil];
    int i, n = [yeses count];
    for (i=0;i<n;i++) {
        [appDefs setObject:[NSNumber numberWithBool:YES] forKey:[yeses objectAtIndex:i]];
    }
    NSArray *noes = [NSArray arrayWithObjects:t_constrainAspectRatio, nil];
    n = [noes count];
    for (i=0;i<n;i++) {
        [appDefs setObject:[NSNumber numberWithBool:NO] forKey:[noes objectAtIndex:i]];
    }
    
    // Numbers
    int intValues[] = {10, 1, 1, 6, 4, 1, 1};
    NSArray *intKeys = [NSArray arrayWithObjects:t_numberOfAutoColumns, t_whichSize, t_interval, t_numPerformers, t_pathLevels, @"titleNumber", nil];
    n = [intKeys count];
    for (i=0;i<n;i++) {
        [appDefs setObject:[NSNumber numberWithInt:intValues[i]] forKey:[intKeys objectAtIndex:i]]; 
    }
    float floatValues[] = { hlA, hlB, hlG, hlR, 12};
    NSArray *floatKeys = [NSArray arrayWithObjects:@"hlA", @"hlB", @"hlG", @"hlR", @"fontSize", nil];
    n = [floatKeys count];
    for (i=0;i<n;i++) {
        [appDefs setObject:[NSNumber numberWithFloat:floatValues[i]] forKey:[floatKeys objectAtIndex:i]];
    }
    
    // Strings
    NSArray *stringValues = [NSArray arrayWithObjects:saveDir, @"Encoded by YourNameHere", @"native", @"", [[MHUtil supportDir] stringByAppendingPathComponent:@"Metahoot Download Cache.xml"], @"Credits", nil];
    NSArray *stringKeys = [NSArray arrayWithObjects:@"saveDir", t_commentText, @"fsAspect", @"iconText", @"cacheLocation", @"skipText", nil];
    n = [stringKeys count];
    for (i=0;i<n;i++) {
        [appDefs setObject:[stringValues objectAtIndex:i] forKey:[stringKeys objectAtIndex:i]];
    }
    
    [appDefs setObject:[[MHUtil supportDir] stringByAppendingString:@"textDump"] forKey:@"textDump"];
    
    [defaults registerDefaults:appDefs];
}

+ (BOOL)boolForKey:(NSString *)key
{	return [tInitNibInstance settingForKey:key];	}

+ (void)setBool:(BOOL)flag forKey:(NSString *)key
{	[tInitNibInstance setSetting:flag forKey:key];	}

+ (NSString *)stringForKey:(NSString *)key
{	return [tInitNibInstance stringSettingForKey:key];	}

+ (void)setString:(NSString *)string forKey:(NSString *)key
{	[tInitNibInstance setStringSetting:string forKey:key];	}

+ (double)doubleForKey:(NSString *)key
{	return [tInitNibInstance doubleSettingForKey:key];	}

+ (void)setDouble:(double)value forKey:(NSString *)key
{       [tInitNibInstance setDoubleSetting:value forKey:key];   }

- (void) flagsChanged:(NSEvent *)theEvent
{
    [[NSNotificationCenter defaultCenter] postNotificationName:@"flagsChangedNotification" object:theEvent];
}

- (void)applicationDidBecomeActive:(NSNotification *)aNotification
{
}

- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag
{
    //NSLog(@"tInit applicationShouldHandleReopen");
    NSArray *windows = [NSApp windows];
    NSMutableArray *visWins = [NSMutableArray array];
    if ([windows count]) {
        int i;
        for (i=0;i<[windows count];i++) {
            if ([[windows objectAtIndex:i] isVisible])
                [visWins addObject:[windows objectAtIndex:i]];
        }
    }
    if (!flag || [visWins count] == 0 || (([visWins count] == 1) && [visWins objectAtIndex:0] == [player fullscreenWindow])) { 
        [controller setMainTabViewName:@"Main"];
        [[controller mainWindow] makeKeyAndOrderFront:nil];
    }
    return NO;
}

- (void)reloadDatabase
{
    NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
	//[openingWindow makeKeyAndOrderFront:nil];
	NSArray *lists = [defs objectForKey:@"playlists"];
	if (nil == lists) lists = [NSArray array];
	/*
	 * look for old-version settings
	 */
	NSArray *oldList = nil;
	oldList = [defs objectForKey:t_movieData];
	if (oldList != nil) {
		NSMutableArray *newLists = [[NSMutableArray alloc] init];
		[newLists addObjectsFromArray:lists];
		NSMutableDictionary *playlist = [[NSMutableDictionary alloc] init];
		[playlist setObject:@"Old Playlist" forKey:@"name"];
		[playlist setObject:oldList forKey:@"movieData"];
		[newLists insertObject:playlist atIndex:0];
		lists = newLists;
		[defs removeObjectForKey:t_movieData];
	}
	
	tPlaylist *aModel;
	NSString *aName;
	NSDictionary *aList;
	int i;
	/*
	 * get the playlist names, and add to controller
	 */
	for (i=1;i<[lists count];i++) {
		aList = [lists objectAtIndex:i];
		aName = [aList objectForKey:@"name"];
		aModel = [(tPlaylist *)[tPlaylist alloc] initWithController:controller];
		[aModel setName:aName];
		[controller addPlaylist:aModel];
	}
	
	/*
	 * add options for smart playlists
	 */
	NSArray *addedLists = [controller playlists];
	NSArray *names = [defs objectForKey:@"playlistNames"];
	NSArray *options = [defs objectForKey:@"playlistOptions"];
	for (i=0;i<[names count];i++) {
		aName = [names objectAtIndex:i];
		if ([addedLists count] <= i+1 || ![aName isEqualToString:[[addedLists objectAtIndex:i+1] name]]) {
			aModel = [(tPlaylist *)[tPlaylist alloc] initWithController:controller];
			[aModel setName:aName];
			[controller addPlaylist:aModel];
			NSArray *option = [options objectAtIndex:i];
			if ([option count])
				[aModel setOptions:option];
		}
	}
	addedLists = [controller playlists];
	
	/*
	 * add the movies to the library playlist
	 */
	NSMutableArray *allMovies = [NSMutableArray array];
	for (i=0;i<[lists count];i++)
		[allMovies addObjectsFromArray:[[lists objectAtIndex:i] objectForKey:@"movieData"]];
	[[addedLists objectAtIndex:0] addFromDefsEntry:allMovies];
	
	// add the movies to the non-library playlists
	tPlaylist *library = [addedLists objectAtIndex:0];
	for (i=0;i<[allMovies count];i++) {
		NSArray *listNumbers = [[allMovies objectAtIndex:i] objectForKey:@"listNumbers"];
		int j, m = [listNumbers count];
		for (j=0;j<m;j++) {
			int index = [[listNumbers objectAtIndex:j] intValue];
			if (index > 0 && index < [addedLists count])
				[(tPlaylist *)[addedLists objectAtIndex:index] addMovie:[library movieForIndex:i]];
		}
	}
	
	// re-sort the playlists
	NSArray *sorts = [defs objectForKey:@"playlistSorts"];
	for (i=0;i<[sorts count];i++) {
		NSString *sort = [sorts objectAtIndex:i];
		if ([sort length])
			[[addedLists objectAtIndex:i] sortByIdentifier:sort];
	}
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    //NSLog(@"tInit applicationDidFinishLaunching");
    /*
     *	Movie Change Listeners
     */
    NSArray *movieChangeListeners = [NSArray arrayWithObjects:chapters, timeline, www, nil];
    int i, n = [movieChangeListeners count];
    for (i=0;i<n;i++) {
        [controller addMovieChangeListener:[movieChangeListeners objectAtIndex:i]];
    }

     /*
     *	(Re)load the Database
     */
    // weird bug workaround
    NSDictionary *fakeMovie = [NSDictionary dictionaryWithObject:[[NSBundle mainBundle] pathForResource:@"dummy" ofType:@"txt"] forKey:@"File Path"];
    tPlaylist *fakePlaylist = [(tPlaylist *)[tPlaylist alloc] initWithController:controller];
    [fakePlaylist setName:@"fake playlist"];
    [fakePlaylist addFromDefsEntry:[NSArray arrayWithObject:fakeMovie]];
    [controller addPlaylist:fakePlaylist];
    [controller removePlaylist:nil];
    
    NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
    if ([defs boolForKey:t_remember]) {
        [self reloadDatabase];
		[theTable reloadData];
    } else { // if not remember
        [controller addPlaylist:nil];
    }
    //[controller tableView:nil shouldSelectRow:-1];
    [controller tableView:nil shouldSelectRow:0];
    [plTable selectRow:0 byExtendingSelection:NO];
    
    [self setBrushedMetal];
    [[controller mainWindow] makeKeyAndOrderFront:nil];
    [controller updateTotals];
    [[theTable dataSource] tableView:theTable shouldSelectRow:0];
    [theTable selectRow:0 byExtendingSelection:NO];
    //[[controller mainWindow] makeFirstResponder:theTable];
}


- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{
    //NSLog(@"tInit applicationShouldTerminate");
    NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
    BOOL remember;
    
    [player windowShouldClose:nil];
    remember = [[defs objectForKey:t_remember] boolValue];
    if (remember) {
        //[model savePrefs];
        [controller savePrefs];
    }
    [defs synchronize];
    //[MHUtil killSupportDir];
    
    id vo = [NSConnection rootProxyForConnectionWithRegisteredName:@"mhImageHelper" host:nil];
    if (nil != vo)
        [vo quit];
    
    [MHUtil clearSupportDir];
    
    return YES;
}


- (NSColor *) tableView: (NSTableView *)tableView backgroundColorForRow: (int) row
{
    if (![rowColoring state]) return [NSColor whiteColor];
    if (tableView != theTable) return [NSColor whiteColor];
    int i = row % 2;
    if (!i)
        return [highlightColor color];
            //[aCell setBackgroundColor:[NSColor colorWithCalibratedRed:1.0 green:0.8586 blue:0.373 alpha:1.0]];
    return [NSColor whiteColor];
            //[aCell setBackgroundColor:[NSColor colorWithCalibratedRed:1.0 green:0.981 blue:0.738 alpha:1.0]];
}

- (NSColor *) tableView: (NSTableView *)tableView highlightColorForRow: (int) row
{
    double a = 1.0, r = (double)61/(double)256, g = (double)128/(double)256, b = (double)223/(double)256;
    return [NSColor colorWithCalibratedRed:r green:g blue:b alpha:a];
}


- (void)savePrefs
{
    //NSLog(@"tInit");
    NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
    [player savePrefs:self];
    
    // Bools
    int i, j, m, n = [theBoolButtons count];
    for (i=0;i<n;i++) {
        [defs setBool:[[theBoolButtons objectAtIndex:i] state] forKey:[theBoolKeys objectAtIndex:i]];
    }
    
    [MHMovie setAsksForMissingFiles:[askMovies state]];
    [MHMovie setIgnoresMissingFiles:![placeHolder state]];
    
	NSArray *tables = [NSArray arrayWithObjects:[controller mainTable], [controller plTable], [controller summaryTable], [controller tracksTable], nil];
	n = [tables count];
	for (i=0;i<n;i++) {
		NSTableView *t = [tables objectAtIndex:i];
		m = [[t tableColumns] count];
		for (j=0;j<m;j++) {
			NSCell *c = [[[t tableColumns] objectAtIndex:j] dataCell];
			if ([c respondsToSelector:@selector(setFont:)])
				[c setFont:[NSFont systemFontOfSize:[fontSize doubleValue]]];
		}
	}
    
    // Strings
    n = [theStringFields count];
    for (i=0;i<n;i++) {
        [defs setObject:[[theStringFields objectAtIndex:i] stringValue] forKey:[theStringKeys objectAtIndex:i]];
    }
    
    // Integers
    NSArray *intButtons = [NSArray arrayWithObjects:autoCols, numPerformers, pathLevels, nil];
    NSArray *intKeys = [NSArray arrayWithObjects:t_numberOfAutoColumns, t_numPerformers, t_pathLevels, nil];
    n = [intKeys count];
    for (i=0;i<n;i++) {
        [defs setInteger:[[intButtons objectAtIndex:i] intValue] forKey:[intKeys objectAtIndex:i]];
    }
    
    int sizeSelection = [saveSizeRadio selectedRow];
    [defs setInteger:sizeSelection forKey:t_saveSize];
    //[defs setInteger:[openWhichSize indexOfSelectedItem] forKey:t_whichSize];
    // color well nonsense
    float r, g, b, a;
    [[highlightColor color] getRed:&r green:&g blue:&b alpha:&a];
    [defs setFloat:r forKey:@"hlR"];
    [defs setFloat:g forKey:@"hlG"];
    [defs setFloat:b forKey:@"hlB"];
    [defs setFloat:a forKey:@"hlA"];
    [defs setFloat:[interval floatValue] forKey:t_interval];
    
    [lang savePrefs];
    
    [self setBrushedMetal];
    [defs synchronize];
}

- (IBAction)editAutoComplete:(id)sender
{
    //[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"learned"];
    //[[NSUserDefaults standardUserDefaults] synchronize];
}

- (IBAction)acAdd:(id)sender
{
    NSMutableDictionary *learned = [NSMutableDictionary dictionaryWithDictionary:[[NSUserDefaults standardUserDefaults] objectForKey:@"learned"]];
    id item = nil;
    int index = [acTable selectedRow];
    if (-1 == index)
        [learned setObject:[NSMutableArray array] forKey:@"New Category"];
    else {
        item = [acTable itemAtRow:index];
        if ([item parent])
            item = [item parent];
        NSString *cat = [item value];
        NSMutableArray *anArray = [NSMutableArray arrayWithArray:[learned objectForKey:cat]];
        [anArray addObject:@"New Value"];
        [learned setObject:anArray forKey:cat];
    }
    [[NSUserDefaults standardUserDefaults] setObject:learned forKey:@"learned"];
    [acTable reloadData];
    if (item)
        [acTable expandItem:item];
}

- (IBAction)acRemove:(id)sender
{
    NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
    NSMutableDictionary *learned = [NSMutableDictionary dictionaryWithDictionary:[defs objectForKey:@"learned"]];
    id item = [acTable itemAtRow:[acTable selectedRow]];
    if (!item) return;
    id parent = [item parent];
    if (parent) {
        NSMutableArray *anArray = [NSMutableArray arrayWithArray:[learned objectForKey:[parent value]]];
        [anArray removeObject:[item value]];
        [learned setObject:anArray forKey:[parent value]];
    } else {
        [learned removeObjectForKey:[item value]];
    }
    [defs setObject:learned forKey:@"learned"];
    [acTable reloadData];
    if (parent)
        [acTable expandItem:parent];
}

- (IBAction)setCache:(id)sender
{
    NSSavePanel *sp = [NSSavePanel savePanel];
    
    int runResult = [sp runModalForDirectory:nil file:@"Metahoot Download Cache.xml"];

    if (runResult == NSOKButton) {
        [cacheText setStringValue:[sp filename]];
    }
}

- (IBAction)defaultHLColor:(id)sender
{
    [highlightColor setColor:[NSColor colorWithCalibratedRed:hlR green:hlG blue:hlB alpha:hlA]];
}

- (void)setBrushedMetal
{
    //NSLog(@"tInit setBrushedMetal");
    NSRect aRect = [[[controller mainWindow] contentView] frame];
    NSRect winRect = [[controller mainWindow] frame];
    NSScreen *screen = [[controller mainWindow] screen];
    aRect.origin = winRect.origin;
    aRect.origin.y += winRect.size.height - aRect.size.height - 22;
    unsigned int styleMask, normalStyleMask = [prefsWindow styleMask];
    unsigned int brushedStyleMask = normalStyleMask | NSTexturedBackgroundWindowMask;
    BOOL shouldBrushed = [brushedMetal state];
    BOOL isBrushed = [[controller mainWindow] styleMask] == brushedStyleMask;
    if ((shouldBrushed && !isBrushed) || (!shouldBrushed && isBrushed)) {
        if (shouldBrushed)
            styleMask = brushedStyleMask;
        else styleMask = normalStyleMask;
        NSBackingStoreType backingType = NSBackingStoreBuffered;
        NSWindow *newWindow = [[NSWindow alloc] initWithContentRect:aRect styleMask:styleMask backing:backingType defer:NO screen:screen];
        NSToolbar *tb = [[controller mainWindow] toolbar];
        NSArray *tbItems = [tb items];
        [newWindow setContentView:[[controller mainWindow] contentView]];
        [newWindow setDelegate:player];
        [newWindow setFrameAutosaveName:@"editingWindow"];
        [newWindow setMinSize:NSMakeSize(400,107)];
        //[newWindow makeKeyAndOrderFront:nil];
        [newWindow registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, NSStringPboardType, nil]];
        [newWindow setTitle:@"MetaHoot"];
        [newWindow setReleasedWhenClosed:NO];
        [controller setMainWindow:newWindow];
        int i;
        for (i=0;i<[tbItems count];i++) {
            [tb removeItemAtIndex:i];
            [tb insertItemWithItemIdentifier:[[tbItems objectAtIndex:i] itemIdentifier] atIndex:i];
        }
        [[controller mainWindow] makeKeyAndOrderFront:nil];
    }
}

- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
{
    //NSLog(@"tInit application: openFile:");
    [controller performSelector:@selector(openFilesFromArray:) withObject:[NSArray arrayWithObject:filename] afterDelay:0];
    //[controller openFilesFromArray:[NSArray arrayWithObject:filename] model:[controller getTrueModel]];
    return YES;
}

- (void) awakeFromNib
{
    //NSLog(@"tInit awakeFromNib");
    tInitNibInstance = self;
    NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
    //NSString *idString;
    int autoColumns;
    int i, n;
    //NSArray *cols = [defs objectForKey:t_cols];
    NSTableColumn *aColumn;
    
    //NSLog(@"init");
    /*
     *	For Drag and Drop
     */
    [[controller mainWindow] registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, NSStringPboardType, nil]];
    /*
     *	Initialize the Tableview shit
     */
    [theTable setAllowsColumnReordering:YES];
    [theTable setAllowsColumnResizing:YES];
    [theTable setAllowsMultipleSelection:YES];
    [theTable setAllowsEmptySelection:YES];
    [theTable setAllowsColumnSelection:YES];
    //[theTable setSizesToFit:NO];
    //[plTable setSizesToFit:YES];
    [theTable registerForDraggedTypes:[NSArray arrayWithObject:@"moviesFromSelf"]];
    [plTable registerForDraggedTypes:[NSArray arrayWithObjects:@"moviesFromOther", NSFilenamesPboardType, nil]];
    NSSize aSize;
    aSize.height = 0.0;
    aSize.width = 1.0;
    [theTable setIntercellSpacing:aSize];
    
    [chapterTable setDelegate:chapters];
   
    //chapter table
    aColumn = [[NSTableColumn alloc] initWithIdentifier:@"Content"];
    [[aColumn headerCell] setStringValue:@"Content"];
    [chapterTable addTableColumn:aColumn];
    aColumn = [[NSTableColumn alloc] initWithIdentifier:@"Start"];
    [[aColumn headerCell] setStringValue:@"Start"];
    [chapterTable addTableColumn:aColumn];
    [chapterTable setDelegate:chapters];
    [chapterTable reloadData];
    [chapterTable setNeedsDisplay:YES];
    
    /*
     *	Restore the Preferences
     */
     
     [lang restorePrefs];
     if (![defs objectForKey:@"controlSpeeds"]) {
        NSDictionary *controlSpeeds = [NSDictionary dictionaryWithObjectsAndKeys:@"2", @"FF Speed", @"2", @"RW Speed", @"10", @"Reverse Jump", @"30", @"Forward Jump", @".3", @"SloMo Speed", @".5", @"Snap Back", nil];
        [defs setObject:controlSpeeds forKey:@"controlSpeeds"];
     }
    
    // BOOLs
    theBoolButtons = [NSArray arrayWithObjects:rememberSwitch, openSizeSwitch, playOn, optAlbum, optAuthor, optComment, optCopy, optCreDate, optFName, optDesc, optDir, optInfo, optPerf, optProd, optWrit, optGenre, optWebsite, saveBeep, askMovies, updateFilename, exitPlay, chapScale, optMerge, floatWindow, hides, brushedMetal, doubleClick, editWarning, customIcon, optIcon, placeHolder, skip, autoComplete, scaleImportedChapters, exitMouse, editChapTimes, scaleDVDChapters, optReduce, dontAnimate, addSeparateAudio, optRating, nil];
    [theBoolButtons retain];
    theBoolKeys = [NSArray arrayWithObjects:t_remember, t_toSize, t_playOn, t_album, t_author, t_comment, t_copy, t_credate, t_fname, t_desc, t_dir, t_info, t_perf, t_prod, t_writ, @"optGenre", @"optWebsite", t_saveBeep, t_ask, @"filename", @"exitPlay", @"chapScale", @"merge", @"float", @"hides", @"brushed", @"doubleClick", @"warn", @"customIcon", @"optIcon", @"placeHolder", @"skip", @"autoComplete", @"scaleImportedChapters", @"exitMouse", @"editChapTimes", @"scaleDVDChapters", @"optReduce", @"dontAnimate", @"addSeparateAudio", @"optRating", nil];
    [theBoolKeys retain];
    n = [theBoolKeys count];
    for (i=0;i<n;i++) {
        [[theBoolButtons objectAtIndex:i] setState:[defs boolForKey:[theBoolKeys objectAtIndex:i]]];
    }
    
    [MHMovie setAsksForMissingFiles:[askMovies state]];
    [MHMovie setIgnoresMissingFiles:![placeHolder state]];
    
    // Strings
    theStringFields = [NSArray arrayWithObjects:saveDirPath, commentText, fsAspect, iconText, skipText, nil];
    [theStringFields retain];
    theStringKeys = [NSArray arrayWithObjects:@"saveDir", t_commentText, @"fsAspect", @"iconText", @"skipText", nil];
    [theStringKeys retain];
    NSString *value;
    n = [theStringKeys count];
    for (i=0;i<n;i++) {
        value = [defs objectForKey:[theStringKeys objectAtIndex:i]];
        if (value) {
            //NSLog(@"nil value for %@", [theStringKeys objectAtIndex:i]);
            [[theStringFields objectAtIndex:i] setStringValue:value];
        }
    }
    
    // Doubles
    theDoubleFields = [[NSArray arrayWithObjects:fontSize, nil] retain];
    theDoubleKeys = [[NSArray arrayWithObjects:@"fontSize", nil] retain];
    n = [theDoubleKeys count];
    for (i=0;i<n;i++) {
        value = [defs objectForKey:[theDoubleKeys objectAtIndex:i]];
        if (nil != value)
            [[theDoubleFields objectAtIndex:i] setStringValue:value];
    }
    
    //[openWhichSize selectItemAtIndex:[defs integerForKey:t_whichSize]];
    //[openWhichSize setEnabled:[openSizeSwitch state]];
    autoColumns = [defs integerForKey:t_numberOfAutoColumns];
    [autoCols setIntValue:autoColumns];
    [saveSizeRadio selectCellAtRow:[defs integerForKey:t_saveSize] column:0];
    [saveTypeRadio selectCellAtRow:[defs integerForKey:t_saveType] column:0];
    [interval setFloatValue:[defs floatForKey:t_interval]];
    //[ffSpeed setFloatValue:[defs floatForKey:t_ff]];
    [numPerformers setIntValue:[defs integerForKey:t_numPerformers]];
    [pathLevels setIntValue:[defs integerForKey:t_pathLevels]];
    
    if ([floatWindow state])
        [viewWindow setLevel:NSFloatingWindowLevel];
    /*
    // color well nonsense
    float r, g, b, a;
    r = [defs floatForKey:@"hlR"];
    g = [defs floatForKey:@"hlG"];
    b = [defs floatForKey:@"hlB"];
    a = [defs floatForKey:@"hlA"];
    if (0 == r && 0 == g && 0 == b && 0 == a) {
        r = hlR;
        g = hlG;
        b = hlB;
        a = hlA;
    }
    [highlightColor setColor:[NSColor colorWithCalibratedRed:r green:g blue:b alpha:a]];
    */
    /*
     *	Set Up the Timer
     */
    NSTimeInterval timeInterval = [defs integerForKey:t_interval];
    theTimer = [NSTimer scheduledTimerWithTimeInterval:timeInterval target:[controller getPlayer] selector:@selector(tick:) userInfo:nil repeats:YES];
    
    [self savePrefs];
}

- (BOOL)settingForKey:(NSString *)key
{
    int i, n = [theBoolKeys count];
    for (i=0;i<n;i++) {
        if ([key isEqualToString:[theBoolKeys objectAtIndex:i]])
            return [[theBoolButtons objectAtIndex:i] state];
    }
    return NO;
}

- (void)setSetting:(BOOL)flag forKey:(NSString *)key
{
    int i, n = [theBoolKeys count];
    for (i=0;i<n;i++) {
        if ([key isEqualToString:[theBoolKeys objectAtIndex:i]])
            [[theBoolButtons objectAtIndex:i] setState:flag];
    }
}

- (NSString *)stringSettingForKey:(NSString *)key
{
    int i, n = [theStringKeys count];
    for (i=0;i<n;i++) {
        if ([key isEqualToString:[theStringKeys objectAtIndex:i]])
            return [[theStringFields objectAtIndex:i] stringValue];
    }
    return @"";
}

- (void)setStringSetting:(NSString *)string forKey:(NSString *)key
{
    int i, n = [theStringKeys count];
    for (i=0;i<n;i++) {
        if ([key isEqualToString:[theStringKeys objectAtIndex:i]])
            [[theStringFields objectAtIndex:i] setStringValue:string];
    }
}

- (double)doubleSettingForKey:(NSString *)key
{
    int i, n = [theDoubleKeys count];
    for (i=0;i<n;i++) {
        if ([key isEqualToString:[theDoubleKeys objectAtIndex:i]])
            return [[theDoubleFields objectAtIndex:i] doubleValue];
    }
    return 0;
}

- (void)setDoubleSetting:(double)value forKey:(NSString *)key
{
    int i, n = [theDoubleKeys count];
    for (i=0;i<n;i++) {
        if ([key isEqualToString:[theDoubleKeys objectAtIndex:i]])
            [[theDoubleFields objectAtIndex:i] setDoubleValue:value];
    }
}

- (IBAction)newTimer:(id)sender
{
    NSTimeInterval timeInterval = [interval floatValue];
    [theTimer invalidate];
    theTimer = [NSTimer scheduledTimerWithTimeInterval:timeInterval target:[controller getPlayer] selector:@selector(tick:) userInfo:nil repeats:YES];
}


- (id)outlineView:(NSOutlineView *)outlineView child:(int)index ofItem:(id)item
{
    NSDictionary *learned = [[NSUserDefaults standardUserDefaults] objectForKey:@"learned"];
    tOutlineItem *toi = [[tOutlineItem alloc] init];
    [toi setParent:item];
    NSString *value;
    if (!item)
        value = [[learned allKeys] objectAtIndex:index];
    else
        value = [[learned objectForKey:[item value]] objectAtIndex:index];
    [toi setValue:value];
    return toi;
}

- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item
{
    return [[[[NSUserDefaults standardUserDefaults] objectForKey:@"learned"] allKeys] containsObject:[item value]];
}

- (int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
{
    NSDictionary *learned = [[NSUserDefaults standardUserDefaults] objectForKey:@"learned"];
    if (!item) return [learned count];
    return [(NSArray *)[learned objectForKey:[item value]] count];
}

- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
{
    //NSDicitonary *learned = [[NSUserDefaults standardUserDefaults] objectForKey:@"learned"];
    return [item value];
}

- (void)outlineView:(NSOutlineView *)outlineView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
{

    NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
    NSMutableDictionary *learned = [NSMutableDictionary dictionaryWithDictionary:[defs objectForKey:@"learned"]];
    NSMutableArray *anArray;
    if ([item parent]) {
        anArray = [NSMutableArray arrayWithArray:[learned objectForKey:[[item parent] value]]];
        [anArray removeObject:[item value]];
        [anArray addObject:object];
        [learned setObject:anArray forKey:[[item parent] value]];
    } else {
        anArray = [NSMutableArray arrayWithArray:[learned objectForKey:[item value]]];
        [learned removeObjectForKey:[item value]];
        [learned setObject:anArray forKey:object];
    }
    [defs setObject:learned forKey:@"learned"];
    [defs synchronize];
}

@end
