#import "MainViewController.h"
#import "TuneViewController.h"
#import "PlaylistViewController.h"
#import "AppDelegate.h"
#import "Tune.h"

#define kCellIdentifier @"com.jhlabs.Tunebook.TuneCellIdentifier"
#define kAddCellIdentifier @"com.jhlabs.Tunebook.AddTuneCellIdentifier"

#define kMaxTunesInSet 10

@implementation MainViewController

@synthesize listContent, filteredListContent, tableView, searchBar, choosingTunes;

#define TUNE_REORDERING 1

#if TARGET_IPAD
- (CGSize)contentSizeForViewInPopoverView {
  return CGSizeMake(320.0, 440.0);
}
#endif

- (void)dealloc {
	[[NSNotificationCenter defaultCenter] removeObserver:self];
	[tableView dealloc];
	[searchBar release];
	[listContent release];
	[filteredListContent release];

  [super dealloc];
}

-(void)awakeFromNib {
#if TARGET_IPAD
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(databaseChanged:) name:@"databaseChanged" object:nil]; 
#endif
}

-(void)viewDidLoad {
//#if TARGET_IPAD
	searchBar.autocorrectionType = UITextAutocorrectionTypeNo;
	searchBar.autocapitalizationType = UITextAutocapitalizationTypeNone;

  tableView.rowHeight = 36;
  tableView.scrollsToTop = YES;

  searchBar.userInteractionEnabled = YES;
  manageButton.enabled = playlist != nil;

  if ( playlist == nil || [playlist isEditable] )
    self.navigationItem.rightBarButtonItem = self.editButtonItem;
  else
    self.navigationItem.rightBarButtonItem = nil;
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(databaseChanged:) name:@"databaseChanged" object:nil]; 
//#endif
}

- (void)databaseChanged:(id)sender {
  if ( playlist )
    listContent = [playlist loadTunes];
  [self filterTunes];
#if SECTION_INDEX
  [self buildSectionIndex];
#endif
	[tableView reloadData];
}

- (void)setPlaylist:(Playlist *)p
{
  Playlist *old = playlist;
  playlist = p;
  [playlist retain];
  [old release];

#if !TARGET_IPAD
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(databaseChanged:) name:@"databaseChanged" object:nil]; 
#endif

  AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
  manageButton.enabled = YES;
  loading = NO;

	searchBar.autocorrectionType = UITextAutocorrectionTypeYes;
	searchBar.autocapitalizationType = UITextAutocapitalizationTypeAllCharacters;

  tableView.rowHeight = 36;
  tableView.scrollsToTop = YES;

  if ( playlist ) {
    listContent = [playlist loadTunes];

    searchBar.userInteractionEnabled = YES;
    manageButton.enabled = YES;
    loading = NO;

    self.navigationItem.title = playlist.name;
    if ( [playlist isEditable] )
      self.navigationItem.rightBarButtonItem = self.editButtonItem;
    else
      self.navigationItem.rightBarButtonItem = nil;
  } else {
    self.navigationItem.title = @"Tunes";

    listContent = appDelegate.tunes;
  }

  [filteredListContent release];
  filteredListContent = [[NSMutableArray alloc] initWithCapacity: [listContent count]];
  [filteredListContent addObjectsFromArray: listContent];
#if SECTION_INDEX
  [self buildSectionIndex];
#endif

//  searchBar.userInteractionEnabled = YES;
	[tableView reloadData];
}

- (Playlist *)playlist
{
  return playlist;
}

- (void)filterTunes
{
  [filteredListContent removeAllObjects];
  [filteredListContent addObjectsFromArray: listContent];
  int index = 0;
  for ( Tune* tune in listContent )
    tune.order = ++index;
}

- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
  [super setEditing:editing animated:animated];
  NSArray *indexPaths = [NSArray arrayWithObjects:
    [NSIndexPath indexPathForRow:0 inSection:0],
    nil
  ];
  [tableView beginUpdates];
  [tableView setEditing:editing animated:YES];
  if ( !playlist ) {
    if ( editing ) {
      // Show the placeholder rows
      [tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationTop];
    } else {
      // Hide the placeholder rows.
      [tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationTop];
    }
  } else
    [tableView reloadData];
  [tableView endUpdates];
  searchBar.userInteractionEnabled = !editing;
//  [searchBar setHidden:editing];
  self.navigationItem.title = playlist.name;
}

#pragma mark UIViewController delegate

