//
//  ViewController.m
//  Storing User Documents in iCloud
//
//  Created by Vandad Nahavandipoor on 10/09/2011.
//  Copyright (c) 2011 Pixolity Ltd. All rights reserved.
//

#import "ViewController.h"

@implementation ViewController
@synthesize cloudDocument;
@synthesize textViewCloudDocumentText;
@synthesize metadataQuery;

- (void)didReceiveMemoryWarning
{
  [super didReceiveMemoryWarning];
  // Usunięcie wszelkich buforowanych danych, obrazów itd., które nie są obecnie używane.
}

- (NSURL *) urlForDocumentsDirectoryIniCloud{
  
  NSURL *result = nil;
  
  /* Miejsce na Twój identyfikator Team ID. */
  NSString *teamID = @"TEAM ID";
  
  NSString *containerID = @"com.pixolity.Storing-User-Documents-in-iCloud";
  
  NSString *teamIDAndContainerID = [NSString stringWithFormat:@"%@.%@",
                                    teamID,
                                    containerID];
  
  NSFileManager *fileManager = [[NSFileManager alloc] init];
  
  NSURL *iCloudURL = [fileManager 
                      URLForUbiquityContainerIdentifier:teamIDAndContainerID];
  
  NSURL *documentsFolderURLIniCloud = 
  [iCloudURL URLByAppendingPathComponent:@"Documents"
                             isDirectory:YES];
  
  /* Jeżeli katalog nie istnieje, trzeba go utworzyć. */
  if ([fileManager fileExistsAtPath:[documentsFolderURLIniCloud path]] == NO){
    NSLog(@"Katalog Documents nie istnieje w usłudze iCloud. Tworzę katalog...");
    NSError *folderCreationError = nil;
    BOOL created = [fileManager createDirectoryAtURL:documentsFolderURLIniCloud
                         withIntermediateDirectories:YES
                                          attributes:nil
                                               error:&folderCreationError];
    
    if (created){
      NSLog(@"Udało się utworzyć katalog Documents w usłudze iCloud.");
      result = documentsFolderURLIniCloud;
    } else {
      NSLog(@"Nie udało się utworzyć katalogu Documents w usłudze iCloud. Błąd = %@",
            folderCreationError);
    }
  } else {
    NSLog(@"Katalog Documents już istnieje w usłudze iCloud.");
    result = documentsFolderURLIniCloud;
  }
  
  return result;
  
}

- (NSURL *) urlForFileInDocumentsDirectoryIniCloud{
  
  return [[self urlForDocumentsDirectoryIniCloud] 
          URLByAppendingPathComponent:@"UserDocument.txt"];
  
}

- (void) cloudDocumentChanged:(CloudDocument *)paramSender{
  self.textViewCloudDocumentText.text = paramSender.documentText;
}

- (void) textViewDidChange:(UITextView *)textView{
  self.cloudDocument.documentText = textView.text;
  [self.cloudDocument updateChangeCount:UIDocumentChangeDone];
}

- (void) listenForKeyboardNotifications{
  /* Ponieważ na ekranie jest widok tekstu, chcemy mieć pewność, że po wyświetleniu klawiatury
   użytkownik będzie widział całą zawartość widoku tekstu. Dlatego też rozpoczynamy
   nasłuchiwanie powiadomień generowanych przez klawiaturę. */
  [[NSNotificationCenter defaultCenter]
   addObserver:self
   selector:@selector(handleKeyboardWillShow:)
   name:UIKeyboardWillShowNotification
   object:nil];
  
  [[NSNotificationCenter defaultCenter] 
   addObserver:self
   selector:@selector(handleKeyboardWillHide:)
   name:UIKeyboardWillHideNotification
   object:nil];
}

- (void) setupTextView{
  /* Utworzenie widoku tekstu. */
  
  CGRect textViewRect = CGRectMake(20.0f,
                                   20.0f,
                                   self.view.bounds.size.width - 40.0f,
                                   self.view.bounds.size.height - 40.0f);
  
  self.textViewCloudDocumentText = [[UITextView alloc] initWithFrame:
                                    textViewRect];
  
  self.textViewCloudDocumentText.delegate = self;
  self.textViewCloudDocumentText.font = [UIFont systemFontOfSize:20.0f];
  [self.view addSubview:self.textViewCloudDocumentText];
}

