#import "MainViewController.h"
#import "RecipeDetailViewController.h"
#import "RecipeEntity.h"

@interface MainViewController() <NSFetchedResultsControllerDelegate>

@end

@implementation MainViewController

@synthesize resultsController;

//START:initWithFetchController
- (id)initWithFetchController:(NSFetchedResultsController*)controller
{
  if (!(self = [super initWithStyle:UITableViewStylePlain])) return nil;
  
  [self setResultsController:controller];
  [controller setDelegate:self];
  
  return self;
}
//END:initWithFetchController

- (void)viewDidLoad
{
  [super viewDidLoad];
  
  [self setTitle:@"Recipes"];
  
  [[self navigationItem] setLeftBarButtonItem:[self editButtonItem]];
  
  UIBarButtonItem *add = nil;
  add = [[UIBarButtonItem alloc] 
         initWithBarButtonSystemItem:UIBarButtonSystemItemAdd 
                              target:self 
                              action:@selector(addRecipe:)];
  [[self navigationItem] setRightBarButtonItem:add];
  [add release], add = nil;
}

- (void)dealloc
{
  [resultsController release], resultsController = nil;
  [super dealloc];
}

#pragma mark -
#pragma mark Add Recipe

- (void)addRecipe:(id)sender
{
  RecipeDetailViewController *controller = nil;
  controller = [[RecipeDetailViewController alloc] init];
  [[self navigationController] pushViewController:controller animated:YES];
  [controller release], controller = nil;
}

#pragma mark -
#pragma mark UITableview Delegate

- (void)tableView:(UITableView*)tableView 
didSelectRowAtIndexPath:(NSIndexPath*)indexPath
{
  RecipeDetailViewController *controller = nil;
  controller = [[RecipeDetailViewController alloc] init];
  [controller setRecipe:[[self resultsController] objectAtIndexPath:indexPath]];
  [[self navigationController] pushViewController:controller animated:YES];
  [controller release], controller = nil;
}

//START:numberOfSectionsInTableView
- (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView 
{
  return [[[self resultsController] sections] count];
}
//END:numberOfSectionsInTableView

//START:tableViewNumberOfRowsInSection
- (NSInteger)tableView:(UITableView*)table 
 numberOfRowsInSection:(NSInteger)section 
{
  id <NSFetchedResultsSectionInfo> sectionInfo = nil;
  sectionInfo = [[[self resultsController] sections] objectAtIndex:section];
  return [sectionInfo numberOfObjects];
}
//END:tableViewNumberOfRowsInSection

//START:updateCellFromRecipe
- (void)updateCell:(UITableViewCell*)cell fromRecipe:(RecipeEntity*)recipe
{
  [[cell textLabel] setText:[recipe name]];
  NSString *text = nil;
  text = [NSString stringWithFormat:@"Serves: %@", [recipe serves]];
  [[cell detailTextLabel] setText:text];
}
//END:updateCellFromRecipe

//START:tableViewCellForRowAtIndexPath
- (UITableViewCell*)tableView:(UITableView*)tableView 
        cellForRowAtIndexPath:(NSIndexPath*)indexPath 
{
  static NSString *cellIdentifier = @"cellIdentifier";
  UITableViewCell *cell = nil;
  cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
  if (!cell) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle 
                                   reuseIdentifier:cellIdentifier] autorelease];
    [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
  }
  [self updateCell:cell fromRecipe:[[self resultsController] 
                                    objectAtIndexPath:indexPath]];
  
  return cell;
}
//END:tableViewCellForRowAtIndexPath

- (NSString*)tableView:(UITableView*)tableView 
titleForHeaderInSection:(NSInteger)section 
{
  id <NSFetchedResultsSectionInfo> sectionInfo = nil;
  sectionInfo = [[[self resultsController] sections] objectAtIndex:section];
  return [sectionInfo name];
}

- (NSArray*)sectionIndexTitlesForTableView:(UITableView*)tableView 
{
  return [[self resultsController] sectionIndexTitles];
}

- (NSInteger)tableView:(UITableView*)tableView 
sectionForSectionIndexTitle:(NSString*)title 
               atIndex:(NSInteger)index 
{
  return [[self resultsController] sectionForSectionIndexTitle:title 
                                                       atIndex:index];
}

#pragma mark -
#pragma mark FetchController delegate

//START:controllerWillChangeContent
- (void)controllerWillChangeContent:(NSFetchedResultsController*)controller 
{
	[[self tableView] beginUpdates];
}
//END:controllerWillChangeContent

//START:controllerDidChangeObjectAtIndexPathForChangeTypeNewIndexPath
- (void)controller:(NSFetchedResultsController*)controller 
   didChangeObject:(id)anObject 
       atIndexPath:(NSIndexPath*)indexPath 
     forChangeType:(NSFetchedResultsChangeType)type 
      newIndexPath:(NSIndexPath*)newIndexPath 
{
  NSArray *array = nil;
  NSIndexSet *section = [NSIndexSet indexSetWithIndex:[newIndexPath section]];
  
	switch (type) {
		case NSFetchedResultsChangeInsert:
      array = [NSArray arrayWithObject:newIndexPath];
			[[self tableView] insertRowsAtIndexPaths:array 
                              withRowAnimation:UITableViewRowAnimationFade];
			break;
		case NSFetchedResultsChangeDelete:
      array = [NSArray arrayWithObject:indexPath];
			[[self tableView] deleteRowsAtIndexPaths:array
                              withRowAnimation:UITableViewRowAnimationFade];
			break;
		case NSFetchedResultsChangeMove:
      array = [NSArray arrayWithObject:newIndexPath];
			[[self tableView] deleteRowsAtIndexPaths:array
                              withRowAnimation:UITableViewRowAnimationFade];
			[[self tableView] reloadSections:section
                      withRowAnimation:UITableViewRowAnimationFade];
			break;
		case NSFetchedResultsChangeUpdate:
      [self updateCell:[[self tableView] cellForRowAtIndexPath:indexPath]
            fromRecipe:[[self resultsController] objectAtIndexPath:indexPath]];
			break;
	}
}
//END:controllerDidChangeObjectAtIndexPathForChangeTypeNewIndexPath

//START:controllerDidChangeSectionAtIndexForChangeType
- (void)controller:(NSFetchedResultsController*)controller 
  didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo 
           atIndex:(NSUInteger)sectionIndex 
     forChangeType:(NSFetchedResultsChangeType)type 
{
  NSIndexSet *sections = [NSIndexSet indexSetWithIndex:sectionIndex];
  
	switch (type) {
		case NSFetchedResultsChangeInsert:
			[[self tableView] insertSections:sections 
                      withRowAnimation:UITableViewRowAnimationFade];
			break;
		case NSFetchedResultsChangeDelete:
			[[self tableView] deleteSections:sections 
                      withRowAnimation:UITableViewRowAnimationFade];
			break;
	}
}
//END:controllerDidChangeSectionAtIndexForChangeType

//START:controllerDidChangeContent
- (void)controllerDidChangeContent:(NSFetchedResultsController*)controller 
{
	[[self tableView] endUpdates];
}
//END:controllerDidChangeContent

@end
