//: Playground - noun: a place where people can play

import UIKit


// Przykład użycia powiadomień.
let NCNAME = "Nazwa powiadomienia"

class PostType {
    let nc = NotificationCenter.default
    
    func post() {
        nc.post(name: Notification.Name(rawValue: NCNAME), object: nil)
    }
}

class ObserverType {
    let nc = NotificationCenter.default
    
    init() {
        nc.addObserver(self, selector: #selector(receiveNotification(notification:)), name: Notification.Name(rawValue: NCNAME), object: nil)
    }
    
    @objc func receiveNotification(notification: Notification) {
        print("Otrzymano powiadomienie")
    }
}

var postType = PostType()
var observerType = ObserverType()
postType.post()


// Przykład typu obserwatora.
protocol ZombieObserverProtocol {
    func turnLeft()
    func turnRight()
    func seesUs()
}

class MyObserver: ZombieObserverProtocol {
    func turnLeft() {
        print("Zombi skręciło w lewo, więc my idziemy w prawo")
    }
    func turnRight() {
        print("Zombie skręciło w prawo, więc my idziemy w lewo")
    }
    func seesUs() {
        print("Zombi nas widzi, UCIEKAJ!!!!")
    }
}

struct Zombie {
    var observer: ZombieObserverProtocol
    
    func turnZombieLeft() {
        // Zombi skręciło w lewo.
        // Trzeba powiadomić obserwatora.
        observer.turnLeft()
    }
    func turnZombieRight() {
        // Zombi skręciło w prawo.
        // Trzeba powiadomić obserwatora.
        observer.turnRight()
    }
    func spotHuman() {
        // Zombi nas widzi.
        // Trzeba powiadomić obserwatora.
        observer.seesUs()
    }
}

var observer = MyObserver()
var zombie = Zombie(observer: observer)

zombie.turnZombieLeft()
zombie.spotHuman()


// Przykład obserwatora właściwości.
protocol PropertyObserverProtocol {
    func propertyChanged(propertyName: String, newValue: Any)
}

class MyObserverType: PropertyObserverProtocol {
    func propertyChanged(propertyName: String, newValue: Any) {
        print("----Zmiana----")
        print("Nazwa właściwości: \(propertyName)")
        print("Nowa wartość:  \(newValue)")
    }
}

struct PropertyObserver {
    var observer: PropertyObserverProtocol
    var property1: String {
        didSet{
            observer.propertyChanged(propertyName: "property1", newValue: property1)
        }
        willSet(newValue) {
            print("Zmiana właściwości")
        }
    }
}

var myObserver = MyObserverType()
var p = PropertyObserver(observer: myObserver, property1: "Początkowy ciąg tekstowy")
p.property1 = "Mój ciąg tekstowy"
