// // Cap.swift // CapCollector // // Created by Christoph on 19.11.18. // Copyright © 2018 CH. All rights reserved. // import Foundation import UIKit import CoreImage import SQLite struct Cap { // MARK: - Static constants static let sufficientImageCount = 10 static let imageWidth = 299 // New for XCode models, 227/229 for turicreate static let imageSize = CGSize(width: imageWidth, height: imageWidth) static let jpgQuality: CGFloat = 0.3 private static let mosaicColumns = 40 static let mosaicCellSize: CGFloat = 60 private static let mosaicRowHeight = mosaicCellSize * 0.866 private static let mosaicMargin = mosaicCellSize - mosaicRowHeight // MARK: - Variables /// The unique number of the cap let id: Int /// The name of the cap let name: String /// The name of the cap without special characters let cleanName: String /// The number of images existing for the cap let count: Int /// Indicate if the cap can be found by the recognition model let matched: Bool /// Indicate if the cap is present on the server let uploaded: Bool // MARK: Init init(name: String, id: Int) { self.id = id self.count = 1 self.name = name self.cleanName = "" self.matched = false self.uploaded = false } init(id: Int, name: String, count: Int) { self.id = id self.name = name self.count = count self.cleanName = name.clean self.matched = false self.uploaded = true } func renamed(to name: String) -> Cap { Cap(from: self, renamed: name) } init(from cap: Cap, renamed newName: String) { self.id = cap.id self.count = cap.count self.name = newName self.cleanName = newName.clean self.matched = cap.matched self.uploaded = cap.uploaded } // MARK: SQLite init(row: Row) { self.id = row[Cap.columnId] self.name = row[Cap.columnName] self.count = row[Cap.columnCount] self.cleanName = name.clean self.matched = row[Cap.columnMatched] self.uploaded = row[Cap.columnUploaded] } static let table = Table("data") static var createQuery: String { table.create(ifNotExists: true) { t in t.column(columnId, primaryKey: true) t.column(columnName) t.column(columnCount) t.column(columnMatched) t.column(columnUploaded) } } static let columnId = Expression("id") static let columnName = Expression("name") static let columnCount = Expression("count") static let columnMatched = Expression("matched") static let columnUploaded = Expression("uploaded") var insertQuery: Insert { return Cap.table.insert( Cap.columnId <- id, Cap.columnName <- name, Cap.columnCount <- count, Cap.columnMatched <- matched, Cap.columnUploaded <- uploaded) } // MARK: Display func matchLabelText(match: Float?, appIsUnlocked: Bool) -> String { if let match = match { let percent = Int((match * 100).rounded()) return String(format: "%d %%", arguments: [percent]) } guard matched else { return "📵" } guard appIsUnlocked, !hasSufficientImages else { return "" } return "⚠️" } func countLabelText(appIsUnlocked: Bool) -> String { guard appIsUnlocked else { return "\(id)" } guard count != 1 else { return "\(id) (1 image)" } return "\(id) (\(count) images)" } // MARK: Images var hasSufficientImages: Bool { count >= Cap.sufficientImageCount } static func thumbnail(for image: UIImage) -> UIImage { let len = GridViewController.len * 2 return image.resize(to: CGSize.init(width: len, height: len)) } } // MARK: - Protocol Hashable extension Cap: Hashable { static func == (lhs: Cap, rhs: Cap) -> Bool { return lhs.id == rhs.id } func hash(into hasher: inout Hasher) { hasher.combine(id) } } // MARK: - Protocol Logger extension Cap: Logger { } // MARK: - String extension extension String { var clean: String { return lowercased().replacingOccurrences(of: "[^a-z0-9 ]", with: "", options: .regularExpression) } } // MARK: - Int extension private extension Int { var isEven: Bool { return self % 2 == 0 } }