11package com.example.util.simpletimetracker.core.mapper
22
3+ import com.example.util.simpletimetracker.domain.base.CurrentTimestampProvider
4+ import com.example.util.simpletimetracker.domain.daysOfWeek.mapper.DaysInCalendarMapper
5+ import com.example.util.simpletimetracker.domain.daysOfWeek.model.DayOfWeek
6+ import com.example.util.simpletimetracker.domain.daysOfWeek.model.DaysInCalendar
7+ import com.example.util.simpletimetracker.domain.extension.orZero
8+ import java.util.Calendar
39import javax.inject.Inject
410import kotlin.math.ceil
511
6- class CalendarToListShiftMapper @Inject constructor() {
12+ class CalendarToListShiftMapper @Inject constructor(
13+ private val timeMapper : TimeMapper ,
14+ private val daysInCalendarMapper : DaysInCalendarMapper ,
15+ private val currentTimestampProvider : CurrentTimestampProvider ,
16+ ) {
717
8- fun mapCalendarToListShift (calendarShift : Int , calendarDayCount : Int ): CalendarRange {
18+ fun mapCalendarToListShift (
19+ calendarShift : Int ,
20+ daysInCalendar : DaysInCalendar ,
21+ startOfDayShift : Long ,
22+ firstDayOfWeek : DayOfWeek ,
23+ ): CalendarRange {
24+ val calendarDayCount = daysInCalendarMapper.mapDaysCount(daysInCalendar)
925 if (calendarDayCount == 0 ) return CalendarRange (0 , 0 )
1026
11- val end = calendarShift * calendarDayCount
27+ val weekShift = getWeekShift(
28+ daysInCalendar = daysInCalendar,
29+ startOfDayShift = startOfDayShift,
30+ firstDayOfWeek = firstDayOfWeek,
31+ )
32+
33+ val end = calendarShift * calendarDayCount + weekShift
1234 val start = end - (calendarDayCount - 1 )
1335
1436 return CalendarRange (start, end)
1537 }
1638
17- fun mapListToCalendarShift (listShift : Int , calendarDayCount : Int ): Int {
39+ fun mapListToCalendarShift (
40+ listShift : Int ,
41+ daysInCalendar : DaysInCalendar ,
42+ startOfDayShift : Long ,
43+ firstDayOfWeek : DayOfWeek ,
44+ ): Int {
45+ val calendarDayCount = daysInCalendarMapper.mapDaysCount(daysInCalendar)
1846 if (calendarDayCount == 0 ) return 0
1947
20- return ceil(listShift.toFloat() / calendarDayCount).toInt()
48+ val weekShift = getWeekShift(
49+ daysInCalendar = daysInCalendar,
50+ startOfDayShift = startOfDayShift,
51+ firstDayOfWeek = firstDayOfWeek,
52+ )
53+ val actualListShift = listShift - weekShift
54+
55+ return ceil(actualListShift.toFloat() / calendarDayCount).toInt()
2156 }
2257
2358 fun recalculateRangeOnCalendarViewSwitched (
2459 currentPosition : Int ,
2560 lastListPosition : Int ,
2661 showCalendar : Boolean ,
27- daysInCalendar : Int ,
62+ daysInCalendar : DaysInCalendar ,
63+ startOfDayShift : Long ,
64+ firstDayOfWeek : DayOfWeek ,
2865 ): Int {
2966 return if (showCalendar) {
3067 mapListToCalendarShift(
3168 listShift = currentPosition,
32- calendarDayCount = daysInCalendar,
69+ daysInCalendar = daysInCalendar,
70+ startOfDayShift = startOfDayShift,
71+ firstDayOfWeek = firstDayOfWeek,
3372 )
3473 } else {
3574 val calendarRange = mapCalendarToListShift(
3675 calendarShift = currentPosition,
37- calendarDayCount = daysInCalendar,
76+ daysInCalendar = daysInCalendar,
77+ startOfDayShift = startOfDayShift,
78+ firstDayOfWeek = firstDayOfWeek,
3879 )
3980 if (lastListPosition in (calendarRange.start.. calendarRange.end)) {
4081 lastListPosition
@@ -46,20 +87,50 @@ class CalendarToListShiftMapper @Inject constructor() {
4687
4788 fun recalculateRangeOnCalendarDaysChanged (
4889 currentPosition : Int ,
49- currentDaysInCalendar : Int ,
50- newDaysInCalendar : Int ,
90+ currentDaysInCalendar : DaysInCalendar ,
91+ newDaysInCalendar : DaysInCalendar ,
92+ startOfDayShift : Long ,
93+ firstDayOfWeek : DayOfWeek ,
5194 ): Int {
5295 // Find another range that contains last day of current range.
5396 val listPosition = mapCalendarToListShift(
5497 calendarShift = currentPosition,
55- calendarDayCount = currentDaysInCalendar,
98+ daysInCalendar = currentDaysInCalendar,
99+ startOfDayShift = startOfDayShift,
100+ firstDayOfWeek = firstDayOfWeek,
56101 ).end
57102 return mapListToCalendarShift(
58103 listShift = listPosition,
59- calendarDayCount = newDaysInCalendar,
104+ daysInCalendar = newDaysInCalendar,
105+ startOfDayShift = startOfDayShift,
106+ firstDayOfWeek = firstDayOfWeek,
60107 )
61108 }
62109
110+ // How many days until week end.
111+ // Week starts on Monday, today Tuesday, result 5.
112+ // Week starts on Monday, today Monday, result 6.
113+ // Week starts on Monday, today Sunday, result 0.
114+ private fun getWeekShift (
115+ daysInCalendar : DaysInCalendar ,
116+ startOfDayShift : Long ,
117+ firstDayOfWeek : DayOfWeek ,
118+ ): Int {
119+ return if (daysInCalendar == DaysInCalendar .WEEK ) {
120+ val weekOrder = timeMapper.getWeekOrder(firstDayOfWeek)
121+ val currentDayOfWeek = timeMapper.getDayOfWeek(
122+ timestamp = currentTimestampProvider.get(),
123+ calendar = Calendar .getInstance(),
124+ startOfDayShift = startOfDayShift,
125+ )
126+ weekOrder.size - weekOrder.indexOf(currentDayOfWeek).takeUnless { it == - 1 }.orZero() - 1
127+ } else {
128+ 0
129+ }
130+ }
131+
132+ // Values are days from today.
133+ // -6:0 last 7 days, 1:7 next 7 days.
63134 data class CalendarRange (
64135 val start : Int ,
65136 val end : Int ,
0 commit comments