/*
 Flash: Flashcard program
 Copyright (C) 2005, Niko Matsakis (niko@alum.mit.edu)
 
 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 2
 of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#import "Import.h"
#import "ImportParameter.h"
#import "OAMacros.h"
#import "Accessors.h"
#import "Errors.h"
#import "OAWorkChunker.h"
#import "OADebug.h"
#import "OACategories.h"

@implementation Import

- initWithDocument:(DictionaryDocument*)dictionary
{
    if ((self = [super init])) {
    
        // do not retain fields of dictionary or dictionary: let it retain us 
        // instead.
        _dictionary = dictionary;
        _managedObjectContext = [_dictionary managedObjectContext];
        
        // for now assume tab delimited:
        _columnSeparator = @"\t";
        
        // XXX: todo, if no languages are defined display an error
        
        // load NIB.  Obviously we don't expect this to fail.
        if (![NSBundle loadNibNamed:@"Import" owner:self]) {
            @throw ([NSException exceptionWithName:@"NoImportNibException" 
                                            reason:@"ImportNibCouldNotBeLoaded"
                                          userInfo:nil]);
        }
        
    }
    return self;
}

- (void) dealloc
{
    [_filesToOpen release];
    [_allData release];
    [_selectedEncoding release];
    [_importParameters release];
    [super dealloc];
}

- (NSManagedObjectContext*) managedObjectContext
{
    return _managedObjectContext;
}

- (void) startImport
{
    NSOpenPanel *oPanel = [NSOpenPanel openPanel];
    [oPanel setAllowsMultipleSelection:YES];
    [oPanel setCanChooseDirectories:NO];
    [oPanel setCanChooseFiles:YES];
    int returnCode = [oPanel runModalForTypes:nil];
    
    /*
    I wanted to do this as a panel, but this doesn't seem to work for some reason:
    [oPanel beginSheetForDirectory:nil 
                              file:nil 
                             types:nil 
                    modalForWindow:[_dictionary mainWindow] 
                     modalDelegate:self 
                    didEndSelector:@selector(fileSelected:returnCode:contextInfo:)
                       contextInfo:nil];
}

- (void) fileSelected:(NSOpenPanel *)oPanel 
           returnCode:(int)returnCode 
          contextInfo:(void *)contextInfo
{
*/
    if (returnCode != NSOKButton)
        return;
        
    _filesToOpen = [[oPanel filenames] retain];
    FOREACH (NSString *, filename, _filesToOpen) {
        OALog (@"File=%@", filename);
    } ENDFOREACH;
    
    [NSApp beginSheet:_panel
       modalForWindow:[_dictionary mainWindow]
        modalDelegate:self
       didEndSelector:@selector(importComplete:returnCode:contextInfo:)
          contextInfo:nil];
       
    // application will run modally now, returning to this point only when finished
}

- (IBAction) import:sender
{
    OALog (@"Import");
    
    _importParameters = [[NSArray alloc] initWithArray:[_importParametersController arrangedObjects]];

    // Validate what the user gave us:
    FOREACH (ImportParameter *, impparam, _importParameters) {
        if ([impparam language1] == nil ||
            [impparam language2] == nil)
        {
            [[NSAlert alertWithError:
                [NSError errorWithDomain:FLASHDOMAIN code:INVALIDLANG userInfo:[NSDictionary dictionaryWithObjectsAndKeys:
                    @"Language must be selected.", NSLocalizedDescriptionKey, 
                    @"Select a language by clicking on the appropriate column and row.", NSLocalizedRecoverySuggestionErrorKey,
                    [NSArray arrayWithObject:@"OK"], NSLocalizedRecoveryOptionsErrorKey,
                    nil]]] runModal];;
            return;
        }
        else if ([impparam relationship] == nil)
        {
            [[NSAlert alertWithError:
                [NSError errorWithDomain:FLASHDOMAIN code:INVALIDREL userInfo:[NSDictionary dictionaryWithObjectsAndKeys:
                    @"Relationship must be selected.", NSLocalizedDescriptionKey, 
                    @"Select a relationship by clicking on the appropriate column and row.", NSLocalizedRecoverySuggestionErrorKey,
                    [NSArray arrayWithObject:@"OK"], NSLocalizedRecoveryOptionsErrorKey,
                    nil]]] runModal];
            return;
        }
    } ENDFOREACH;
    
    _selectedEncoding = [[_encodingsController selectedObject] retain];

    [NSApp endSheet:_panel returnCode:1];
}

- (IBAction) dontImport:sender
{
    OALog (@"Don't Import");

    [NSApp endSheet:_panel returnCode:0];
}

- (void) importComplete:(NSOpenPanel *)sheet 
             returnCode:(int)shouldImport
            contextInfo:(void *)contextInfo
{
    [_panel orderOut:self];
    
    if (!shouldImport)
        return;
    
    /* Begin by opening each file and sucking in the data to create a big list of lines */
    _allData = [[NSMutableArray alloc] initWithCapacity:4096];    
    
    FOREACH (NSString *, filename, _filesToOpen) {
        NSError *error = nil;
        OALog (@"Loading lines from %@", filename);
            
        NSString *filestr = [NSString stringWithContentsOfFile:filename 
                                                      encoding:[_selectedEncoding encoding]
                                                         error:&error];
        if (!filestr) {
            assert (error != nil);
            [[NSAlert alertWithError:error] runModal];
            continue;
        }
        
        NSArray *lines = [filestr componentsSeparatedByString:@"\n"];
        [_allData addObjectsFromArray:lines];
    } ENDFOREACH;
            
    [OAWorkChunker startWorkBy:self 
                    workMethod:@selector(doImport:)
                completeMethod:@selector(imported)
                      maxCount:[_allData count]
                        prompt:@"Importing..."
                   allowCancel:NO]; // currently unsupported YES];
}

- (NSArray*) encodings
{
    return [OAEncoding encodings];
}

- (void) doImport:(OAWorkChunker*)workchunk
{
    int max = [workchunk index] + 10;
    if (max > [_allData count])
        max = [_allData count];
    for (int i = [workchunk index]; i < max; i++) {
        NSString *line = [_allData objectAtIndex:i];
        @try {
            OAIndent (@"Importing line #%d: %@", i, line);
            NSArray *columns = [line componentsSeparatedByString:_columnSeparator];
            FOREACH (ImportParameter *, impparam, _importParameters) {
                int idx1 = [[impparam column1] intValue]-1;
                int idx2 = [[impparam column2] intValue]-1;
                if (idx1 < [columns count] && idx2 < [columns count]) {
                    NSString *texts[2] = { 
                        [[columns objectAtIndex:idx1] strip],
                        [[columns objectAtIndex:idx2] strip]
                        };
                        
                    if ([texts[0] length] != 0 && [texts[1] length] != 0) {
                        NSManagedObject *langs[2] = { 
                            [impparam language1], 
                            [impparam language2] };
                        NSManagedObject *relationship = 
                            [impparam relationship];
                        OALog (@"Imp param: indx=%d,%d text=%@,%@ lang=%@,%@ rel=%@",
                               idx1, idx2, texts[0], texts[1], 
                               [langs[0] nameValue], [langs[1] nameValue], 
                               [relationship nameValue]);
                        [_dictionary createAndConnectWords:texts 
                                                 languages:langs
                                              relationship:relationship];
                    }
                }
            } ENDFOREACH;            
        } 
        @finally {
            OAUndent ();
        }
    } 
    
    [workchunk workCompleted:max-[workchunk index]];
    OALog (@"doImport complete");
}

- (void) imported
{

}

@end
