OSDN Git Service

改修工廠メニューをダウンロード後処理していなかったので修正
[kcd/KCD.git] / KCD / StrengthenListViewController.swift
1 //
2 //  StrengthenListViewController.swift
3 //  KCD
4 //
5 //  Created by Hori,Masaki on 2016/12/25.
6 //  Copyright © 2016年 Hori,Masaki. All rights reserved.
7 //
8
9 import Cocoa
10
11 fileprivate let resourceName = "EnhancementListItem2"
12 fileprivate let resourceExtension = "plist"
13
14 class StrengthenListViewController: MainTabVIewItemViewController {
15     override var nibName: String! {
16         return "StrengthenListViewController"
17     }
18     override func viewDidLoad() {
19         super.viewDidLoad()
20         
21         if let url = Bundle.main.url(forResource: resourceName, withExtension: resourceExtension) {
22             if let data = try? Data(contentsOf: url) {
23                 let a = NSKeyedUnarchiver.unarchiveObject(with: data)
24                 guard let array = a as? [EnhancementListItem] else {
25                     print("\(resourceName).\(resourceExtension) not found.")
26                     return
27                 }
28                 equipmentStrengthenList = array
29                 buildList()
30                 
31                 #if DEBUG
32                     //
33                 #else
34                     downloadPList()
35                 #endif
36             }
37         }
38         
39         let nc = NotificationCenter.default
40         nc.addObserver(forName: .Periodic, object: notifier, queue: nil) { [weak self] _ in
41             guard let `self` = self else { return }
42             self.buildList()
43         }
44         nc.addObserver(forName: .Periodic, object: plistDownloadNotifier, queue: nil) { [weak self] _ in
45             guard let `self` = self else { return }
46             self.downloadPList()
47         }
48     }
49         
50     @IBOutlet weak var tableView: NSTableView!
51     
52     private let downloader = EnhancementListItemDownloader()
53     private var equipmentStrengthenList: [EnhancementListItem] = []
54     dynamic var itemList: [EnhancementListItem] = []
55     dynamic var offsetDay: Int = 0 {
56         didSet { buildList() }
57     }
58     
59     private let notifier: PeriodicNotifier = PeriodicNotifier(hour: 0, minutes: 0)
60     private let plistDownloadNotifier = PeriodicNotifier(hour: 23, minutes: 55)
61     
62     private func allItemList() -> [EnhancementListItem] {
63         var allIdentifier: [String] = []
64         var dict: [String:EnhancementListItem] = [:]
65         equipmentStrengthenList.forEach {
66             var item = dict[$0.identifier]
67             if item == nil {
68                 item = $0.replace(weekday: 10)
69                 dict[$0.identifier] = item
70                 allIdentifier.append($0.identifier)
71             }
72             var secondShips = item?.secondsShipNames
73             secondShips?.append(contentsOf: $0.secondsShipNames)
74             secondShips?.uniqueInPlace()
75             dict[$0.identifier] = item?.replace(secondsShipNames: secondShips)
76         }
77         
78         return allIdentifier.flatMap { dict[$0] }
79     }
80     func buildList() {
81         var newList: [EnhancementListItem] = {
82             if offsetDay == -1 { return allItemList() }
83             
84             let currentDay = NSCalendar.current.dateComponents([.weekday], from: Date())
85             var targetWeekday = currentDay.weekday! + offsetDay
86             if targetWeekday > 7 { targetWeekday = 1 }
87             return equipmentStrengthenList.filter { $0.weekday == targetWeekday }
88         }()
89         
90         var type: EquipmentType = .unknown
91         let group: [(EquipmentType, Int)] = newList.enumerated().flatMap {
92             if type != $0.element.equipmentType {
93                 type = $0.element.equipmentType
94                 return (type, $0.offset)
95             }
96             return nil
97         }
98         let t = SlotItemEquipTypeTransformer()
99         let prototype = newList[0]
100         group.reversed().forEach {
101             let item = prototype.replace(identifier: t.transformedValue($0.0.rawValue) as! String?,
102                                          equipmentType: .unknown)
103             newList.insert(item, at: $0.1)
104         }
105         itemList = newList
106     }
107     func downloadPList() {
108         downloader.download { [weak self] (array) in
109             guard let `self` = self else { return }
110             DispatchQueue.main.async {
111                 self.equipmentStrengthenList = array
112                 self.buildList()
113             }
114         }
115     }
116 }
117
118 extension StrengthenListViewController: NSTableViewDelegate {
119     func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
120         let item = itemList[row]
121         let identifier = (item.equipmentType == .unknown) ? "GroupCell" : "ItemCell"
122         return tableView.make(withIdentifier: identifier, owner: nil)
123     }
124     func tableView(_ tableView: NSTableView, isGroupRow row: Int) -> Bool {
125         return (itemList[row].equipmentType == .unknown)
126     }
127     func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
128         return (itemList[row].equipmentType == .unknown) ? 23.0 : 103.0
129     }
130 }
131
132 fileprivate class EnhancementListItemDownloader: NSObject, URLSessionDownloadDelegate {
133     private var plistDownloadSession: URLSession!
134     private var plistDownloadQueue: OperationQueue!
135     private var plistDownloadTask: URLSessionDownloadTask?
136     private var finishOperation: (([EnhancementListItem]) -> Void)? = nil
137     
138     override init() {
139         super.init()
140         
141         plistDownloadQueue = OperationQueue()
142         plistDownloadQueue.name = "StrengthenListViewControllerPlistDownloadQueue"
143         plistDownloadQueue.maxConcurrentOperationCount = 1
144         plistDownloadQueue.qualityOfService = .background
145         let configuration = URLSessionConfiguration.default
146         plistDownloadSession = URLSession(configuration: configuration, delegate: self, delegateQueue: plistDownloadQueue)
147     }
148     
149     func download(using block: @escaping ([EnhancementListItem]) -> Void) {
150         if plistDownloadTask != nil { return }
151         guard let plistURL = URL(string: "http://git.osdn.jp/view?p=kcd/KCD.git;a=blob;f=KCD/\(resourceName).\(resourceExtension);hb=HEAD") else { return }
152         
153         finishOperation = block
154         plistDownloadTask = plistDownloadSession.downloadTask(with: plistURL)
155         plistDownloadTask?.resume()
156     }
157     
158     func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
159         guard let data = try? Data(contentsOf: location, options: []) else { return }
160         guard let list = NSKeyedUnarchiver.unarchiveObject(with: data as Data) as? [EnhancementListItem] else { return }
161         finishOperation?(list)
162     }
163     func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
164         plistDownloadTask = nil
165     }
166 }