- (void)viewWillAppear:(BOOL)animated
{
	NSIndexPath *tableSelection = [tableView indexPathForSelectedRow];
	[tableView deselectRowAtIndexPath:tableSelection animated:NO];
	[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES];
  if ( playlist && !playlist.saved )
    self.navigationItem.rightBarButtonItem = bookmarkButtonItem;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
  return YES;
}

- (BOOL)shouldAutorotate {
  return YES;
}

- (NSUInteger)supportedInterfaceOrientations {
  return UIInterfaceOrientationMaskAll;
}

#pragma mark UITableView delegate methods

- (void)tableView:(UITableView *)tv didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
	if ( [searchBar isFirstResponder] )
    [searchBar resignFirstResponder];
#if !TARGET_IPAD
  [tv deselectRowAtIndexPath:indexPath animated:YES];
#endif
  int row = indexPath.row;
  if ( playlist ) {
    if ( indexPath.row == 0 ) {
      NSMutableString* dots = [[NSMutableString alloc] init];
      Tune *tune = [[Tune alloc] init];
      tune.title = playlist.name;
      tune.key = @"D";
      tune.hydrated = YES;
      tune.temporary = YES;
      NSArray *tunes = [playlist loadTunes];
      int count = MIN( kMaxTunesInSet, [tunes count] );
      for ( int i = 0; i < count; i++ ) {
        Tune* t = [tunes objectAtIndex:i];
        [t hydrate];
        [dots appendString:[t dots]];
        [dots appendString:@"\n"];
        [t dehydrate];
      }
      [tunes release];
      tune.dots = dots;
      [dots release];
      AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
#if TARGET_IPAD
      [appDelegate.tuneViewController showTune:tune];
#else
      TuneViewController *controller = [[TuneViewController alloc] initWithTune:tune fromPlayList:nil];
      [appDelegate.navigationController pushViewController:controller animated:YES];
      [controller autorelease];
#endif
      [tune release];
      return;
    }
    row--;
  }
  Tune *tune = (Tune *)[filteredListContent objectAtIndex:row];
  if ( choosingTunes ) {
    tune.selected = !tune.selected;
    [tableView reloadData];
  } else {
    [tune hydrate];
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
#if TARGET_IPAD
    [appDelegate.tuneViewController showTune:tune fromPlayList:playlist];
#else
    TuneViewController *controller = [[TuneViewController alloc] initWithTune:tune fromPlayList:playlist];
    [appDelegate.navigationController pushViewController:controller animated:YES];
    [controller autorelease];
#endif
  }
}

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
  if ( playlist && indexPath.row == 0 && [filteredListContent count] == 0 )
    return nil;
  return indexPath;
}

#pragma mark UITableView data source methods

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
#if SECTION_INDEX
printf("sections %d\n", sectionCount);
  return sectionCount;
#endif
	return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
  if ( loading )
    return 0;
  int count = [filteredListContent count];
#if SECTION_INDEX
  count = sectionIndex[section+1] - sectionIndex[section];
printf(" rows %d %d\n", section, count);
#endif
  if ( self.editing || playlist )
    count++;
  return count;
}

#define ROW_HEIGHT 24
#define kTitleTag 1
#define kKeyTag 2
#define kTimeTag 3

- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
	UITableViewCell *cell;
  int row = indexPath.row;
  
  if ( (self.editing || playlist) && row == 0 ) {
    cell = [tableView dequeueReusableCellWithIdentifier:kAddCellIdentifier];

    if ( cell == nil ) {
      CGRect rect = CGRectMake(0.0, 0.0, [tableView bounds].size.width, ROW_HEIGHT);
      cell = [[[UITableViewCell alloc] initWithFrame:rect reuseIdentifier:kAddCellIdentifier] autorelease];
    }
  } else {
    cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier];
	
    if ( cell == nil )
      cell = [self tableviewCellWithReuseIdentifier:kCellIdentifier];
  }
	
#if SECTION_INDEX
  row += sectionIndex[indexPath.section];
