package com.example.shiftalarm import android.content.Context import android.content.res.ColorStateList import android.graphics.Color import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView import androidx.core.content.ContextCompat import androidx.recyclerview.widget.RecyclerView import java.time.LocalDate data class DayShift( val date: LocalDate?, val shift: String?, val hasMemo: Boolean = false, val memoContent: String? = null ) class CalendarAdapter( var days: List, private val listener: OnDayClickListener, var showHolidays: Boolean = true ) : RecyclerView.Adapter() { interface OnDayClickListener { fun onDayClick(date: LocalDate, currentShift: String) } class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { val root: View = view.findViewById(R.id.dayRoot) val dayNumber: TextView = view.findViewById(R.id.dayNumber) val shiftChar: TextView = view.findViewById(R.id.shiftChar) val holidayNameSmall: TextView = view.findViewById(R.id.holidayNameSmall) val memoIndicator: ImageView = view.findViewById(R.id.memoIndicator) val tvTide: TextView = view.findViewById(R.id.tvTide) val memoContent: TextView = view.findViewById(R.id.memoContent) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val view = LayoutInflater.from(parent.context).inflate(R.layout.item_day, parent, false) return ViewHolder(view) } private fun dpToPx(context: Context, dp: Float): Int { return (dp * context.resources.displayMetrics.density).toInt() } override fun onBindViewHolder(holder: ViewHolder, position: Int) { val item = days[position] val context = holder.itemView.context if (item.date == null) { holder.itemView.visibility = View.INVISIBLE return } holder.itemView.visibility = View.VISIBLE // Day Number holder.dayNumber.text = item.date.dayOfMonth.toString() // Holiday / Weekend logic val isSunday = item.date.dayOfWeek == java.time.DayOfWeek.SUNDAY val isSaturday = item.date.dayOfWeek == java.time.DayOfWeek.SATURDAY val fullHolidayName = HolidayManager.getHolidayName(item.date) val isToday = item.date == LocalDate.now() // Day Number Color if (fullHolidayName != null || isSunday) { holder.dayNumber.setTextColor(Color.parseColor("#FF5252")) } else if (isSaturday) { holder.dayNumber.setTextColor(Color.parseColor("#448AFF")) } else { holder.dayNumber.setTextColor(ContextCompat.getColor(context, R.color.text_primary)) } // Tide Display val prefs = context.getSharedPreferences("ShiftAlarmPrefs", Context.MODE_PRIVATE) val showTide = prefs.getBoolean("show_tide", false) val tideLocation = prefs.getString("selected_tide_location", "군산") ?: "군산" if (showTide) { val tide = HolidayManager.getTide(item.date, tideLocation) if (tide.isNotEmpty()) { holder.tvTide.visibility = View.VISIBLE holder.tvTide.text = tide } else { holder.tvTide.visibility = View.GONE } } else { holder.tvTide.visibility = View.GONE } // --- Shift & Holiday Display Logic --- holder.shiftChar.background = null holder.shiftChar.text = "" holder.holidayNameSmall.visibility = View.GONE holder.shiftChar.textSize = 15f // "반월", "반년" (Half-Monthly, Half-Yearly) Special Logic // These are overrides or specific shifts that user sets. // User requested: "월", "년" text. Half-filled background (Red + Transparent). // Check exact string or "startswith" if logic changed? // Logic in adapter `getShift` might return "반월", "반년". if (showHolidays && fullHolidayName != null) { // Holiday Mode (Priority): Show full holiday name, no circle holder.shiftChar.text = fullHolidayName holder.shiftChar.setTextColor(Color.parseColor("#FF5252")) holder.shiftChar.textSize = 11f holder.shiftChar.background = null } else if (item.shift != null && item.shift != "비번") { // Shift Mode // Handle specific "Half" cases first if (item.shift == "반월" || item.shift == "반년") { holder.shiftChar.text = if (item.shift == "반월") "월" else "년" holder.shiftChar.setTextColor(ContextCompat.getColor(context, R.color.black)) // Black for contrast on Half Red/Transparent holder.shiftChar.textSize = 15f holder.shiftChar.background = ContextCompat.getDrawable(context, R.drawable.bg_shift_half_red) } else { // Standard Logic val shiftAbbreviation = when (item.shift) { "주간" -> "주" "석간" -> "석" "야간" -> "야" "주간 맞교대" -> "주맞" "야간 맞교대" -> "야맞" "휴무", "휴가" -> "휴" "월차" -> "월" "연차" -> "연" "교육" -> "교" else -> item.shift.take(1) } holder.shiftChar.text = shiftAbbreviation holder.shiftChar.textSize = 17f holder.shiftChar.setTypeface(null, android.graphics.Typeface.BOLD) val shiftColorRes = when (item.shift) { "주간" -> R.color.shift_lemon "석간" -> R.color.shift_seok "야간" -> R.color.shift_ya "주간 맞교대" -> R.color.shift_jumat "야간 맞교대" -> R.color.shift_yamat "휴무", "휴가", "월차", "연차" -> R.color.shift_red "교육" -> R.color.primary else -> R.color.text_secondary } val shiftColor = ContextCompat.getColor(context, shiftColorRes) if (isToday) { // Today: Solid Circle val background = ContextCompat.getDrawable(context, R.drawable.bg_shift_solid_v4) as? android.graphics.drawable.GradientDrawable background?.setColor(shiftColor) holder.shiftChar.background = background holder.shiftChar.backgroundTintList = null if (item.shift == "주간" || item.shift == "석간") { holder.shiftChar.setTextColor(ContextCompat.getColor(context, R.color.black)) } else { holder.shiftChar.setTextColor(Color.WHITE) } } else { // Not Today: Stroke Circle val background = ContextCompat.getDrawable(context, R.drawable.bg_shift_stroke_v4) as? android.graphics.drawable.GradientDrawable background?.setStroke(dpToPx(context, 1.5f), shiftColor) background?.setColor(Color.TRANSPARENT) holder.shiftChar.background = background holder.shiftChar.backgroundTintList = null holder.shiftChar.setTextColor(shiftColor) } } } // Lunar date small display if requested or just default if (!showHolidays && fullHolidayName != null) { holder.holidayNameSmall.visibility = View.VISIBLE holder.holidayNameSmall.text = fullHolidayName } else { // Ensure visibility GONE if not needed (e.g. standard day) holder.holidayNameSmall.visibility = View.GONE } // Double check: if showHolidays=true (Holiday mode), we handled it at top block. // But if showHolidays=true and NO holiday, we show lunar date? // User asked: "Overlap date and holiday text". // My item_day.xml has holidayNameSmall at bottom now. // If showHolidays=true, CalendarAdapter usually HIDES shiftChar and shows Holiday Name? // Wait, standard logic (lines 84-91 above): // If showHolidays && fullHolidayName != null -> shiftChar shows Name. // If showHolidays && fullHolidayName == null -> shiftChar shows LUNAR DATE? (Old logic had this). if (showHolidays && fullHolidayName == null) { // Show Lunar Date in shiftChar instead of empty? // Or shiftChar is empty, show small text? // Previous code: // holder.shiftChar.text = "" // holder.holidayNameSmall.visibility = View.VISIBLE // holder.holidayNameSmall.text = HolidayManager.getLunarDateString(item.date) holder.shiftChar.text = HolidayManager.getLunarDateString(item.date) holder.shiftChar.textSize = 11f holder.shiftChar.setTextColor(ContextCompat.getColor(context, R.color.text_tertiary)) holder.shiftChar.background = null } // Memo Indicator holder.memoIndicator.visibility = View.GONE // Hide indicator, showing text instead if (item.hasMemo && !item.memoContent.isNullOrEmpty()) { holder.memoContent.visibility = View.VISIBLE holder.memoContent.text = item.memoContent } else { holder.memoContent.visibility = View.GONE } // Today Border or Highlight if (isToday) { holder.root.setBackgroundResource(R.drawable.bg_grid_cell_today_v4) } else { holder.root.setBackgroundResource(R.drawable.bg_grid_cell_v4) } holder.itemView.setOnClickListener { if (item.date != null && item.shift != null) { listener.onDayClick(item.date, item.shift) } } } override fun getItemCount(): Int = days.size }