3 * Copyright 2012 Samsung Electronics Co., Ltd
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
9 * http://www.tizenopensource.org/license
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.
23 #define ANIMATION_TIME 0.2
25 typedef enum year_index {
26 CAL_YEAR_PREV_YEAR = -1,
31 static const char *_name = NULL;
37 Evas_Object *ly; // self
38 Evas_Object *handle_base;
40 struct _year* prev_year;
41 struct _year* cur_year;
42 struct _year* next_year;
44 Eina_Bool ignore_mouse_down; // block mouse down event during flick
46 Evas_Coord_Rectangle rect;
47 Evas_Coord_Point down1,down2;
48 Evas_Coord_Point move1,move2;
56 Evas_Coord_Rectangle mouse_down_position;
57 Evas_Coord_Rectangle mouse_up_position;
58 Evas_Coord_Rectangle pos_to;
63 char wday[8][7];//To reduce get text time
64 char month[12][32];//To reduce get text time
66 Ecore_Idler* idler; //To make prev & next year object
68 Evas_Object* edje_handle[12];
69 } cal_view_main_year_data;
77 cal_view_main_year_data *p;
80 static char signal_source[32];
81 static struct _year* __cal_year_create_year_object(Evas_Object* parent, cal_view_main_year_data* p, enum year_index);
82 static void __cal_year_delete_year_object(struct _year* y);
83 static void __cal_year_mouse_up(void *data, Evas *e, Evas_Object *ly, void *ei);
84 static void __cal_year_mouse_down(void *data, Evas *e, Evas_Object *ly, void *ei);
85 static void __cal_year_mouse_move(void *data, Evas *e, Evas_Object *ly, void *ei);
86 static void __cal_year_update_select(struct _year *y, int tm_mon);
87 static void __cal_year_delete_edje_handle(cal_view_main_year_data* p);
89 static inline void __cal_year_stop_animation(cal_view_main_year_data *p)
91 c_retm_if(!p, "Input parameter is null.");
94 ecore_animator_del(p->ani);
99 static void __cal_year_delete_layout(void *data, Evas *e, Evas_Object *obj, void *ei)
103 c_retm_if(!data, "Input parameter is null.");
105 cal_view_main_year_data *p = data;
107 __cal_year_delete_edje_handle(p);
109 __cal_year_stop_animation(p);
112 __cal_year_delete_year_object(p->prev_year);
114 __cal_year_delete_year_object(p->cur_year);
116 __cal_year_delete_year_object(p->next_year);
119 ecore_idler_del(p->idler);
124 static void __cal_year_set_month_text(struct _year* y)
126 c_retm_if(!y, "Input parameter is null.");
129 cal_view_main_year_data* p = y->p;
133 for (i = 0; i < 12; i++)
134 edje_object_part_text_set(y->edj, cal_util_get_part_text("mb/%d/text", i), p->month[i]);
137 static void __cal_year_make_month_text(cal_view_main_year_data* p)
139 c_retm_if(!p, "Input parameter is null.");
145 cal_util_update_tm_month(&tm, tm.tm_mon*(-1));
147 for(i = 0; i < 12 ; i++)
149 cal_util_get_time_text(p->month[i], 31, CAL_UTIL_DATE_FORMAT_4, NULL, &tm);
150 cal_util_update_tm_month(&tm, 1);
154 static void __cal_year_make_wday_text(cal_view_main_year_data* p)
156 c_retm_if(!p, "Input parameter is null.");
162 cal_util_update_tm_day(&tm, tm.tm_wday*(-1));
164 for(i = 0; i < 7 ; i++) {
165 cal_util_get_time_text(p->wday[i], 7, CAL_UTIL_DATE_FORMAT_17, NULL, &tm);
166 cal_util_update_tm_day(&tm, 1);
170 static void __cal_year_set_wday_text(Evas_Object *month, int start)
172 c_retm_if(!month, "Input parameter is null.");
176 cal_view_main_year_data* p = CAL_UTIL_GET_PRIV_DATA(month);
178 for (i = 0; i < 7; i++)
180 edje_object_part_text_set(month, cal_util_get_part_text("sdh/%d/text", i), p->wday[(i+start)%7]);
183 cal_util_emit_signal(month, "satday,%d", i);
188 cal_util_emit_signal(month, "sunday,%d", i);
192 static void __cal_year_update_today(Evas_Object *ly, int tm_year, int tm_mon, int tm_mday, int pos)
194 c_retm_if(!ly, "Input parameter is null.");
196 cal_view_main_year_data *p = CAL_UTIL_GET_PRIV_DATA(ly);
197 c_retm_if(!p, "CAL_UTIL_GET_PRIV_DATA returned null.");
199 struct appdata *ad = p->ad;
200 c_retm_if(!ad, "p->ad is null.");
202 if (tm_year == ad->today_tm.tm_year && tm_mon == ad->today_tm.tm_mon && tm_mday == ad->today_tm.tm_mday)
203 cal_util_emit_signal(ly, "today,%d", pos-1);
207 static void __cal_year_fill_month(Evas_Object *month, int tm_year, int tm_mon, int *first_wday, int start_wday)
209 c_retm_if(!month, "Input parameter is null.");
215 max = CAL_UTIL_GET_WDAY(wday - start_wday);
217 for (i = 0; i < max; i++)
219 cal_util_set_text(month, cal_util_get_part_text("sdb/%d/text", i), "");
223 max = i + cal_util_get_max_days(tm_year, tm_mon);
226 cal_util_set_text(month, cal_util_get_part_text("sdb/%d/text", i), "%d", day);
229 cal_util_emit_signal(month, "satday,%d", i);
231 cal_util_emit_signal(month, "sunday,%d", i);
233 wday = CAL_UTIL_GET_WDAY(wday + 1);
235 __cal_year_update_today(month, tm_year, tm_mon, day-1, i);
242 cal_util_set_text(month, cal_util_get_part_text("sdb/%d/text", i), "");
248 static Evas_Object* __cal_year_create_month(struct _year *y, int tm_mon, int *wday, int start)
252 Evas_Object *month = edje_object_add(y->evas);
254 Eina_Bool r = edje_object_file_set(month, EDJ_FILE, "main/year/cal");
257 ERR("edje_object_file_set(%p, %s, %s) is failed.", month, EDJ_FILE, "main/year/cal");
259 evas_object_del(month);
264 evas_object_data_set(month,"priv",y->p);
266 __cal_year_set_wday_text(month, start);
268 __cal_year_fill_month(month, y->year, tm_mon, wday, start);
273 static int __cal_year_get_first_wday(int tm_year)
279 localtime_r(&t, &tm);
281 tm.tm_year = tm_year;
286 c_retvm_if(t == -1, 0, "mktime() returned -1.");
291 static void __cal_year_fill_months(struct _year* y)
293 c_retm_if(!y, "Input parameter is null.");
298 cal_view_main_year_data* p = y->p;
300 first_wday = __cal_year_get_first_wday(y->year);
302 __cal_year_make_wday_text(p);
304 for (i = 0; i < 12; i++)
306 month = __cal_year_create_month(y, i, &first_wday, p->ad->wday_start);
307 c_retm_if(!month, "");
309 edje_object_part_swallow(y->edj, cal_util_get_part_text("mb/%d/sw", i), month);
311 evas_object_data_set(y->ly, cal_util_get_part_text("mb/%d/sw", i), month);
315 static inline void __cal_year_move_year_objects(cal_view_main_year_data *p, Evas_Coord x)
317 c_retm_if(!p, "Input parameter is null.");
323 p->next_year = __cal_year_create_year_object(p->ly, p, CAL_YEAR_NEXT_YEAR);
324 c_retm_if(!p->next_year, "__cal_year_create_year_object(p->ly, p, CAL_YEAR_NEXT_YEAR) returned null");
327 evas_object_move(p->cur_year->image, x, p->rect.y);
329 evas_object_move(p->next_year->image, x + p->rect.w, p->rect.y);
334 p->prev_year = __cal_year_create_year_object(p->ly, p, CAL_YEAR_PREV_YEAR);
335 c_retm_if(!p->prev_year, "__cal_year_create_year_object(p->ly, p, CAL_YEAR_PREV_YEAR) returned null");
338 evas_object_move(p->cur_year->image, x, p->rect.y);
340 evas_object_move(p->prev_year->image, x -p->rect.w, p->rect.y);
343 evas_object_move(p->handle_base, x, p->rect.y);
346 static void __cal_year_image_object_mouse_down_callback(void *data, Evas *e, Evas_Object *obj, void *ei)
348 c_retm_if(!data, "Input parameter is null.");
350 cal_view_main_year_data *p = data;
351 struct _year *y = p->cur_year;
353 int index = (int)evas_object_data_get(obj, "index");
355 snprintf(signal_source, 31, "mb/%d/base", index);
356 edje_object_signal_emit(y->edj, "mouse,down,1", signal_source);
361 static void __cal_year_image_object_mouse_up_callback(void *data, Evas *e, Evas_Object *obj, void *ei)
363 c_retm_if(!data, "Input parameter is null.");
365 cal_view_main_year_data *p = data;
366 struct _year *y = p->cur_year;
367 struct appdata* ad = p->ad;
369 snprintf(signal_source, 31, "mb/%d/base", p->pos_down);
370 edje_object_signal_emit(y->edj, "mouse,up,1", signal_source);
372 if (p->ignore_mouse_down)
374 p->ignore_mouse_down = EINA_FALSE;
378 cal_util_update_tm_month(&ad->base_tm, p->pos_down - ad->base_tm.tm_mon);
380 cal_main_change_view(p->parent, CV_MONTH);
383 static void __cal_year_delete_edje_handle(cal_view_main_year_data* p)
385 c_retm_if(!p, "p is null.");
389 for (i = 0 ; i < 12 ; i++)
391 c_retm_if(!p->edje_handle[i], "p->edje_handle[%d] is null.", i);
393 evas_object_event_callback_del(p->edje_handle[i], EVAS_CALLBACK_MOUSE_DOWN, __cal_year_image_object_mouse_down_callback);
394 evas_object_event_callback_del(p->edje_handle[i], EVAS_CALLBACK_MOUSE_UP, __cal_year_image_object_mouse_up_callback);
396 evas_object_del(p->edje_handle[i]);
399 c_retm_if(!p->handle_base, "p->handle_base is null.");
400 evas_object_del(p->handle_base);
403 static inline int __cal_year_update_view(cal_view_main_year_data *p)
407 c_retvm_if(!p, -1, "Input parameter is null.");
408 c_retvm_if(!p->ad, -1, "p->ad is null.");
410 struct appdata* ad = p->ad;
412 int d = p->tm_to.tm_year - p->ad->base_tm.tm_year;
414 ad->base_tm = p->tm_to;
416 cal_util_emit_signal(p->cur_year->edj, "unselect,%d", p->pos_selected);
418 elm_object_part_content_unset(p->ly, "content");
419 elm_object_part_content_unset(p->ly, "content/left");
420 elm_object_part_content_unset(p->ly, "content/right");
425 evas_object_del(p->prev_year->image);
426 __cal_year_delete_year_object(p->prev_year);
429 p->prev_year = p->cur_year;
430 p->cur_year = p->next_year;
431 p->next_year = __cal_year_create_year_object(p->ly, p, CAL_YEAR_NEXT_YEAR);
436 evas_object_del(p->next_year->image);
437 __cal_year_delete_year_object(p->next_year);
440 p->next_year = p->cur_year;
441 p->cur_year = p->prev_year;
442 p->prev_year = __cal_year_create_year_object(p->ly, p, CAL_YEAR_PREV_YEAR);
445 elm_object_part_content_set(p->ly, "content", p->cur_year->image);
448 elm_object_part_content_set(p->ly, "content/left", p->prev_year->image);
451 elm_object_part_content_set(p->ly, "content/right", p->next_year->image);
453 cal_main_update_title_text(ad->title, CV_YEAR, &ad->base_tm, ad->wday_start);
455 __cal_year_update_select(p->cur_year, ad->base_tm.tm_mon);
457 __cal_year_move_year_objects(p, 0);
459 if (p->ignore_mouse_down)
460 p->ignore_mouse_down = EINA_FALSE;
465 static Eina_Bool __cal_year_animation(void *data, double pos)
467 c_retvm_if(!data, ECORE_CALLBACK_CANCEL, "Input parameter is null.");
469 cal_view_main_year_data *p = data;
472 dx = (p->mouse_up_position.x - p->pos_to.x) * cal_util_nsin(1.0 - pos);
473 __cal_year_move_year_objects(p, p->pos_to.x + dx);
475 if ((dx + p->pos_to.x)%p->rect.w == 0)
478 __cal_year_update_view(p);
479 return ECORE_CALLBACK_CANCEL;
482 return ECORE_CALLBACK_RENEW;
485 static inline void __cal_year_start_animation(cal_view_main_year_data *p)
487 c_retm_if(!p, "Input parameter is null.");
489 if (p->mouse_up_position.x == p->pos_to.x)
493 p->ani = ecore_animator_timeline_add(ANIMATION_TIME, __cal_year_animation, p);
495 p->ani_start = ecore_time_get();
498 static void inline __cal_year_set_go(cal_view_main_year_data *p, int d)
500 c_retm_if(!p, "Input parameter is null.");
504 p->tm_to = p->ad->base_tm;
508 r = cal_util_update_tm_year(&p->tm_to, d);
512 p->pos_to.x = p->rect.w * (d * -1);
515 static void __cal_year_mouse_up(void *data, Evas *e, Evas_Object *ly, void *ei)
517 c_retm_if(!data, "Input parameter is null.");
519 Evas_Event_Mouse_Up *ev = ei;
520 cal_view_main_year_data *p = data;
527 cal_util_get_geometry(&p->mouse_up_position, p->cur_year->image);
529 if (p->mouse_up_position.x > (p->rect.w >> 2))
530 __cal_year_set_go(p, -1);
531 else if (p->mouse_up_position.x < (p->rect.w >> 2) * -1)
532 __cal_year_set_go(p, 1);
535 Evas_Coord x = ev->canvas.x - p->down1.x;
537 if (x < 3 && x > -3 && p->mouse_up_position.x ==0)
540 __cal_year_set_go(p, 0);
543 __cal_year_start_animation(p);
546 static void __cal_year_mouse_move(void *data, Evas *e, Evas_Object *ly, void *ei)
548 c_retm_if(!data, "Input parameter is null.");
550 cal_view_main_year_data *p = data;
552 Evas_Event_Mouse_Move *ev = ei;
555 Evas_Coord th = elm_finger_size_get();
558 p->move1.x = ev->cur.canvas.x;
559 p->move1.y = ev->cur.canvas.y;
561 if (!p->downed || p->multi_touched)
565 if ((cnt & 0x7) != 0) // Workaround
568 dx = p->move1.x - p->down1.x;
570 x = p->mouse_down_position.x + p->move1.x - p->down1.x;
572 __cal_year_move_year_objects(p, x);
574 p->ignore_mouse_down = EINA_TRUE;
579 static void __cal_year_mouse_down(void *data, Evas *e, Evas_Object *ly, void *ei)
581 c_retm_if(!data, "Input parameter is null.");
583 cal_view_main_year_data *p = data;
584 struct _year *y = p->cur_year;
586 Evas_Event_Mouse_Down *ev = ei;
588 p->down1.x = p->move1.x = ev->canvas.x;
589 p->down1.y = p->move1.y = ev->canvas.y;
591 cal_util_get_geometry(&p->mouse_down_position, y->image);
593 __cal_year_stop_animation(p);
596 p->multi_touched = 0;
599 static void __cal_year_update_select(struct _year *y, int tm_mon)
601 c_retm_if(!y, "Input parameter is null.");
603 cal_view_main_year_data* p = y->p;
605 if (p->pos_selected != -1)
606 cal_util_emit_signal(y->edj, "unselect,%d", p->pos_selected);
608 cal_util_emit_signal(y->edj, "select,%d", tm_mon);
610 p->pos_selected = tm_mon;
613 static Evas_Object *__cal_year_create_image(Evas_Object *parent, Eina_Bool is_landscape_mode)
615 c_retvm_if(!parent, NULL, "Input parameter is null.");
622 ecore_x_window_size_get(ecore_x_window_root_first_get(), &w, &h);
624 if (is_landscape_mode) {
630 e = evas_object_evas_get(parent);
631 ee = ecore_evas_ecore_evas_get(e);
633 img = ecore_evas_object_image_new(ee);
637 evas_object_image_alpha_set(img, EINA_TRUE);
638 evas_object_image_size_set(img, w, h);
639 evas_object_image_fill_set(img, 0, 0, w, h);
641 evas_object_show(img);
646 static Evas_Object *__cal_year_add_edje(Evas *e, const char *grp, Evas_Coord w, Evas_Coord h)
650 Evas_Object *eo = edje_object_add(e);
651 c_retv_if(!eo, NULL);
653 Eina_Bool r = edje_object_file_set(eo, EDJ_FILE, grp);
656 ERR("edje_object_file_set(%p, %s, %s) is failed.", eo, EDJ_FILE, grp);
663 evas_object_freeze_events_set(eo, EINA_TRUE);
665 evas_object_resize(eo, w, h);
666 evas_object_move(eo, 0, 0);
667 evas_object_show(eo);
672 static void __cal_year_image_object_resize_callback(void *data, Evas *e, Evas_Object *obj, void *ei)
674 c_retm_if(!data, "Input parameter is null.");
676 struct _year *y = data;
677 c_retm_if(!y->edj, "y->edj is null.");
678 c_retm_if(!y->p, "y->p is null.");
680 cal_view_main_year_data *p = y->p;
682 cal_util_get_geometry(&p->rect, obj);
684 evas_object_resize(y->edj, p->rect.w, p->rect.h);
685 evas_object_move(y->edj, 0, 0);
688 static void __cal_year_image_object_move_callback(void *data, Evas *e, Evas_Object *obj, void *ei)
690 c_retm_if(!data, "Input parameter is null.");
692 struct _year *y = data;
694 evas_object_move(y->edj, 0, 0);
697 static void __cal_year_delete_year_object(struct _year* y)
701 c_retm_if(!y, "Input parameter is null.");
703 evas_object_del(y->edj);
708 static struct _year* __cal_year_create_year_object(Evas_Object* ly, cal_view_main_year_data* p, enum year_index year)
710 c_retvm_if(!ly, NULL, "Input parameter is null.");
711 c_retvm_if(!p, NULL, "Input parameter is null.");
712 c_retvm_if(!p->ad, NULL, "p->ad is null.");
714 struct appdata* ad = p->ad;
715 c_retv_if(!ad, NULL);
717 struct tm tm = ad->base_tm;
719 int r = cal_util_update_tm_year(&tm, year);
720 c_retvm_if(r < 0, NULL, "cal_util_update_tm_year(%d, %d is failed", tm.tm_year, year);
722 struct _year* y = calloc(1, sizeof(struct _year));
725 y->image = __cal_year_create_image(ly, ad->is_landscape_mode);
727 y->evas = ecore_evas_object_evas_get(y->image);
729 y->edj = __cal_year_add_edje(y->evas, p->name, p->rect.w, p->rect.h);
734 elm_object_part_content_set(ly, "content/right", y->image);
736 elm_object_part_content_set(ly, "content/left", y->image);
738 elm_object_part_content_set(ly, "content", y->image);
741 y->year = tm.tm_year;
743 evas_object_event_callback_add(y->image, EVAS_CALLBACK_RESIZE, __cal_year_image_object_resize_callback, y);
744 evas_object_event_callback_add(y->image, EVAS_CALLBACK_MOVE, __cal_year_image_object_move_callback, y);
746 __cal_year_set_month_text(y);
747 __cal_year_fill_months(y);
752 static void __cal_year_create_edje_handle(cal_view_main_year_data* p)
754 c_retm_if(!p, "p is null.");
756 Evas * e = evas_object_evas_get(p->ly);
758 Evas_Object *ly = NULL;
759 Evas_Object *handle = NULL;
762 if (!p->ad->is_landscape_mode) {
763 ly = cal_util_add_layout(p->ly, "year/edje/handle");
765 ly = cal_util_add_layout(p->ly, "year/edje/handle/l");
768 c_retm_if(!ly, "ly is null.");
770 for (i = 0 ; i < 12 ; i++)
772 handle = evas_object_rectangle_add(e);
773 c_retm_if(!handle, "evas_object_rectangle_add returned null.");
775 evas_object_color_set(handle, 0, 0, 0, 0);
776 evas_object_data_set(handle, "index", (void*)i);
777 snprintf(part, sizeof(part), "handle/%d/sw", i);
778 elm_object_part_content_set(ly, part, handle);
780 evas_object_event_callback_add(handle, EVAS_CALLBACK_MOUSE_DOWN, __cal_year_image_object_mouse_down_callback, p);
781 evas_object_event_callback_add(handle, EVAS_CALLBACK_MOUSE_UP, __cal_year_image_object_mouse_up_callback, p);
783 p->edje_handle[i] = handle;
786 elm_object_part_content_set(p->ly, "edje/handle", ly);
792 Evas_Object* cal_year_create_view(struct appdata *ad, Evas_Object *main)
794 c_retvm_if(!ad, NULL, "Input parameter is null.");
795 c_retvm_if(!main, NULL, "Input parameter is null.");
797 cal_view_main_year_data *p;
798 Evas_Object* ly = NULL;
800 CAL_CALLOC(p, 1, cal_view_main_year_data);
802 if (!ad->is_landscape_mode) {
803 p->name = _name = "main/year/months";
805 p->name = _name = "main/year/months/l";
811 edje_object_part_geometry_get(CAL_UTIL_GET_EDJ_DATA(ad->main), "cont", NULL, NULL, &p->rect.w, &p->rect.h);
813 memset(p->wday, 0, 8*7);
814 memset(p->month, 0, 32*12);
816 __cal_year_make_month_text(p);
818 ly = cal_util_add_layout(p->ad->nv, "year/layout");
825 evas_object_data_set(ly, "priv", p);
828 p->pos_selected = -1;
830 __cal_year_create_edje_handle(p);
832 evas_object_event_callback_add(ly, EVAS_CALLBACK_DEL, __cal_year_delete_layout, p);
833 evas_object_event_callback_add(ly, EVAS_CALLBACK_MOUSE_DOWN, __cal_year_mouse_down, p);
834 evas_object_event_callback_add(ly, EVAS_CALLBACK_MOUSE_UP, __cal_year_mouse_up, p);
835 evas_object_event_callback_add(ly, EVAS_CALLBACK_MOUSE_MOVE, __cal_year_mouse_move, p);
840 static Eina_Bool __cal_year_create_year_with_idler(void* data)
844 c_retvm_if(!data, ECORE_CALLBACK_CANCEL, "Input param is null.");
846 cal_view_main_year_data* p = data;
848 c_retvm_if(!p->ad, ECORE_CALLBACK_CANCEL, "p->ad is null.");
851 __cal_year_delete_year_object(p->prev_year);
853 p->prev_year = __cal_year_create_year_object(p->ly, p, CAL_YEAR_PREV_YEAR);
854 c_retvm_if(!p->prev_year, ECORE_CALLBACK_CANCEL, "__cal_year_create_year_object returned null.");
857 __cal_year_delete_year_object(p->next_year);
859 p->next_year = __cal_year_create_year_object(p->ly, p, CAL_YEAR_NEXT_YEAR);
860 c_retvm_if(!p->next_year, ECORE_CALLBACK_CANCEL, "__cal_year_create_year_object returned null.");
864 return ECORE_CALLBACK_CANCEL;
867 static void __cal_year_update_current_year(cal_view_main_year_data* p)
871 c_retm_if(!p, "Input parameter is null.");
873 p->cur_year = __cal_year_create_year_object(p->ly, p, CAL_YEAR_CURR_YEAR);
874 c_retm_if(!p->cur_year, "__cal_year_create_year_object returned null.");
876 elm_object_part_content_set(p->ly, "content", p->cur_year->image);
879 void cal_year_update_view(Evas_Object *ly)
883 c_retm_if(!ly, "Input parameter is null.");
885 cal_view_main_year_data *p;
888 p = CAL_UTIL_GET_PRIV_DATA(ly);
889 c_retm_if(!p, "p is null.");
892 c_retm_if(!ad, "p->ad is null.");
894 if (!p || CAL_STRCMP(p->name, _name)) {
895 ERR("update year view: Invalid object");
899 __cal_year_update_current_year(p);
903 ecore_idler_del(p->idler);
907 p->idler = ecore_idler_add(__cal_year_create_year_with_idler, (void*)p);
909 __cal_year_update_select(p->cur_year, ad->base_tm.tm_mon);