#endif
  if ( self.editing || playlist )
    row--;
  if ( self.editing && row == -1 ) {
    cell.textLabel.text = playlist ? @"Add tunes" : @"Add new tune";
    cell.accessoryType = UITableViewCellAccessoryNone;
  } else if ( !self.editing && playlist && row == -1 ) {
    int count = [filteredListContent count];
    if ( count == 0 ) {
      cell.textLabel.text = [NSString stringWithFormat:@"No Tunes", count];
      cell.accessoryType = UITableViewCellAccessoryNone;
    } else if ( count <= kMaxTunesInSet ) {
      cell.textLabel.text = [NSString stringWithFormat:@"All %d Tunes", count];
      cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    } else {
      cell.textLabel.text = [NSString stringWithFormat:@"First %d Tunes (of %d)", kMaxTunesInSet, count];
      cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    }
    cell.textLabel.textColor = [UIColor darkGrayColor];
	} else {
    Tune *tune = (Tune *)[filteredListContent objectAtIndex:row];
    UILabel *label;
    label = (UILabel *)[cell viewWithTag:kTitleTag];
    label.text = tune.title;

    label = (UILabel *)[cell viewWithTag:kKeyTag];
    label.text = tune.key;
    if ( tune.timeSigDen != 0 )
      label.text = [NSString stringWithFormat:@"%d/%d %@", tune.timeSigNum, tune.timeSigDen, label.text];

    cell.textLabel.text = @"";
    if ( choosingTunes )
      cell.accessoryType = tune.selected ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
    else
      cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
  }

	return cell;
}

- (UITableViewCellEditingStyle)tableView:(UITableView *)tv editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
  if ( self.editing ) {
    if ( indexPath.row == 0 ) {
      return UITableViewCellEditingStyleInsert;
    } else {
      return UITableViewCellEditingStyleDelete;
    }
  }
  return playlist ? UITableViewCellEditingStyleNone : UITableViewCellEditingStyleDelete;
}

- (void)tableView:(UITableView *)tv commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
  if (editingStyle == UITableViewCellEditingStyleDelete) {
    int row = indexPath.row;
    if ( self.editing || playlist )
      row--;
    Tune *tune = (Tune *)[filteredListContent objectAtIndex:row];
    if ( playlist ) {
      [playlist removeTuneAtIndex:row];
    } else {
      AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
      [appDelegate removeTune:tune];
    }
    [filteredListContent removeObjectAtIndex:row];
#if SECTION_INDEX
    [self buildSectionIndex];
#endif
    [tv reloadData];
#if TARGET_IPAD
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    if ( appDelegate.tuneViewController.tune == tune )
      [appDelegate.tuneViewController showTune:nil];
#endif
  } else if (editingStyle == UITableViewCellEditingStyleInsert) {
    if ( playlist == NULL ) {
      Tune *tune = [[Tune alloc] init];
      tune.title = @"New Tune";
      tune.key = @"D";
      tune.dots = @"X: 1\nT: New Tune\nL: 1/8\nM:4/4\nK: D\n|";
      AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
#if TARGET_IPAD
      [appDelegate.tuneViewController showTune:tune];
      [appDelegate.tuneViewController editPressed:self];
#else
      TuneViewController *controller = [[TuneViewController alloc] initWithTune:tune];
      [appDelegate.navigationController pushViewController:controller animated:YES];
      [controller setEditing:YES];
      [controller autorelease];
#endif
      return;
    }
    MainViewController *controller = [[MainViewController alloc] initWithNibName:@"AddTunes" bundle:nil];
    controller.playlist = nil;
    controller.choosingTunes = playlist;
#if TARGET_IPAD
    controller.modalPresentationStyle = UIModalPresentationFormSheet;
#endif
    [self presentModalViewController:controller animated:YES];
    [tv reloadData];
	}
}

- (UITableViewCell *)tableviewCellWithReuseIdentifier:(NSString *)identifier {
	
  CGRect bounds = [tableView bounds];
	CGRect rect = CGRectMake(0.0, 0.0, bounds.size.width, ROW_HEIGHT);
	
	UITableViewCell *cell = [[[UITableViewCell alloc] initWithFrame:rect reuseIdentifier:identifier] autorelease];
	
	UILabel *label;
	
	rect = CGRectMake( 10, 3, bounds.size.width-32, 17 );
	label = [[UILabel alloc] initWithFrame:rect];
	label.tag = kTitleTag;
	label.font = [UIFont boldSystemFontOfSize:15];
  label.opaque = NO;
	label.adjustsFontSizeToFitWidth = NO;
	[cell.contentView addSubview:label];
	label.highlightedTextColor = [UIColor whiteColor];
	[label release];
	
	rect = CGRectMake( 10, 22, bounds.size.width-32, 10);
	label = [[UILabel alloc] initWithFrame:rect];
	label.tag = kKeyTag;
	label.font = [UIFont systemFontOfSize:12];
	label.adjustsFontSizeToFitWidth = NO;
  label.opaque = NO;
	[cell.contentView addSubview:label];
	label.highlightedTextColor = [UIColor whiteColor];
	[label release];
	return cell;
}

