OSDN Git Service

AppDelegateからウインドウに関する部分を分離した
[kcd/KCD.git] / KCD / NyukyoDockStatus.swift
1 //
2 //  NyukyoDockStatus.swift
3 //  KCD
4 //
5 //  Created by Hori,Masaki on 2017/01/23.
6 //  Copyright © 2017年 Hori,Masaki. All rights reserved.
7 //
8
9 import Cocoa
10
11 fileprivate enum DockState: Int {
12     case empty = 0
13     case hasShip = 1
14 }
15
16 class NyukyoDockStatus: NSObject {
17     private let number: Int
18     private let controller: NSArrayController
19     private var didNotify = false
20     private var realTime: TimeInterval = 0.0 {
21         didSet { time = realTime as NSNumber }
22     }
23     dynamic var name: String?
24     dynamic var time: NSNumber?
25     dynamic var state: NSNumber? {
26         didSet { updateState() }
27     }
28     dynamic var shipId: NSNumber? {
29         didSet { updateState() }
30     }
31     dynamic var completeTime: NSNumber?
32     
33     init?(number: Int) {
34         guard 1...4 ~= number else { return nil }
35         self.number = number
36         controller = NSArrayController()
37         super.init()
38         controller.managedObjectContext = ServerDataStore.default.context
39         controller.entityName = NyukyoDock.entityName
40         controller.fetchPredicate = NSPredicate(format: "id = %ld", number)
41         controller.automaticallyRearrangesObjects = true
42         controller.fetch(nil)
43         
44         bind(#keyPath(state), to: controller, withKeyPath: "selection.state")
45         bind(#keyPath(shipId), to: controller, withKeyPath: "selection.ship_id")
46         bind(#keyPath(completeTime), to: controller, withKeyPath: "selection.complete_time")
47     }
48     deinit {
49         unbind(#keyPath(state))
50         unbind(#keyPath(shipId))
51         unbind(#keyPath(completeTime))
52     }
53     
54     private func updateState() {
55         guard let state = state as? Int,
56             let stat = DockState(rawValue: state)
57             else { return print("unknown State") }
58         if stat == .empty {
59             didNotify = false
60             name = nil
61             time = nil
62             return
63         }
64         
65         guard let shipId = shipId as? Int,
66             shipId != 0
67             else { return }
68         guard let ship = ServerDataStore.default.ship(by: shipId)
69             else {
70                 name = "Unknown"
71                 DispatchQueue(label: "NyukyoDockStatus")
72                     .asyncAfter(deadline: .now() + 0.33) {
73                         self.updateState()
74                 }
75                 return
76         }
77         name = ship.name
78     }
79     
80     func update() {
81         guard let name = name else {
82             time = nil
83             return
84         }
85         guard let completeTime = completeTime as? Int
86             else {
87                 self.name = nil
88                 time = nil
89                 return
90         }
91         let compTime = TimeInterval(Int(completeTime / 1_000))
92         let diff = compTime - Date().timeIntervalSince1970
93         
94         realTime = diff < 0 ? 0 : diff
95         
96         if didNotify { return }
97         if diff >= 1 * 60 { return }
98         
99         let notification = NSUserNotification()
100         let format = NSLocalizedString("%@ Will Finish Docking.", comment: "%@ Will Finish Docking.")
101         notification.title = String(format: format, name)
102         notification.informativeText = notification.title
103         if UserDefaults.standard.playFinishNyukyoSound {
104             notification.soundName = NSUserNotificationDefaultSoundName
105         }
106         NSUserNotificationCenter.default.deliver(notification)
107         didNotify = true
108     }
109 }