package com.taf.attendance import android.app.DatePickerDialog import android.os.Bundle import android.widget.ArrayAdapter import android.widget.ListView import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.lifecycleScope import com.prolificinteractive.materialcalendarview.CalendarDay import com.prolificinteractive.materialcalendarview.MaterialCalendarView import androidx.core.content.ContextCompat import com.taf.attendance.decorators.RangeDayDecorator import com.taf.attendance.data.AttendanceRepository import com.taf.attendance.model.AttendanceRecord import kotlinx.coroutines.launch import java.text.DateFormat import java.util.Calendar import java.util.Date class HoursActivity : AppCompatActivity() { private lateinit var repo: AttendanceRepository private lateinit var calendar: MaterialCalendarView private var rangeStart: Long = 0L private var rangeEnd: Long = 0L private var rangeDecorator: RangeDayDecorator? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_hours) repo = AttendanceRepository(this) calendar = findViewById(R.id.calendarView) val details = findViewById(R.id.detailsList) val totalText = findViewById(R.id.totalText) // allow selecting a single day directly from the calendar calendar.selectionMode = MaterialCalendarView.SELECTION_MODE_SINGLE // show and select today by default val today = Calendar.getInstance() calendar.selectedDate = CalendarDay.from(today) updateDay(today.timeInMillis, details, totalText) calendar.setOnDateChangedListener { _, date, _ -> val cal = Calendar.getInstance() cal.set(date.year, date.month - 1, date.day, 0, 0, 0) updateDay(cal.timeInMillis, details, totalText) } findViewById(R.id.startPicker).setOnClickListener { showDatePicker { date -> rangeStart = date updateRange(totalText) updateCalendarRange() } } findViewById(R.id.endPicker).setOnClickListener { showDatePicker { date -> rangeEnd = date updateRange(totalText) updateCalendarRange() } } } private fun showDatePicker(onDate: (Long) -> Unit) { val now = Calendar.getInstance() DatePickerDialog(this, { _, y, m, d -> val cal = Calendar.getInstance() cal.set(y, m, d, 0, 0, 0) onDate(cal.timeInMillis) }, now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DAY_OF_MONTH)).show() } private fun updateDay(dayStart: Long, list: ListView, text: TextView) { val cal = Calendar.getInstance() cal.timeInMillis = dayStart cal.set(Calendar.HOUR_OF_DAY, 0) cal.set(Calendar.MINUTE, 0) cal.set(Calendar.SECOND, 0) val start = cal.timeInMillis cal.set(Calendar.HOUR_OF_DAY, 23) cal.set(Calendar.MINUTE, 59) cal.set(Calendar.SECOND, 59) val end = cal.timeInMillis lifecycleScope.launch { val records = repo.history(start, end) displayRecords(records, list, text) } } private fun updateRange(text: TextView) { if (rangeStart == 0L || rangeEnd == 0L) return var start = rangeStart var end = rangeEnd if (start > end) { val tmp = start start = end end = tmp } lifecycleScope.launch { val records = repo.history(start, end) val hours = calculateHours(records) text.text = String.format("Selected Range Hours: %.2f", hours) } } private fun updateCalendarRange() { if (rangeStart == 0L || rangeEnd == 0L) return var start = rangeStart var end = rangeEnd if (start > end) { val tmp = start start = end end = tmp } rangeDecorator?.let { calendar.removeDecorator(it) } val startDay = CalendarDay.from(Date(start)) val endDay = CalendarDay.from(Date(end)) val drawable = ContextCompat.getDrawable(this, R.drawable.range_selector_background)!! rangeDecorator = RangeDayDecorator(startDay, endDay, drawable) calendar.addDecorator(rangeDecorator!!) } private suspend fun displayRecords(records: List, list: ListView, text: TextView) { val adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, records.map { "${it.type} - ${DateFormat.getTimeInstance().format(Date(it.time))}" }) list.adapter = adapter val hours = calculateHours(records) text.text = String.format("Hours: %.2f", hours) } private fun calculateHours(records: List): Double { var total = 0L var lastIn: Long? = null for (rec in records.sortedBy { it.time }) { if (rec.type == "in") { lastIn = rec.time } else if (rec.type == "out" && lastIn != null) { total += rec.time - lastIn!! lastIn = null } } return total / 3600000.0 } }