#if SECTION_INDEX
- (void)buildSectionIndex
{
  sectionCount = 0;
  unichar lastc = 0;
  int count = [filteredListContent count];
  for ( int i = 0; i < count; i++ ) {
    Tune *tune = (Tune *)[filteredListContent objectAtIndex:i];
    NSString* title = [tune title];
    unichar c = [title characterAtIndex:0];
    if ( c != lastc )
      if ( sectionCount < 25 )
        sectionIndex[sectionCount++] = i;
    lastc = c;
  }
  sectionIndex[sectionCount] = count;
}

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
  return [NSArray arrayWithObjects:UITableViewIndexSearch, @"A", @"B", @"C", @"D", @"E", @"F", @"G", @"H", @"I", @"J", @"K", @"L", @"M", @"O", @"P", @"M", @"P", @"Q", @"R", @"M", @"O", @"P", @"Q", @"R", @"S", @"T", @"U", @"V", @"W", @"X", @"Y", @"Z", nil];
}

- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{
  return index;
}
#endif

#if TUNE_REORDERING
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
  AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
  return appDelegate.tuneSortOrder == kSortTunesByOrder &&
    playlist != nil &&
    indexPath.row != 0 && indexPath.row <= [filteredListContent count] &&
    [listContent count] == [filteredListContent count];
}

- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
  // Check for moving to the placeholder row. If so, retarget to just below that row.
  if ( proposedDestinationIndexPath.row == 0 )
    return [NSIndexPath indexPathForRow:1 inSection:sourceIndexPath.section];

  return proposedDestinationIndexPath;
}

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
  if ( toIndexPath.row <= [listContent count] ) {
    id item = [[listContent objectAtIndex:fromIndexPath.row-1] retain];
    [listContent removeObjectAtIndex:fromIndexPath.row-1];
    [listContent insertObject:item atIndex:toIndexPath.row-1];
    [item release];
    [self filterTunes];
    [playlist updateSortOrder:listContent];
  }
}
#endif

- (void)searchBarTextDidBeginEditing:(UISearchBar *)bar
{
}

- (void)searchBarTextDidEndEditing:(UISearchBar *)bar
{
}

- (void)searchBar:(UISearchBar *)bar textDidChange:(NSString *)searchText
{
  AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
	[filteredListContent removeAllObjects];
  [appDelegate searchForTunes:searchText tunes:listContent results:filteredListContent];
#if SECTION_INDEX
  [self buildSectionIndex];
#endif
	[tableView reloadData];
}

- (void)searchBarCancelButtonClicked:(UISearchBar *)bar
{
	if ( bar.text.length > 0 ) {
    [self filterTunes];
	}
	
#if SECTION_INDEX
  [self buildSectionIndex];
#endif
	[tableView reloadData];

	[bar resignFirstResponder];
	bar.text = @"";
}

- (void)searchBarSearchButtonClicked:(UISearchBar *)bar
{
	[bar resignFirstResponder];
}

- (void)searchForDots:(NSString *)searchText
{
  AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
	[filteredListContent removeAllObjects];
  [appDelegate searchForDots:searchText tunes:listContent results:filteredListContent];
#if SECTION_INDEX
  [self buildSectionIndex];
#endif
	[tableView reloadData];
}

- (IBAction)donePressed:(id)sender
{
  AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
  [appDelegate startTransaction];
  for ( Tune *tune in listContent ) {
    if ( tune.selected )
      [choosingTunes addTune:tune];
    tune.selected = NO;
  }
  [appDelegate commitTransaction];
  [[NSNotificationCenter defaultCenter] postNotificationName:@"databaseChanged" object:self]; 
  [self dismissModalViewControllerAnimated:YES];
}

- (IBAction)cancelPressed:(id)sender
{
  for ( Tune *tune in listContent )
    tune.selected = NO;
  [self dismissModalViewControllerAnimated:YES];
}

- (IBAction)bookmarkPressed:(id)sender
{
  UIActionSheet *sheet = [[UIActionSheet alloc]
    initWithTitle:@"Create a smart tunebook with this search?"
    delegate:self
    cancelButtonTitle:@"Don't Create"
    destructiveButtonTitle:@"Create"
    otherButtonTitles:nil
  ];
  [sheet showInView:self.view];
}

#pragma mark UIActionSheetDelegate methods

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
  if ( buttonIndex == 0 ) {
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    [appDelegate addPlaylist:playlist];
  }
}

@end
