4e67d0ee5d6a7119f8b7b5f79960daf26da78c27
[apps/core/preloaded/calendar.git] / src / list-comparator.c
1 /*
2   *
3   *  Copyright 2012  Samsung Electronics Co., Ltd
4   *
5   *  Licensed under the Flora License, Version 1.0 (the "License");
6   *  you may not use this file except in compliance with the License.
7   *  You may obtain a copy of the License at
8   *
9   *       http://floralicense.org/license/
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   */
17
18 #include "list-comparator.h"
19
20 #define INVALID_DATETIME_VALUE 0
21
22 // Former has priority in case of a tie
23 static int __cal_list_comparator_min(int* v, int n)
24 {
25         int min = -1;
26         int i;
27         for (i = 0; i < n; i++) {       // Working upwards guarantees former has priority in case of a tie
28                 if (v[i] == INVALID_DATETIME_VALUE)
29                         continue;
30                 if (min == -1 || v[i] < v[min]) // Found first valid value or something less than current min
31                         min = i;
32         }
33         return min;
34 }
35
36 // Latter has priority in case of a tie
37 static int __cal_list_comparator_max(int* v, int n)
38 {
39         int max = -1;
40         int i;
41         for (i = n - 1; i >= 0; i--) {  // Working downwards guarantees latter has priority in case of a tie
42                 if (v[i] == INVALID_DATETIME_VALUE)
43                         continue;
44                 if (max == -1 || v[max] < v[i]) // Found first valid value or something greater than current max
45                         max = i;
46         }
47         return max;
48 }
49
50 static inline int __cal_list_get_day_val(const struct tm* day)
51 {
52         return (day->tm_year << 9) | (day->tm_mon << 5) | day->tm_mday;
53 }
54
55 static inline void __cal_list_get_day_tm(const calendar_time_s* time, struct tm* day)
56 {
57         switch (time->type) {
58         case CALENDAR_TIME_UTIME:
59                 cal_util_convert_lli_to_tm(NULL, time->time.utime, day);
60                 break;
61         case CALENDAR_TIME_LOCALTIME:
62                 day->tm_year = time->time.date.year - 1900;
63                 day->tm_mon = time->time.date.month - 1;
64                 day->tm_mday = time->time.date.mday;
65                 break;
66         default:
67                 // error
68                 break;
69         }
70 }
71
72 int cal_list_comparator_determine_next(
73                 calendar_record_h record1, calendar_record_h record2, calendar_record_h record3,
74                 unsigned int time_property_id1, unsigned int time_property_id2, unsigned int time_property_id3,
75                 int direction, struct tm* current_day, bool* day_has_changed)
76 {
77         struct tm daytm[3];
78         memset(daytm, 0, sizeof(struct tm) * 3);
79
80         // Get the day of each record - value of 0 means it's out of the game.
81         // Since tm_mday is 1 to 31, 0 is not a possible result of __cal_list_get_day_value().
82         int dayval[3] = {INVALID_DATETIME_VALUE, INVALID_DATETIME_VALUE, INVALID_DATETIME_VALUE};
83
84         calendar_time_s time;
85
86         if (record1) {
87                 calendar_record_get_caltime(record1, time_property_id1, &time);
88                 __cal_list_get_day_tm(&time, &daytm[0]);
89                 dayval[0] = __cal_list_get_day_val(&daytm[0]);
90                 DBG("Contestant: 1(%s)", cal_util_print_day(&daytm[0]));
91         }
92
93         if (record2) {
94                 calendar_record_get_caltime(record2, time_property_id2, &time);
95                 __cal_list_get_day_tm(&time, &daytm[1]);
96                 dayval[1] = __cal_list_get_day_val(&daytm[1]);
97                 DBG("Contestant: 2(%s)", cal_util_print_day(&daytm[1]));
98         }
99
100         if (record3) {
101                 calendar_record_get_caltime(record3, time_property_id3, &time);
102                 __cal_list_get_day_tm(&time, &daytm[2]);
103                 dayval[2] = __cal_list_get_day_val(&daytm[2]);
104                 DBG("Contestant: 3(%s)", cal_util_print_day(&daytm[2]));
105         }
106
107         int winner;
108         if (direction > 0)
109                 winner = __cal_list_comparator_min(dayval, 3);
110         else
111                 winner = __cal_list_comparator_max(dayval, 3);
112
113         *day_has_changed = false;
114
115         if (winner < 0) {
116                 DBG("Winner: none!");
117                 return 0;
118         }
119
120         if (__cal_list_get_day_val(current_day) != dayval[winner]) {
121                 *current_day = daytm[winner];
122                 *day_has_changed = true;
123         }
124
125         DBG("Winner: %d", winner + 1);
126         return winner + 1;
127 }