//
//  LanguagesTabController.m
//  Flash2
//

#import "LanguagesTabController.h"
#import "Models.h"
#import "CodeController.h"
#import "OxCoreData.h"
#import "OxNSArrayController.h"
#import "OxNSTreeController.h"
#import "OxNSDocument.h"

@implementation LanguagesTabController

- (void) awakeFromNib
{
}

- (NSManagedObjectContext*) managedObjectContext
{
    return [m_vocabulary managedObjectContext];
}

- (IBAction) addLanguage:(id)sender {
    [m_languagesAddOn awaitAdd];
    
    NSManagedObjectContext *mctx = [self managedObjectContext];
    Language *language = [NSEntityDescription insertNewObjectForEntityForName:E_LANGUAGE
                                                       inManagedObjectContext:mctx];
    Category *rootCategory = [NSEntityDescription insertNewObjectForEntityForName:E_CATEGORY 
                                                           inManagedObjectContext:mctx];
    language.rootCategory = rootCategory;
    rootCategory.language = language;
    rootCategory.name = @"All";
    //rootCategory.order = [NSNumber numberWithInt:0];   
}

- (IBAction) addCategory:(id)sender {
    [m_categoriesAddOn awaitAdd];

    NSManagedObjectContext *mctx = [self managedObjectContext];
    Language *lang = [m_languages selectedObject];
    Category *parentCategory = [m_categories selectedObject];
    Category *newCategory = [NSEntityDescription insertNewObjectForEntityForName:E_CATEGORY 
                                                          inManagedObjectContext:mctx];
    newCategory.language = lang;
    newCategory.superCategory = parentCategory;
    newCategory.name = @"New Category";
    newCategory.order = [NSNumber numberWithInt:INT_MAX];
    [lang reorderRelationshipsAndCategories];
}

- (IBAction) addRelationship:(id)sender {
    [m_relationshipsAddOn awaitAdd];
    
    NSManagedObjectContext *mctx = [self managedObjectContext];
    Language *lang = [m_languages selectedObject];
    Category *category = [m_categories selectedObject];
    
    Relationship *newRel = [NSEntityDescription insertNewObjectForEntityForName:E_RELATIONSHIP 
                                                         inManagedObjectContext:mctx];
    newRel.fromCategory = category;
    newRel.toCategory = lang.rootCategory;    // sensible default
    newRel.name = @"New Relationship";
    newRel.order = [NSNumber numberWithInt:INT_MAX];
    [lang reorderRelationshipsAndCategories];
}

- (IBAction) editMethods:(id)sender {
    Language *curLang = [m_languages selectedObject];
    CodeController *cc = [[CodeController alloc] initWithManagedObjectContext:[self managedObjectContext]
                                                                     language:curLang];
    [[cc window] makeKeyAndOrderFront:self];
}

- (NSArray*) keyboardLayouts
{
    return [NSArray array];
}

#pragma mark -
#pragma mark Sort descriptors

- (NSArray*) sortByOrder {
    NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:K_ORDER ascending:YES];
    return [NSArray arrayWithObject:sort];
}

- (NSArray*) sortByLanguageAndOrder {
    NSSortDescriptor *lang = 
    [[NSSortDescriptor alloc] initWithKey:K_CATEGORY_LANGUAGE
                                ascending:YES
                                 selector:@selector(compareName:)];    
    NSSortDescriptor *order = 
    [[NSSortDescriptor alloc] initWithKey:K_ORDER 
                                ascending:YES];    
    return [NSArray arrayWithObjects:lang,order,nil];
}

#pragma mark -
#pragma mark Moving Categories

void addSubCategories(NSMutableArray *result, Category *cat) {
    for (Category *subcat in cat.subCategories) {
        [result addObject:subcat];
        addSubCategories(result, subcat);
    }
}

@synthesize categoriesToMove = a_categoriesToMove;
@synthesize targetCategory = a_targetCategory;

- (IBAction) moveCategory:(id)sender
{
    // gather a list of all categories (in order) and set the property
    // (the move panel is watching it)
    NSMutableArray *catMove = [NSMutableArray array];
    Language *curLang = [m_languages selectedObject];
    Category *rootCat = curLang.rootCategory;
    [catMove addObject:rootCat];
    addSubCategories(catMove, rootCat);
    self.categoriesToMove = catMove;
    
    // initialize target category to the current parent
    Category *categoryToMove = [m_categories selectedObject];
    self.targetCategory = categoryToMove.superCategory;
    
    // 
    NSApplication *app = [NSApplication sharedApplication];
    [app beginSheet:m_movePanel
     modalForWindow:m_window
      modalDelegate:self
     didEndSelector:@selector(moveSheetDidEnd:returnCode:contextInfo:)
        contextInfo:nil];
}

- (IBAction) move:(id)sender
{
    NSApplication *app = [NSApplication sharedApplication];
    [app endSheet:m_movePanel returnCode:YES];
}

- (IBAction) dontMove:(id)sender
{
    NSApplication *app = [NSApplication sharedApplication];
    [app endSheet:m_movePanel returnCode:NO];
}

- (void)moveSheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
{
    if (returnCode == YES) {
        Category *categoryToMove = [m_categories selectedObject];
        Category *newParentCategory = self.targetCategory;
        
        // make sure that categoryToMove is not a parent of newParentCategory!
        NSLog(@"Move category %@ to new parent %@", categoryToMove.name, newParentCategory.name);
        if (categoryToMove != newParentCategory) {
            Category *p = newParentCategory;
            while (p != categoryToMove && p != nil)
                p = p.superCategory;
            if (p == nil)
                categoryToMove.superCategory = newParentCategory;
            else
                [m_vocabulary presentErrorMessage:@"Cannot move \"%@\" into child category \"%@\"",
                 categoryToMove.name, newParentCategory.name];
        } else
            [m_vocabulary presentErrorMessage:@"Cannot move \"%@\" into itself",
             categoryToMove.name];
    }
    [sheet orderOut:self];
    
    self.targetCategory = nil;
    self.categoriesToMove = [NSArray array];
}

@end
