Untitled

mail@pastecode.io avatar
unknown
kotlin
2 months ago
5.7 kB
2
Indexable
Never
package com.example.projektmunka.logic

import android.annotation.SuppressLint
import android.location.Location
import com.example.projektmunka.data.Node
import com.example.projektmunka.data.Route
import com.example.projektmunka.utils.Constants.TIMER_INTERVAL
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import java.util.Timer
import java.util.TimerTask

@SuppressLint("MissingPermission")
class UserRouteTracker(
    private val locationTracker: LocationTracker,
    private val fitnessCalculator: FitnessCalculator,
    private val stepCounter: StepCounter,
) {

    private var isTracking = false
    private var startTime: Long? = null
    private var endTime: Long? = null
    private var timer: Timer? = null
    private var elapsedTime: Long = 0


    private val _locationList = MutableStateFlow(mutableListOf<Location?>())
    val locationList = _locationList.asStateFlow()

    private val _lastLocation = MutableStateFlow<Location?>(null)
    val lastLocation = _lastLocation.asStateFlow()

    private val _distanceTravelled = MutableStateFlow(0.0)
    val distanceTravelled = _distanceTravelled.asStateFlow()

    private val _averageSpeed = MutableStateFlow(0.0)
    val averageSpeed = _averageSpeed.asStateFlow()

    private val _stepsTaken = MutableStateFlow(0)
    val stepsTaken = _stepsTaken.asStateFlow()

    private val _calorieBurned = MutableStateFlow(0.0)
    val calorieBurned = _calorieBurned.asStateFlow()

    private val _heartRate = MutableStateFlow(0)
    val heartRate = _heartRate.asStateFlow()

    private val _averageHeartRate = MutableStateFlow(0.0)
    val averageHeartRate = _averageHeartRate.asStateFlow()

    private val _isSessionFinished = MutableStateFlow(false)
    val isSessionFinished = _isSessionFinished.asStateFlow()

    private val _generatedRoute = MutableStateFlow<Route?>(null)
    val generatedRoute = _generatedRoute.asStateFlow()

    private val _currentRoute = MutableStateFlow<Route?>(null)
    val currentRoute = _currentRoute.asStateFlow()

    private val _generatedRoutePOIs = MutableStateFlow<Route?>(null)
    val generatedRoutePois = _generatedRoutePOIs.asStateFlow()

    init {
        observeLocationData()
    }

    fun startTimer() {
        timer = Timer()
        timer?.scheduleAtFixedRate(object : TimerTask() {
            override fun run() {
                elapsedTime += TIMER_INTERVAL
            }
        }, 0, TIMER_INTERVAL.toLong())
    }

    fun stopTimer() {
        timer?.cancel()
        timer = null
    }

    suspend fun generateDiffRoute(
        routeGeneratorFunc: suspend () -> Route
    ) {
        if (!isTracking) {
            isTracking = true

            //útvonalgenerálás indítása
            val route = routeGeneratorFunc()
            _generatedRoute.emit(route)
        }
    }

    suspend fun generateCircularDiffRoute(routeGeneratorFunc: suspend () -> Pair<Route, Route>): Pair<Route, Route>? {

        var route: Pair<Route, Route>? = null
        if (!isTracking) {
            isTracking = true

            route = routeGeneratorFunc()
            _generatedRoute.emit(route.first)
            _generatedRoutePOIs.emit(route.second)

            //startSession()

            return route
        }
        return null
    }

    fun Node.toLocation(): Location {
        val location = Location("")
        location.latitude = this.lat
        location.longitude = this.lon
        return location
    }

    fun observeLocationData() {
        CoroutineScope(locationTracker.scope.coroutineContext).launch {
            locationTracker.currentLocation.collect { currentLocation ->
                if (currentLocation != null && currentLocation != _lastLocation.value) {
                    _lastLocation.value = currentLocation
                    _locationList.value = _locationList.value.toMutableList().apply {
                        add(currentLocation)

                    }
                }
                if (currentLocation != null) {
                    updateSessionData(currentLocation)
                }
            }
        }
    }

    fun startSession() {
        stepCounter.registerStepCounterListener()
        startTime = System.currentTimeMillis()
        startTimer()
    }

    fun stopSession() {
        if (isTracking) {
            isTracking = false
            //locationService.stopLocationUpdates()
            endTime = System.currentTimeMillis()
            stopTimer()
            stepCounter.unregisterStepCounterListener()
        }
    }

    private fun updateSessionData(currentLocation: Location) {
        CoroutineScope(Dispatchers.Default).launch {
            val distance =
                fitnessCalculator.calculateDistance(locationList.value) //a teljes eddig megtett út kell nekünk

            _distanceTravelled.emit(distance)
            _averageSpeed.emit(fitnessCalculator.calculateAverageSpeed(distance, elapsedTime))
            _stepsTaken.emit(stepCounter.getStepCount())
            _calorieBurned.emit(
                fitnessCalculator.calculateCaloriesBurned(
                    locationList.value,
                    (elapsedTime / 60000).toDouble()
                )
            )
        }
    }

    /*private fun saveUserRouteToDatabase(route: Route){
        userRouteRepository.saveUserRouteToDatabase(route)
    }*/
}
Leave a Comment