2 // StrengthenListViewController.swift
5 // Created by Hori,Masaki on 2016/12/25.
6 // Copyright © 2016年 Hori,Masaki. All rights reserved.
11 private let resourceName = "EnhancementListItem2"
12 private let resourceExtension = "plist"
15 private struct FilterCategories {
17 static let allType: [EquipmentType] = (1...100).flatMap { EquipmentType(rawValue: $0) }
18 static let canonType: [EquipmentType] = [.smallCaliberMainGun, .mediumCaliberMainGun,
19 .largeCaliberMainGun, .largeCaliberMainGunII]
20 static let torpedoType: [EquipmentType] = [.secondaryGun, .torpedo,
21 .antiAircraftGun, .antiSunmrinerSercher, .submarinTorpedo,
23 static let airplaneType: [EquipmentType] = [.fighter, .bomber, .attacker, .searcher,
24 .airplaneSearcher, .airplaneBomber,
25 .largeAirplane, .airplaneFighter,
26 .landAttecker, .localFighter,
27 .jetFighter, .jetBomber,
28 .jetAttacker, .jetSearcher,
30 static let radarType: [EquipmentType] = [.smallRadar, .largeRadar,
33 static let otherType: [EquipmentType] = {
35 .filter { !canonType.contains($0) }
36 .filter { !torpedoType.contains($0) }
37 .filter { !airplaneType.contains($0) }
38 .filter { !radarType.contains($0) }
41 enum FilterType: Int {
51 let categories: [EquipmentType]
53 init(type: FilterType) {
56 case .all: categories = FilterCategories.allType
57 case .canon: categories = FilterCategories.canonType
58 case .torpedo: categories = FilterCategories.torpedoType
59 case .airplane: categories = FilterCategories.airplaneType
60 case .radar: categories = FilterCategories.radarType
61 case .other: categories = FilterCategories.otherType
66 final class StrengthenListViewController: MainTabVIewItemViewController {
68 @IBOutlet private weak var tableView: NSTableView!
70 @objc dynamic var itemList: Any { return filteredItems as Any }
71 @objc dynamic var offsetDay: Int = 0 {
73 didSet { buildList() }
75 @objc dynamic var filterType: Int = 0 {
78 if let t = FilterCategories.FilterType(rawValue: filterType) {
80 showsTypes = FilterCategories(type: t).categories
84 showsTypes = FilterCategories.allType
90 override var nibName: NSNib.Name {
92 return .nibName(instanceOf: self)
95 private var filteredItems: [StrengthenListItem] = [] {
97 willSet { willChangeValue(forKey: #keyPath(itemList)) }
98 didSet { didChangeValue(forKey: #keyPath(itemList)) }
101 private let itemListBuildNotifier = PeriodicNotifier(hour: 0, minutes: 0)
102 private let plistDownloadNotifier = PeriodicNotifier(hour: 23, minutes: 55)
103 private let downloader = EnhancementListItemDownloader(name: resourceName, extension: resourceExtension)
104 private var equipmentStrengthenList: [EnhancementListItem] = []
105 private var showsTypes: [EquipmentType] = FilterCategories.allType
107 override func viewDidLoad() {
111 if let url = Bundle.main.url(forResource: resourceName, withExtension: resourceExtension),
112 let data = try? Data(contentsOf: url) {
114 guard let array = NSKeyedUnarchiver.unarchiveObject(with: data) as? [EnhancementListItem] else {
116 return Logger.shared.log("\(resourceName).\(resourceExtension) not found.")
119 equipmentStrengthenList = array
123 let nc = NotificationCenter.default
124 nc.addObserver(forName: .Periodic, object: itemListBuildNotifier, queue: nil) { [weak self] _ in
129 nc.addObserver(forName: .Periodic, object: plistDownloadNotifier, queue: nil) { [weak self] _ in
131 self?.downloadPList()
141 private func weekdayFiltered() -> [EnhancementListItem] {
143 if offsetDay == -1 { return allItemList() }
145 let currentDay = NSCalendar.current.dateComponents([.weekday], from: Date())
146 var targetWeekday = currentDay.weekday! + offsetDay
147 if targetWeekday > 7 { targetWeekday = 1 }
149 return equipmentStrengthenList.filter { $0.weekday == targetWeekday }
152 private func convert(items: [EnhancementListItem]) -> [StrengthenListItem] {
154 guard let item = items.first else { return [] }
156 let group: StrengthenListItem = StrengthenListGroupItem(type: item.equipmentType)
157 let items: [StrengthenListItem] = items.map(StrengthenListEnhancementItem.init(item:))
159 return [group] + items
162 private func buildList() {
164 let filtered = weekdayFiltered()
165 filteredItems = filtered
166 .map { $0.equipmentType }
168 .filter { showsTypes.contains($0) }
169 .map { type in filtered.filter { $0.equipmentType == type } }
173 private func downloadPList() {
175 downloader.download { [weak self] items in
177 DispatchQueue.main.async {
179 self?.equipmentStrengthenList = items
185 private func packSecondShipName(_ items: [EnhancementListItem]) -> [String] {
187 return items.flatMap { $0.secondsShipNames }.unique()
190 private func allItemList() -> [EnhancementListItem] {
192 return equipmentStrengthenList
193 .map { $0.identifier }
195 .map { identifier in equipmentStrengthenList.filter { $0.identifier == identifier } }
196 .flatMap { $0.first?.replace(secondsShipNames: packSecondShipName($0)) }
200 extension StrengthenListViewController: NSTableViewDelegate {
202 func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
204 let item = filteredItems[row]
205 return item.cellType.makeCellWithItem(item: item, tableView: tableView, owner: nil)
208 func tableView(_ tableView: NSTableView, isGroupRow row: Int) -> Bool {
210 return filteredItems[row] is StrengthenListGroupItem
213 func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
215 let item = filteredItems[row]
217 return item.cellType.estimateCellHeightForItem(item: item, tableView: tableView)