Files
Cable/Cable/Systems/SystemComponentsPersistence.swift
Stefan Lange-Hegermann a2314585ea added subscription booking
2025-10-28 22:43:41 +01:00

271 lines
8.5 KiB
Swift

import Foundation
import SwiftUI
import SwiftData
struct SystemComponentsPersistence {
static func createDefaultLoad(
for system: ElectricalSystem,
in context: ModelContext,
existingLoads: [SavedLoad],
existingBatteries: [SavedBattery],
existingChargers: [SavedCharger]
) -> SavedLoad {
let defaultName = String(
localized: "default.load.new",
comment: "Default name when creating a new load from system view"
)
let loadName = uniqueName(
startingWith: defaultName,
loads: existingLoads,
batteries: existingBatteries,
chargers: existingChargers
)
let newLoad = SavedLoad(
name: loadName,
voltage: 12.0,
current: 5.0,
power: 60.0,
length: 10.0,
crossSection: 1.0,
iconName: "lightbulb",
colorName: "blue",
isWattMode: false,
system: system,
remoteIconURLString: nil
)
context.insert(newLoad)
return newLoad
}
static func createLoad(
from item: ComponentLibraryItem,
for system: ElectricalSystem,
in context: ModelContext,
existingLoads: [SavedLoad],
existingBatteries: [SavedBattery],
existingChargers: [SavedCharger]
) -> SavedLoad {
let localizedName = item.localizedName
let baseName = localizedName.isEmpty ? "Library Load" : localizedName
let loadName = uniqueName(
startingWith: baseName,
loads: existingLoads,
batteries: existingBatteries,
chargers: existingChargers
)
let voltage = item.displayVoltage ?? 12.0
let power = item.watt ?? (item.current != nil ? item.current! * voltage : 0)
let current: Double
if let explicitCurrent = item.current {
current = explicitCurrent
} else if voltage > 0 {
current = power / voltage
} else {
current = 0
}
let affiliateLink = item.primaryAffiliateLink
let newLoad = SavedLoad(
name: loadName,
voltage: voltage,
current: current,
power: power,
length: 10.0,
crossSection: 1.0,
iconName: "lightbulb",
colorName: "blue",
isWattMode: item.watt != nil,
system: system,
remoteIconURLString: item.iconURL?.absoluteString,
affiliateURLString: affiliateLink?.url.absoluteString,
affiliateCountryCode: affiliateLink?.country
)
context.insert(newLoad)
return newLoad
}
static func makeBatteryDraft(
for system: ElectricalSystem,
existingLoads: [SavedLoad],
existingBatteries: [SavedBattery],
existingChargers: [SavedCharger]
) -> BatteryConfiguration {
let defaultName = NSLocalizedString(
"battery.editor.default_name",
bundle: .main,
value: "New Battery",
comment: "Default name when configuring a new battery"
)
let batteryName = uniqueName(
startingWith: defaultName,
loads: existingLoads,
batteries: existingBatteries,
chargers: existingChargers
)
return BatteryConfiguration(
name: batteryName,
iconName: "battery.100.bolt",
colorName: system.colorName,
system: system
)
}
static func makeChargerDraft(
for system: ElectricalSystem,
existingLoads: [SavedLoad],
existingBatteries: [SavedBattery],
existingChargers: [SavedCharger]
) -> ChargerConfiguration {
let defaultName = NSLocalizedString(
"charger.editor.default_name",
bundle: .main,
value: "New Charger",
comment: "Default name when configuring a new charger"
)
let chargerName = uniqueName(
startingWith: defaultName,
loads: existingLoads,
batteries: existingBatteries,
chargers: existingChargers
)
return ChargerConfiguration(
name: chargerName,
iconName: "bolt.fill",
colorName: system.colorName,
system: system
)
}
static func saveBattery(
_ configuration: BatteryConfiguration,
for system: ElectricalSystem,
existingBatteries: [SavedBattery],
in context: ModelContext
) {
if let existing = existingBatteries.first(where: { $0.id == configuration.id }) {
configuration.apply(to: existing)
} else {
let newBattery = SavedBattery(
id: configuration.id,
name: configuration.name,
nominalVoltage: configuration.nominalVoltage,
capacityAmpHours: configuration.capacityAmpHours,
chemistry: configuration.chemistry,
usableCapacityOverrideFraction: configuration.usableCapacityOverrideFraction,
chargeVoltage: configuration.chargeVoltage,
cutOffVoltage: configuration.cutOffVoltage,
minimumTemperatureCelsius: configuration.minimumTemperatureCelsius,
maximumTemperatureCelsius: configuration.maximumTemperatureCelsius,
iconName: configuration.iconName,
colorName: configuration.colorName,
system: system
)
context.insert(newBattery)
}
}
static func saveCharger(
_ configuration: ChargerConfiguration,
for system: ElectricalSystem,
existingChargers: [SavedCharger],
in context: ModelContext
) {
if let existing = existingChargers.first(where: { $0.id == configuration.id }) {
configuration.apply(to: existing)
} else {
let newCharger = SavedCharger(
id: configuration.id,
name: configuration.name,
inputVoltage: configuration.inputVoltage,
outputVoltage: configuration.outputVoltage,
maxCurrentAmps: configuration.maxCurrentAmps,
maxPowerWatts: configuration.maxPowerWatts,
iconName: configuration.iconName,
colorName: configuration.colorName,
system: system
)
context.insert(newCharger)
}
}
static func deleteBatteries(
at offsets: IndexSet,
from batteries: [SavedBattery],
in context: ModelContext
) {
for index in offsets {
context.delete(batteries[index])
}
}
static func deleteChargers(
at offsets: IndexSet,
from chargers: [SavedCharger],
in context: ModelContext
) {
for index in offsets {
context.delete(chargers[index])
}
}
static func uniqueName(
startingWith baseName: String,
loads: [SavedLoad],
batteries: [SavedBattery],
chargers: [SavedCharger]
) -> String {
let existingNames = Set(
loads.map { $0.name } +
batteries.map { $0.name } +
chargers.map { $0.name }
)
if !existingNames.contains(baseName) {
return baseName
}
var counter = 2
var candidate = "\(baseName) \(counter)"
while existingNames.contains(candidate) {
counter += 1
candidate = "\(baseName) \(counter)"
}
return candidate
}
static func createDefaultCharger(
for system: ElectricalSystem,
in context: ModelContext,
existingLoads: [SavedLoad],
existingBatteries: [SavedBattery],
existingChargers: [SavedCharger]
) -> SavedCharger {
let defaultName = String(
localized: "charger.default.new",
bundle: .main,
comment: "Default name when creating a new charger from system view"
)
let chargerName = uniqueName(
startingWith: defaultName,
loads: existingLoads,
batteries: existingBatteries,
chargers: existingChargers
)
let charger = SavedCharger(
name: chargerName,
inputVoltage: 230,
outputVoltage: 14.4,
maxCurrentAmps: 30,
iconName: "bolt.fill",
colorName: system.colorName,
system: system
)
context.insert(charger)
return charger
}
}