//
//  EditCardsController.m
//  Flash2
//
//  Copyright 2008 Nicholas Matsakis. 
//  The code in thie file is released to the public under the
//  terms of the MIT License as described here:
//  http://www.opensource.org/licenses/mit-license.php
//

#import "AddCardsController.h"
#import "OxMemoize.h"
#import "OxCoreData.h"
#import "OxKeyValue.h"
#import "Card.h"
#import "OxNSSet.h"
#import "OxObservableArray.h"
#import "OxNSString.h"

@implementation AddCardsController

@synthesize language = a_language;

#pragma mark -
#pragma mark Initialization

- (void) awakeFromNib {
    m_mctx = [m_dict managedObjectContext];
    [self reset:self];
    [self addObserver:self forKeyPath:@"language" options:0 context:nil];
}

- (void) observeValueForKeyPath:(NSString*)keyPath 
                       ofObject:(id)object 
                         change:(NSDictionary*)change 
                        context:(void*)context
{
    invokeObservationSelector(self, keyPath, object, change, context);
}

#pragma mark -
#pragma mark New Cards

@synthesize newCards = a_newCards;
@synthesize newCardsC = m_newCardsController;

- (void) addEmptyCard:(id)sender
{  
    if (self.language == nil)
        return;
        
    if (m_lastCard) [m_lastCard removeObserver:self forKeyPath:@"relationName"];   
    m_lastCard = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                  @"", @"fromString", @"", @"toString", [NSNull null], @"relationName", nil];
    [m_lastCard addObserver:self forKeyPath:@"relationName" options:0 context:nil];

	self.newCards = [self.newCards arrayByAddingObject:m_lastCard];
}

- (void) observeValueForRelationNameOfObject:(id)object 
									  change:(NSDictionary*)change 
									 context:(void*)context
{
    NSAssert(object == m_lastCard, @"Observation for an object besides m_lastCard");
    NSAssert(m_lastCard, @"m_lastCard nil");
    [self addEmptyCard:self];
}

- (void) observeValueForLanguageOfObject:(id)object 
                                  change:(NSDictionary*)change 
                                 context:(void*)context
{
    // when language changes, reset the relations and all
    NSAssert(object == self, @"Observation for an object besides self");
    [self reset:self];
}

#pragma mark -
#pragma mark Existing Cards

+ (NSSet*) keyPathsForValuesAffectingExistingCards {
    return [NSSet setWithObjects:
			@"newCards.fromString", 
			@"newCards.toString", 
			nil];
}

//@dynamic existingCards;

- (NSPredicate*) existingCards
{
	NSArray *fromStrings = [self.newCards valueForKeyPath:@"fromString"];
	NSArray *toStrings = [self.newCards valueForKeyPath:@"toString"];
	NSMutableSet *allStrings = [NSMutableSet setWithUnionOfArrays:fromStrings, toStrings, nil];
	[allStrings removeObject:@""];
	
	if ([allStrings isEmpty]) {
		return nil; // show all cards
	}
	
	NSMutableArray *clauses = [NSMutableArray array];
	NSMutableDictionary *vars = [NSMutableDictionary dictionary];
	int counter = 0;
	for (NSString *string in allStrings) {
		NSString *varName = [NSString stringWithFormat:@"str%d", counter++];
		[vars setValue:string forKey:varName];
		[clauses addObject:[NSString stringWithFormat:@"fromStringDisplay contains $%@", varName]];
		[clauses addObject:[NSString stringWithFormat:@"toStringDisplay contains $%@", varName]];
	}
	
	NSString *predicateString = [NSString stringByJoining:clauses withString:@" OR "];
	NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateString];
	return [predicate predicateWithSubstitutionVariables:vars];
}

#pragma mark -
#pragma mark Actions

- (IBAction) addAll:(id)sender {
	NSNull *null = [NSNull null];
    for (NSDictionary *dict in self.newCards) {
        NSString *fromString = [dict valueForKey:@"fromString"];
        NSString *relationName = [dict valueForKey:@"relationName"];
        NSString *toString = [dict valueForKey:@"toString"];
        
        [dict setValue:@"" forKey:@"fromString"];
        [dict setValue:@"" forKey:@"toString"];
        
        if ([fromString isEqualToString:@""] || (id)relation == null || [toString isEqualToString:@""]) 
            continue;
        
        Card *card = [NSEntityDescription insertNewObjectForEntityForName:@"Card"
                                                   inManagedObjectContext:m_mctx];
        card.fromStringDisplay = card.fromStringCommit = fromString;
        card.relationName = relationName;
        card.toStringDisplay = card.toStringCommit = toString;        
    }
}

- (IBAction) reset:(id)sender {
    self.newCards = [OxObservableArray array];
    [self addEmptyCard:nil];
}

@end
