package com.dano.test1 import android.content.res.Configuration import android.net.ConnectivityManager import android.net.Network import android.net.NetworkCapabilities import android.net.NetworkRequest import android.os.Bundle import android.view.View import android.widget.EditText import android.widget.LinearLayout import android.widget.ProgressBar import android.widget.Toast import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import java.io.File class MainActivity : AppCompatActivity() { private lateinit var openingScreenHandler: HandlerOpeningScreen var isInQuestionnaire: Boolean = false var isFirstQuestionnairePage: Boolean = false private var progress: ProgressBar? = null // LIVE: Network-Callback (optional für Statusleiste) private var netCb: ConnectivityManager.NetworkCallback? = null // Wir kennen hier (vor dem OpeningScreen) noch keine Nutzerwahl → Deutsch als Startsprache. private val bootLanguageId: String get() = "GERMAN" private fun t(key: String): String = LanguageManager.getText(bootLanguageId, key) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // === Offline-Start ermöglichen === // Bedingung: gespeicherter User/Token UND lokale DB vorhanden -> direkt OpeningScreen val hasCreds = !TokenStore.getUsername(this).isNullOrBlank() && !TokenStore.getToken(this).isNullOrBlank() val hasDb = hasLocalDb() if (hasCreds && hasDb) { openingScreenHandler = HandlerOpeningScreen(this) openingScreenHandler.init() return } // Sonst: Login-Dialog -> Login -> DB (einmalig) laden -> OpeningScreen showLoginThenDownload() } /** Prüft, ob die lokale DB-Datei vorhanden ist. */ private fun hasLocalDb(): Boolean { val dbFile = getDatabasePath("questionnaire_database") return dbFile != null && dbFile.exists() && dbFile.length() > 0 } /** Zeigt den Login-Dialog an, führt Login aus und lädt danach einmalig die DB. */ private fun showLoginThenDownload() { val container = LinearLayout(this).apply { orientation = LinearLayout.VERTICAL setPadding(dp(20), dp(8), dp(20), 0) } val etUser = EditText(this).apply { hint = t("username_hint") setSingleLine() } val etPass = EditText(this).apply { hint = t("password_hint") setSingleLine() inputType = android.text.InputType.TYPE_CLASS_TEXT or android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD } container.addView(etUser) container.addView(etPass) val dialog = AlertDialog.Builder(this) .setTitle(t("login_required_title")) .setView(container) .setCancelable(false) .setPositiveButton(t("login_btn")) { _, _ -> val user = etUser.text.toString().trim() val pass = etPass.text.toString() if (user.isEmpty() || pass.isEmpty()) { Toast.makeText(this, t("please_username_password"), Toast.LENGTH_SHORT).show() showLoginThenDownload() return@setPositiveButton } showBusy(true) LoginManager.loginUserWithCredentials( context = this, username = user, password = pass, onSuccess = { token -> // Nach erfolgreichem Login: einmalig komplette DB ziehen DatabaseDownloader.downloadAndReplaceDatabase( context = this, token = token ) { ok -> showBusy(false) // Wenn Download fehlgeschlagen ist, aber evtl. schon eine DB lokal liegt, // lassen wir den Nutzer trotzdem weiterarbeiten (Offline). if (!ok && !hasLocalDb()) { Toast.makeText(this, t("download_failed_no_local_db"), Toast.LENGTH_LONG).show() // Zurück zum Login, damit man es erneut probieren kann showLoginThenDownload() return@downloadAndReplaceDatabase } if (!ok) { Toast.makeText(this, t("download_failed_use_offline"), Toast.LENGTH_LONG).show() } // Opening-Screen starten openingScreenHandler = HandlerOpeningScreen(this) openingScreenHandler.init() openingScreenHandler.refreshHeaderStatusLive() } }, onError = { msg -> showBusy(false) val txt = t("login_failed_with_reason").replace("{reason}", msg ?: "") Toast.makeText(this, txt, Toast.LENGTH_LONG).show() showLoginThenDownload() } ) } .setNegativeButton(t("exit_btn")) { _, _ -> finishAffinity() } .create() dialog.show() } private fun showBusy(show: Boolean) { if (show) { if (progress == null) { progress = ProgressBar(this).apply { isIndeterminate = true (window?.decorView as? android.view.ViewGroup)?.addView(this) } } progress?.visibility = View.VISIBLE } else { progress?.visibility = View.GONE } } private fun dp(v: Int): Int = (v * resources.displayMetrics.density).toInt() // --- LIVE NETZSTATUS (optional, für deine Status-Leiste) --- override fun onResume() { super.onResume() registerNetworkCallback() if (::openingScreenHandler.isInitialized && !isInQuestionnaire) { openingScreenHandler.refreshHeaderStatusLive() } } override fun onPause() { super.onPause() unregisterNetworkCallback() } private fun registerNetworkCallback() { if (netCb != null) return val cm = getSystemService(ConnectivityManager::class.java) val req = NetworkRequest.Builder() .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .build() netCb = object : ConnectivityManager.NetworkCallback() { override fun onAvailable(network: Network) { runOnUiThread { if (::openingScreenHandler.isInitialized && !isInQuestionnaire) { openingScreenHandler.refreshHeaderStatusLive() } } } override fun onLost(network: Network) { runOnUiThread { if (::openingScreenHandler.isInitialized && !isInQuestionnaire) { openingScreenHandler.refreshHeaderStatusLive() } } } override fun onCapabilitiesChanged(network: Network, caps: NetworkCapabilities) { runOnUiThread { if (::openingScreenHandler.isInitialized && !isInQuestionnaire) { openingScreenHandler.refreshHeaderStatusLive() } } } } cm.registerNetworkCallback(req, netCb!!) } private fun unregisterNetworkCallback() { val cb = netCb ?: return val cm = getSystemService(ConnectivityManager::class.java) cm.unregisterNetworkCallback(cb) netCb = null } // --- /LIVE NETZSTATUS --- override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) } fun startQuestionnaire(questionnaire: QuestionnaireBase<*>, languageID: String) { isInQuestionnaire = true isFirstQuestionnairePage = true questionnaire.attach(this, languageID) questionnaire.startQuestionnaire() } override fun onBackPressed() { if (!::openingScreenHandler.isInitialized || !openingScreenHandler.onBackPressed()) { super.onBackPressed() } } fun finishQuestionnaire() { isInQuestionnaire = false isFirstQuestionnairePage = false if (::openingScreenHandler.isInitialized) { openingScreenHandler.init() } } }