AnimalRating/app/src/main/java/com/example/animalrating/HomeActivity.kt

218 lines
9.6 KiB
Kotlin

package com.example.animalrating
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.view.View
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.ImageView
import android.widget.PopupMenu
import android.widget.SeekBar
import android.widget.Spinner
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.google.android.material.button.MaterialButton
class HomeActivity : AppCompatActivity() {
companion object {
const val ALGORITHM_HAMMING = "Hamming Distance"
const val ALGORITHM_EUCLIDEAN = "Euclidean Distance"
const val ALGORITHM_JACCARD = "Jaccard Similarity"
private const val PERMISSION_REQUEST_CODE = 101
private const val PREF_COW_ILLUSTRATION_INDEX = "COW_ILLUSTRATION_INDEX"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_home)
StringProvider.initialize(this)
setupUI()
checkAndRequestPermissions()
}
private fun checkAndRequestPermissions() {
val permissions = mutableListOf<String>()
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
permissions.add(android.Manifest.permission.CAMERA)
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
permissions.add(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
}
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
permissions.add(android.Manifest.permission.READ_EXTERNAL_STORAGE)
}
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_MEDIA_IMAGES) != PackageManager.PERMISSION_GRANTED) {
permissions.add(android.Manifest.permission.READ_MEDIA_IMAGES)
}
} else {
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
permissions.add(android.Manifest.permission.READ_EXTERNAL_STORAGE)
}
}
}
if (permissions.isNotEmpty()) {
ActivityCompat.requestPermissions(this, permissions.toTypedArray(), PERMISSION_REQUEST_CODE)
}
}
private fun setupUI() {
// Language Spinner
val languageSpinner = findViewById<Spinner>(R.id.spinnerLanguage)
val languages = StringProvider.getLanguages()
val languageAdapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, languages)
languageAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
languageSpinner.adapter = languageAdapter
val prefs = getSharedPreferences("AnimalRatingPrefs", MODE_PRIVATE)
val savedLang = prefs.getString("LANGUAGE", "English")
languageSpinner.setSelection(languages.indexOf(savedLang))
languageSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
val selectedLanguage = languages[position]
val currentLang = prefs.getString("LANGUAGE", "English")
// Only update and recreate if language actually changed
if (selectedLanguage != currentLang) {
saveSettings() // Save UI state so it's not lost
StringProvider.setLanguage(selectedLanguage, this@HomeActivity)
// Post recreate to avoid WindowLeaked (allows spinner popup to close)
android.os.Handler(android.os.Looper.getMainLooper()).post {
recreate()
}
}
}
override fun onNothingSelected(parent: AdapterView<*>?) {}
}
// Set text from StringProvider
findViewById<TextView>(R.id.tvTitle).text = StringProvider.getString("title_home")
findViewById<MaterialButton>(R.id.btnViewGallery).text = StringProvider.getString("btn_view_gallery")
findViewById<MaterialButton>(R.id.btnSelectCow).text = StringProvider.getString("btn_select_cow")
findViewById<TextView>(R.id.tvAlgorithmLabel).text = StringProvider.getString("label_algorithm")
findViewById<TextView>(R.id.tvThresholdLabel).text = StringProvider.getString("label_match_threshold")
// Cow Illustration and Logic
val ivCowIllustration = findViewById<ImageView>(R.id.ivCowIllustration)
val savedIndex = prefs.getInt(PREF_COW_ILLUSTRATION_INDEX, 0)
setCowIllustration(ivCowIllustration, savedIndex)
ivCowIllustration.setOnClickListener { view ->
showIllustrationPopup(view, ivCowIllustration)
}
// Navigation buttons
findViewById<MaterialButton>(R.id.btnViewGallery).setOnClickListener {
startActivity(Intent(this, GalleryActivity::class.java))
}
findViewById<MaterialButton>(R.id.btnSelectCow).setOnClickListener {
saveSettingsAndStart()
}
// Algorithm Spinner
val spinner = findViewById<Spinner>(R.id.spinnerAlgorithm)
val algorithms = listOf(ALGORITHM_HAMMING, ALGORITHM_EUCLIDEAN, ALGORITHM_JACCARD)
val adapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, algorithms)
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
spinner.adapter = adapter
// Set default selection from preferences or intent
val savedAlg = prefs.getString("ALGORITHM", ALGORITHM_HAMMING)
spinner.setSelection(algorithms.indexOf(savedAlg))
// Threshold SeekBar
val seekBar = findViewById<SeekBar>(R.id.seekBarThreshold)
val tvThreshold = findViewById<TextView>(R.id.tvThresholdValue)
val savedThreshold = prefs.getInt("THRESHOLD", 75)
seekBar.progress = savedThreshold
tvThreshold.text = "$savedThreshold%"
seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
tvThreshold.text = "$progress%"
}
override fun onStartTrackingTouch(seekBar: SeekBar?) {}
override fun onStopTrackingTouch(seekBar: SeekBar?) {}
})
}
private fun showIllustrationPopup(anchor: View, imageView: ImageView) {
val popup = PopupMenu(this, anchor)
for (i in 0..4) {
popup.menu.add(0, i, i, "Illustration $i")
}
popup.setOnMenuItemClickListener { item ->
val index = item.itemId
setCowIllustration(imageView, index)
// Save preference
getSharedPreferences("AnimalRatingPrefs", MODE_PRIVATE).edit()
.putInt(PREF_COW_ILLUSTRATION_INDEX, index)
.apply()
true
}
popup.show()
}
private fun setCowIllustration(imageView: ImageView, index: Int) {
// Map index to drawable resource
// We assume resources are named cow_illustration (for index 0 or default) or similar logic if strictly named
// But user said "cow_illustration_{n}, where n=0,1,2,3,4"
// However, currently we likely only have 'cow_illustration' in drawable from previous step, or user implies they exist.
// We will try to find resources dynamically.
val resName = "cow_illustration_$index"
val resId = resources.getIdentifier(resName, "drawable", packageName)
if (resId != 0) {
imageView.setImageResource(resId)
} else {
// Fallback to default if specific one not found
if (index == 0) {
// Maybe it's just "cow_illustration" without suffix if n=0 is base?
// Or user provided 5 distinct files. We try 'cow_illustration' as fallback.
val defaultId = resources.getIdentifier("cow_illustration", "drawable", packageName)
if (defaultId != 0) imageView.setImageResource(defaultId)
}
}
}
private fun saveSettings() {
val spinner = findViewById<Spinner>(R.id.spinnerAlgorithm)
val seekBar = findViewById<SeekBar>(R.id.seekBarThreshold)
if (spinner != null && seekBar != null) {
val selectedAlgorithm = spinner.selectedItem?.toString() ?: ALGORITHM_HAMMING
val threshold = seekBar.progress
// Save to preferences
val prefs = getSharedPreferences("AnimalRatingPrefs", MODE_PRIVATE)
prefs.edit().apply {
putString("ALGORITHM", selectedAlgorithm)
putInt("THRESHOLD", threshold)
apply()
}
}
}
private fun saveSettingsAndStart() {
saveSettings()
startActivity(Intent(this, CowSelectionActivity::class.java))
}
}