//
//  MyDocument.m
//  Flash2
//
//  Created by Nicholas Matsakis on 8/1/08.
//  Copyright Nicholas Matsakis 2008 . All rights reserved.
//

#import "Dictionary.h"
#import "UpdateCardController.h"
#import "Card.h"
#import "OxNSSet.h"
#import "Language.h"

@implementation Dictionary

- (id)init 
{
    self = [super init];
    if (self != nil) {
		// These never change once the program starts:
		m_languages = [Language languages];
		m_relations = [m_languages valueForKeyPath:@"@distinctUnionOfArrays.relations"];
    }
    return self;
}

@synthesize languages = m_languages;
@synthesize relations = m_relations;

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

- (void)windowControllerDidLoadNib:(NSWindowController *)windowController 
{
    [super windowControllerDidLoadNib:windowController];
    // user interface preparation code
}

- (void)awakeFromNib
{
	NSManagedObjectContext *mctx = [self managedObjectContext];
	NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
	[center addObserver:self
			   selector:@selector(objectsDidChange:)
				   name:NSManagedObjectContextObjectsDidChangeNotification
				 object:mctx];									
}

- (void) finalize
{
	NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
	[center removeObserver:self];
	[super finalize];
}

- (void) possibleSpellingChangeFrom:(NSString *)commit to:(NSString *)display
{
	if ([display isEqual:commit])
		return;
	UpdateCardController *ucc = [[UpdateCardController alloc] initWithOldSpelling:commit
																	  newSpelling:display 
															 managedObjectContext:[self managedObjectContext]];
	[ucc execute];
}

// Invoked whenever objects in the NSManagedObjectContext* change.
// Search through updated objects and look for those whose fromStringDisplay (rsp. toStringDisplay)
// varies from their fromStringCommit (rsp. toStringDisplay).  If any
// are detected, that indicates that the user updated the spelling of a card:
// in that case, create an UpdateCardController instance and give it
// control.
- (void)objectsDidChange:(NSNotification*)notification
{
	NSUndoManager *undoManager = [self undoManager];
	if ([undoManager isUndoing] || [undoManager isRedoing])
		return;
	NSSet *updatedObjects = [[notification userInfo] objectForKey:NSUpdatedObjectsKey];
	if (updatedObjects == nil || [updatedObjects isEmpty])
		return;
	[self performSelector:@selector(checkForOutOfSyncObject:)
			   withObject:[updatedObjects copy]	
			   afterDelay:0];
}

- (void) checkForOutOfSyncObject:(NSSet*)updatedObjects
{
	NSUndoManager *undoManager = [self undoManager];
	
	[undoManager beginUndoGrouping];
	
	for (id obj in updatedObjects) {
		if ([obj isKindOfClass:[Card class]]) {
			Card *card = obj;
			[self possibleSpellingChangeFrom:card.fromStringCommit to:card.fromStringDisplay];
			[self possibleSpellingChangeFrom:card.toStringCommit to:card.toStringDisplay];
			if (![card.fromStringCommit isEqual:card.fromStringDisplay])
				card.fromStringCommit = card.fromStringDisplay;
			if (![card.toStringCommit isEqual:card.toStringDisplay])
				card.toStringCommit = card.toStringDisplay;
		}
	}
	
	[undoManager endUndoGrouping];
}

@end
