#import "AppDelegate.h"

@interface AppDelegate()

- (NSString*)applicationSupportFolder;

@end

@implementation AppDelegate

//START:addImageAction
- (IBAction)addImage:(id)sender
{
  id recipe = [[recipeArrayController selectedObjects] lastObject];
  if (!recipe) return;
  
  NSOpenPanel *openPanel = [NSOpenPanel openPanel];
  
  [openPanel setCanChooseDirectories:NO];
  [openPanel setCanCreateDirectories:NO];
  [openPanel setAllowsMultipleSelection:NO];
  
  SEL select = @selector(addImageSheetDidEnd:returnCode:contextInfo:);
  [openPanel beginSheetForDirectory:nil
                               file:nil
                     modalForWindow:window
                      modalDelegate:self
                     didEndSelector:select
                        contextInfo:recipe];
}
//END:addImageAction

//START:addImageCallback
- (void)addImageSheetDidEnd:(NSOpenPanel*)openPanel 
                 returnCode:(NSInteger)returnCode 
                contextInfo:(NSManagedObject*)recipe
{
  if (returnCode == NSCancelButton) return;
  NSString *path = [openPanel filename];
  
  //Build the path we want the file to be at
  NSString *destPath = [self applicationSupportFolder];
  NSString *guid = [[NSProcessInfo processInfo] globallyUniqueString];
  destPath = [destPath stringByAppendingPathComponent:guid];
  NSError *error = nil;
  [[NSFileManager defaultManager] copyItemAtPath:path
                                          toPath:destPath
                                           error:&error];
  if (error) {
    [NSApp presentError:error];
  }
  [recipe setValue:destPath forKey:@"imagePath"];
}
//END:addImageCallback

- (NSString *)applicationSupportFolder
{
  NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
  NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : NSTemporaryDirectory();
  return [basePath stringByAppendingPathComponent:@"GrokkingRecipes"];
}

//START:managedObjectModel
- (NSManagedObjectModel*)managedObjectModel
{
  if (managedObjectModel) return managedObjectModel;
  
  NSString *path = [[NSBundle mainBundle] pathForResource:@"DataModel"
                                                   ofType:@"mom"];
  NSAssert(path != nil, @"Unable to find DataModel in main bundle");
  if (!path) return nil;
  
  NSURL *url = [NSURL fileURLWithPath:path];
  managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:url];
  return managedObjectModel;
}
//END:managedObjectModel

//START:persistentStoreCoordinator
- (NSPersistentStoreCoordinator*)persistentStoreCoordinator;
{
  if (persistentStoreCoordinator) return persistentStoreCoordinator;
  
  NSString *filename = @"GrokkingRecipes.xml";
  NSFileManager *fileManager = [NSFileManager defaultManager];
  NSString *path = [self applicationSupportFolder];
  if ( ![fileManager fileExistsAtPath:path
                          isDirectory:NULL] ) {
    [fileManager createDirectoryAtPath:path
                            attributes:nil];
  }
  
  path = [path stringByAppendingPathComponent:filename];
  NSURL *url = [NSURL fileURLWithPath:path];
  NSManagedObjectModel *mom = [self managedObjectModel];
  persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] 
                                initWithManagedObjectModel:mom];
  
  NSError *error = nil;
  if (![persistentStoreCoordinator addPersistentStoreWithType:NSXMLStoreType
                                                configuration:nil 
                                                          URL:url 
                                                      options:nil 
                                                        error:&error]) {
    [NSApp presentError:error];
  }
  return persistentStoreCoordinator;
}
//END:persistentStoreCoordinator

//START:managedObjectContext
- (NSManagedObjectContext*)managedObjectContext
{
  if (managedObjectContext) return managedObjectContext;
  
  NSPersistentStoreCoordinator *coord = [self persistentStoreCoordinator];
  
  if (!coord) return nil;
  
  managedObjectContext = [[NSManagedObjectContext alloc] init];
  [managedObjectContext setPersistentStoreCoordinator: coord];
  
  NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
  [request setEntity:[NSEntityDescription entityForName:@"Type"
                                 inManagedObjectContext:managedObjectContext]];
  
  NSError *error = nil;
  NSArray *result = [managedObjectContext executeFetchRequest:request 
                                                        error:&error];
  NSAssert(error == nil, [error localizedDescription]);
  if ([result count]) return managedObjectContext;
  
  //The types table has not been populated
  NSArray *types;
  types = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"RecipeTypes"];
  
  for (NSString *type in types) {
    NSManagedObject *object = [NSEntityDescription 
                               insertNewObjectForEntityForName:@"Type" 
                               inManagedObjectContext:managedObjectContext];
    [object setValue:type forKey:@"name"];
  }
  
  return managedObjectContext;
}
//END:managedObjectContext

- (NSUndoManager *)windowWillReturnUndoManager:(NSWindow *)window 
{
  return [[self managedObjectContext] undoManager];
}

//START:retrieveBigMeals
- (NSArray*)retrieveBigMeals
{
  NSManagedObjectContext *moc = [self managedObjectContext];
  NSManagedObjectModel *mom = [self managedObjectModel];
  NSFetchRequest *request = [mom fetchRequestTemplateForName:@"bigMeals"];
  NSError *error = nil;
  NSArray *result = [moc executeFetchRequest:request error:&error];
  if (error) {
    [NSApp presentError:error];
    return nil;
  }
  return result;
}
//END:retrieveBigMeals

//START:allRecipesSortedByName
- (NSArray*)allRecipesSortedByName
{
  NSSortDescriptor *nameSort = [[NSSortDescriptor alloc] initWithKey:@"name"
                                                           ascending:YES];
  NSArray *sorters = [NSArray arrayWithObject:nameSort];
  [nameSort release], nameSort = nil;
  
  NSManagedObjectContext *moc = [self managedObjectContext];
  NSFetchRequest *request = [[NSFetchRequest alloc] init];
  [request setSortDescriptors:sorters];
  [request setEntity:[NSEntityDescription entityForName:@"Recipe"
                                 inManagedObjectContext:moc]];
  NSError *error = nil;
  NSArray *result = [moc executeFetchRequest:request 
                                       error:&error];
  [request release], request = nil;
  if (error) {
    [NSApp presentError:error];
    return nil;
  }
  return result;
}
//END:allRecipesSortedByName

- (IBAction)saveAction:(id)sender 
{
  NSError *error = nil;
  if (![[self managedObjectContext] save:&error]) {
    [[NSApplication sharedApplication] presentError:error];
  }
}

- (NSApplicationTerminateReply)applicationShouldTerminate:(id)sender
{
  NSError *error = nil;
  
  if (!managedObjectContext) return NSTerminateNow;
  if (![managedObjectContext commitEditing]) {
    //Failed to commit editing.
    return NSTerminateCancel;
  }
  if (![managedObjectContext hasChanges]) return NSTerminateNow;
  if (![managedObjectContext save:&error]) {
    int alertReturn = NSRunAlertPanel(nil, @"Could not save changes while quitting. Quit anyway?" , @"Quit anyway", @"Cancel", nil);
    if (alertReturn == NSAlertAlternateReturn) NSTerminateCancel; 
  }
  return NSTerminateNow;
}

- (void) dealloc 
{
  [managedObjectContext release], managedObjectContext = nil;
  [persistentStoreCoordinator release], persistentStoreCoordinator = nil;
  [managedObjectModel release], managedObjectModel = nil;
  [super dealloc];
}

@end
