OSDN Git Service

b8ad937946c8bbd2d6c3cfed5fa8821355afb812
[kcd/KCD.git] / KCD / MissionStatus.swift
1
2 //
3 //  MissionStatus.swift
4 //  KCD
5 //
6 //  Created by Hori,Masaki on 2017/01/23.
7 //  Copyright © 2017年 Hori,Masaki. All rights reserved.
8 //
9
10 import Cocoa
11
12 fileprivate enum State: Int {
13     case none = 0
14     case hasMission = 1
15     case finish = 2
16     case earlyReturn = 3
17 }
18
19 class MissionStatus: NSObject {
20     private let number: Int
21     private let controller: NSArrayController
22     private var didNotify = false
23     private var realTime: TimeInterval = 0.0 {
24         didSet { time = realTime as NSNumber }
25     }
26     dynamic var name: String?
27     dynamic var time: NSNumber?
28     dynamic var state: NSNumber?
29     dynamic var missionId: NSNumber? {
30         didSet { updateState() }
31     }
32     
33     init?(number: Int) {
34         guard (2...4).contains(number) else { return nil }
35         self.number = number
36         controller = NSArrayController()
37         super.init()
38         controller.managedObjectContext = ServerDataStore.default.managedObjectContext
39         controller.entityName = Deck.entityName
40         controller.fetchPredicate = NSPredicate(format: "id = %ld", number)
41         controller.automaticallyRearrangesObjects = true
42         controller.fetch(nil)
43         
44         bind("state", to: controller, withKeyPath: "selection.mission_0")
45         bind("missionId", to: controller, withKeyPath: "selection.mission_1")
46     }
47     
48     private func updateState() {
49         guard let state = state as? Int,
50             let stat = State(rawValue: state)
51             else { return print("unknown State") }
52         if stat == .none || stat == .finish  {
53             if stat == .none { didNotify = false }
54             name = nil
55             time = nil
56             return
57         }
58         
59         guard let missionId = self.missionId as? Int
60             else { return }
61         guard let mission = ServerDataStore.default.masterMission(by: missionId)
62             else {
63                 name = "Unknown"
64                 DispatchQueue(label: "MissionStatus")
65                     .asyncAfter(deadline: .now() + 0.33) {
66                         self.updateState()
67                 }
68                 return
69         }
70         name = mission.name
71     }
72     
73     func update() {
74         if name == nil {
75             time = nil
76             return
77         }
78         guard let t = controller.value(forKeyPath: "selection.mission_2") as? Int
79             else {
80                 name = nil
81                 time = nil
82                 return
83         }
84         let compTime = TimeInterval(Int(t / 1_000))
85         let now = Date()
86         let diff = compTime - now.timeIntervalSince1970
87         
88         if diff < 0 { realTime = 0 }
89         else { realTime = diff }
90         
91         if didNotify { return }
92         if diff >= 1 * 60 { return }
93         
94         guard let fleetName = controller.value(forKeyPath: "selection.name") as? String
95             else { return }
96         let notification = NSUserNotification()
97         let format = NSLocalizedString("%@ Will Return From Mission.", comment: "%@ Will Return From Mission.")
98         notification.title = String(format: format, fleetName)
99         let txtFormat = NSLocalizedString("%@ Will Return From %@.", comment: "%@ Will Return From %@.")
100         notification.informativeText = String(format: txtFormat, fleetName, name!)
101         if UserDefaults.standard.playFinishMissionSound {
102             notification.soundName = NSUserNotificationDefaultSoundName
103         }
104         NSUserNotificationCenter.default.deliver(notification)
105         didNotify = true
106     }
107 }