- (void) startSearchingForDocumentIniCloud{
  /* Rozpoczęcie wyszukiwania istniejących dokumentów. */
  self.metadataQuery = [[NSMetadataQuery alloc] init];
  
  NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K like %@", 
                            NSMetadataItemFSNameKey, 
                            @"*"];
  
  [self.metadataQuery setPredicate:predicate];
  NSArray *searchScopes = [[NSArray alloc] initWithObjects:
                           NSMetadataQueryUbiquitousDocumentsScope,
                           nil];
  [self.metadataQuery setSearchScopes:searchScopes];
  
  NSString *metadataNotification = 
    NSMetadataQueryDidFinishGatheringNotification;
  
  [[NSNotificationCenter defaultCenter] 
   addObserver:self
   selector:@selector(handleMetadataQueryFinished:)
   name:metadataNotification
   object:nil];
  
  [self.metadataQuery startQuery];
}

- (void)viewDidLoad{
  [super viewDidLoad];
  [self listenForKeyboardNotifications];
  self.view.backgroundColor = [UIColor brownColor];
  [self setupTextView];
  [self startSearchingForDocumentIniCloud];
}

- (void)viewDidUnload
{
  [[NSNotificationCenter defaultCenter] removeObserver:self];
  [self setTextViewCloudDocumentText:nil];
  [self setMetadataQuery:nil];
  [super viewDidUnload];
}

- (void) handleMetadataQueryFinished:(NSNotification *)paramNotification{
  
  /* Upewniamy się, że to odpowiednie zapytanie metadanych... */
  NSMetadataQuery *senderQuery = (NSMetadataQuery *)[paramNotification object];
  
  if ([senderQuery isEqual:self.metadataQuery] == NO){
    NSLog(@"Wiadomość pochodzi od nieznanego zapytania metadanych.");
    return;
  }
  
  [self.metadataQuery disableUpdates];
    
  /* Zaprzestajemy nasłuchiwania powiadomień, ponieważ już ich nie potrzebujemy. */
  NSString *metadataNotification = 
    NSMetadataQueryDidFinishGatheringNotification;
  
  [[NSNotificationCenter defaultCenter] removeObserver:self
                                                  name:metadataNotification
                                                object:nil];
  [self.metadataQuery stopQuery];
  
  NSLog(@"Zapytanie metadanych zostało zakończone.");
  
  
  /* Sprawdzamy, czy ten dokument został już wcześniej utworzony w pamięci masowej
   usługi iCloud użytkownika. Jeśli tak, trzeba uniknąć jego nadpisania i po
   prostu użyć istniejącego dokumentu. */
  __block BOOL documentExistsIniCloud = NO;
  NSString *FileNameToLookFor = @"UserDocument.txt";
  
  NSArray *results = self.metadataQuery.results;
  
  [results enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    NSMetadataItem *item = (NSMetadataItem *)obj;
    NSURL *itemURL = (NSURL *)[item valueForAttribute:NSMetadataItemURLKey];
    NSString *lastComponent = (NSString *)[[itemURL pathComponents] lastObject];
    if ([lastComponent isEqualToString:FileNameToLookFor]){
      if ([itemURL isEqual:[self urlForFileInDocumentsDirectoryIniCloud]]){
        documentExistsIniCloud = YES;
        *stop = YES;
      }
    }
  }];
  
  NSURL *urlOfDocument = [self urlForFileInDocumentsDirectoryIniCloud];
  self.cloudDocument = [[CloudDocument alloc] initWithFileURL:urlOfDocument
                                                     delegate:self];
  
  __weak ViewController *weakSelf = self;
  
  /* Jeżeli dokument istnieje, należy go otworzyć. */
  if (documentExistsIniCloud){
    NSLog(@"Dokument już istnieje w usłudze iCloud. Wczytuję ten dokument...");
    [self.cloudDocument openWithCompletionHandler:^(BOOL success) {
      if (success){
        ViewController *strongSelf = weakSelf;
        NSLog(@"Udało się wczytać dokument z usługi iCloud.");
        strongSelf.textViewCloudDocumentText.text = 
          strongSelf.cloudDocument.documentText;
      } else {
        NSLog(@"Nie udało się wczytać dokumentu z usługi iCloud.");
      }
    }];
    
  } else {
    NSLog(@"Dokument nie istnieje w usłudze iCloud. Tworzę dokument...");
    
    /* Jeżeli dokument nie istnieje, klasa CloudDocument utworzy nowy dokument
      i umieści go pod podanym adresem URL. */
    [self.cloudDocument saveToURL:[self urlForFileInDocumentsDirectoryIniCloud]
                 forSaveOperation:UIDocumentSaveForCreating
                completionHandler:^(BOOL success) {
                  if (success){
                    NSLog(@"Udało się utworzyć nowy plik w usłudze iCloud.");
                    ViewController *strongSelf = weakSelf;
                    
                    strongSelf.textViewCloudDocumentText.text = 
                      strongSelf.cloudDocument.documentText;
                    
                  } else {
                    NSLog(@"Nie udało się utworzyć pliku.");
                  }
                }];
    
  }
  
}



