Garmin/app/src/main/java/eu/ztsh/garmin/data/GarminMapper.kt
2024-08-03 00:22:00 +02:00

153 lines
No EOL
4.8 KiB
Kotlin

package eu.ztsh.garmin.data
class GarminMapper {
companion object {
fun map(lanes: Lanes): IntArray {
return intArrayOf(0x02, lanes.lanes.lanes.sumOf { it.value }, lanes.outlines.lanes.sumOf { it.value })
}
fun map(direction: Direction): IntArray {
return toDirectionArray(direction.angle, direction.out, direction.roundabout)
}
fun map(distance: Distance): IntArray {
return setDistance(distance.distance, distance.unit)
}
fun map(speed: Speed): IntArray {
return setSpeed(speed.speed, speed.limit, speed.limit > 0 && speed.speed > speed.limit)
}
fun setTime(hours: Int, minutes: Int, traffic: Boolean = false, flag: Boolean = false): IntArray {
val trafficChar = asChar(traffic)
val flagChar = asChar(flag)
return if (hours > 99) {
intArrayOf(
0x05,
trafficChar,
asDigit(hours / 1000),
asDigit(hours / 100),
0x00,
asDigit(hours / 10),
asDigit(hours),
0xff,
flagChar
)
} else {
intArrayOf(
0x05,
trafficChar,
asDigit(hours / 10),
asDigit(hours),
0xff,
asDigit(minutes / 10),
asDigit(minutes),
0x00,
flagChar
)
}
}
fun speedControl(state: Boolean): IntArray {
return intArrayOf(0x04, if (state) 0x01 else 0x02)
}
fun cleanDistance(): IntArray {
return intArrayOf(0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
}
private fun toDirectionArray(
angle: OutAngle,
out: OutType = OutType.Lane,
roundabout: OutAngle = OutAngle.AsDirection
): IntArray {
val param1: Int = when (angle) {
OutAngle.LeftDown -> 0x10
OutAngle.RightDown -> 0x20
else -> out.value
}
val param2: Int = if (out == OutType.RightRoundabout
|| out == OutType.LeftRoundabout
) {
if (roundabout == OutAngle.AsDirection) angle.value else roundabout.value
} else {
0x00
}
val param3: Int =
if (angle == OutAngle.LeftDown || angle == OutAngle.RightDown) 0x00 else angle.value
return intArrayOf(0x01, param1, param2, param3)
}
private fun setDistance(distance: Double, unit: Unit = Unit.Any): IntArray {
val isDecimal = (distance * 10).toInt() != (distance.toInt() * 10)
val distanceValue = if (isDecimal) distance * 10 else distance
return intArrayOf(
0x03,
asDigit(distanceValue / 1000), // position 1
asDigit(distanceValue / 100), // position 2
asDigit(distanceValue / 10), // position 3
if (isDecimal) 0xff else 0x00, // comma
asDigit(distanceValue), // position 4
unit.value // unit
)
}
private fun setSpeed(
speed: Int,
limit: Int = 0,
limitWarning: Boolean = false,
acc: Boolean = false
): IntArray {
// TODO: car connection
val accChar = asChar(acc)
val limitWarningChar = asChar(limitWarning)
return if (limit > 0) {
intArrayOf(
0x06,
asDigit(speed / 100),
asDigit(speed / 10),
asDigit(speed),
0xff,
asDigit(limit / 100),
asDigit(limit / 10),
asDigit(limit),
limitWarningChar,
accChar
)
} else {
intArrayOf(
0x06,
0x00,
0x00,
0x00,
0x00,
asDigit(speed / 100),
asDigit(speed / 10),
asDigit(speed),
limitWarningChar,
accChar
)
}
}
private fun asDigit(n: Double): Int {
return asDigit(n.toInt())
}
private fun asDigit(n: Int): Int {
if (n == 0) {
return 0
}
val m = n % 10
return if (m == 0) 10 else m
}
private fun asChar(boolean: Boolean): Int {
return if (boolean) 0xff else 0x00
}
}
}