//
//  CountingOperation.m
//  Operations
//
//  Created by Vandad Nahavandipoor on 11-08-29.
//  Copyright 2011  All rights reserved.
//

#import "SimpleOperation.h"

@implementation SimpleOperation

NSObject      *givenObject;
BOOL          finished;
BOOL          executing;

- (id) init {
  NSNumber *dummyObject = [NSNumber numberWithInteger:123];
  return([self initWithObject:dummyObject]);
}

- (id) initWithObject:(NSObject *)paramObject{
  self = [super init];
  if (self != nil){
    /* To są wartości przeznaczone dla metody main. */
    givenObject = paramObject;
  }
  return(self);
}

- (void) start {
  
  /* W przypadku przerwania przed rozpoczęciem operacji
   trzeba natychmiast zakończyć działanie i wygenerować
   wymagane powiadomienia mechanizmu KVO. */
  if ([self isCancelled]){
    /* Operacja ZOSTAŁA przerwana. */
      /* Zapewnienie zgodności z KVO. */
    [self willChangeValueForKey:@"isFinished"];
    finished = YES;
    [self didChangeValueForKey:@"isFinished"];
    return;
    
  } else {
    /* Operacja NIE ZOSTAŁA przerwana. */
      /* Zapewnienie zgodności z KVO. */
    [self willChangeValueForKey:@"isExecuting"];
    executing = YES;
    /* Wywołanie metody main wewnątrz metody start. */
    [self didChangeValueForKey:@"isExecuting"];
    [self main];
  }
  
}

- (void) main {
  
  @try {
    @autoreleasepool {
      /* Zmienna lokalna, która po zakończeniu zadania powinna mieć przypisaną wartość YES. */
      BOOL taskIsFinished = NO;
      
      /* Utworzenie pętli while tylko wtedy, gdy zmienna
         taskIsFinished ma przypisaną wartość YES lub
         operacja została przerwana. */
      while (taskIsFinished == NO &&
             [self isCancelled] == NO){
        
        /* Wykonanie zadania. */
        NSLog(@"%s", __FUNCTION__);
        NSLog(@"Obiekt parametru = %@", givenObject);
        NSLog(@"Wątek główny = %@", [NSThread mainThread]);
        NSLog(@"Wątek bieżący = %@", [NSThread currentThread]);
        
        /* To bardzo ważne polecenie. Dzięki niemu możemy zakończyć pętlę
            i nadal stosować się do reguł przerwania operacji. */
        taskIsFinished = YES;
        
      }
      
      /* Zapewnienie zgodności z KVO. Wygenerowanie wymaganych powiadomień KVO. */
      [self willChangeValueForKey:@"isFinished"];
      [self willChangeValueForKey:@"isExecuting"];
      finished = YES;
      executing = NO;
      [self didChangeValueForKey:@"isFinished"];
      [self didChangeValueForKey:@"isExecuting"];
    }
  }
  @catch (NSException * e) {
    NSLog(@"Wyjątek %@", e);
  }
  
}

- (BOOL)  isConcurrent{
  return YES;
}

- (BOOL)  isFinished{
  /* Funkcja po prostu zwraca wartość. */
  return finished;
}

- (BOOL)  isExecuting{
  /* Funkcja po prostu zwraca wartość. */
  return executing;
}

@end