- (void) handleKeyboardWillShow:(NSNotification *)paramNotification{
  
  NSDictionary *userInfo = [paramNotification userInfo];
  
  NSValue *animationCurveObject = 
  [userInfo valueForKey:UIKeyboardAnimationCurveUserInfoKey];
  
  NSValue *animationDurationObject =
  [userInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey];
  
  NSValue *keyboardEndRectObject = 
  [userInfo valueForKey:UIKeyboardFrameEndUserInfoKey];
  
  NSUInteger animationCurve = 0;
  double animationDuration = 0.0f;
  CGRect keyboardEndRect = CGRectMake(0, 0, 0, 0);
  
  [animationCurveObject getValue:&animationCurve];
  [animationDurationObject getValue:&animationDuration];
  [keyboardEndRectObject getValue:&keyboardEndRect];
  
  UIWindow *window = [[[UIApplication sharedApplication] delegate] window];
  
  /* Konwersja ramki z systemu współrzędnych okna na system współrzędnych widoku. */
  keyboardEndRect = [self.view convertRect:keyboardEndRect
                                  fromView:window];
  
  [UIView beginAnimations:@"changeTextViewContentInset"
                  context:NULL];
  [UIView setAnimationDuration:animationDuration];
  [UIView setAnimationCurve:(UIViewAnimationCurve)animationCurve];
  
  CGRect intersectionOfKeyboardRectAndWindowRect =
  CGRectIntersection(window.frame, keyboardEndRect);
  
  CGFloat bottomInset = intersectionOfKeyboardRectAndWindowRect.size.height;
  
  self.textViewCloudDocumentText.contentInset = UIEdgeInsetsMake(0.0f,
                                                                 0.0f,
                                                                 bottomInset,
                                                                 0.0f);
  
  [UIView commitAnimations];
  
}

- (void) handleKeyboardWillHide:(NSNotification *)paramNotification{
  
  if (UIEdgeInsetsEqualToEdgeInsets(self.textViewCloudDocumentText.contentInset, 
                                    UIEdgeInsetsZero)){
    /* Zawartość widoku tekstu pozostała nienaruszona, więc nie trzeba nic zmieniać. */
    return;
  }
  
  NSDictionary *userInfo = [paramNotification userInfo];
  
  NSValue *animationCurveObject = 
  [userInfo valueForKey:UIKeyboardAnimationCurveUserInfoKey];
  
  NSValue *animationDurationObject =
  [userInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey];
    
  NSUInteger animationCurve = 0;
  double animationDuration = 0.0f;
  
  [animationCurveObject getValue:&animationCurve];
  [animationDurationObject getValue:&animationDuration];
  
  [UIView beginAnimations:@"changeTextViewContentInset"
                  context:NULL];
  [UIView setAnimationDuration:animationDuration];
  [UIView setAnimationCurve:(UIViewAnimationCurve)animationCurve];
  
  self.textViewCloudDocumentText.contentInset = UIEdgeInsetsZero;
  
  [UIView commitAnimations];
  
}

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

@end
