2.0 alpha
[apps/core/preloaded/calendar.git] / src / view-main-month-cal.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://www.tizenopensource.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
19 #include "view.h"
20 #include "detail.h"
21
22 #define CAL_MONTH_CALENDAR_LAST_LINE_POS_INDEX 41
23
24 #define WEEKS_OF_MONTH 6
25 #define DAYS_OF_WEEK 7
26 #define DAYS_OF_WEEKLY_MONTHS_VIEW 42
27 #define LINES_OF_WEEKLY_MONTHS_EVENT 3
28 #define LINES_OF_WEEKLY_MONTHS_EVENT_LANDSCAPE 1
29
30
31
32 enum {
33         ST_PREV = -1,
34         ST_CURR = 0,
35         ST_NEXT = 1,
36 };
37
38 typedef enum {
39         CAL_MONTH_CALENDAR_DAY_TYPE_SUNDAY = 0,
40         CAL_MONTH_CALENDAR_DAY_TYPE_SATDAY,
41         CAL_MONTH_CALENDAR_DAY_TYPE_WEEKDAY,
42 } cal_month_calendar_day_type_t;
43
44 struct _day {
45         int enabled:1;
46         int checked:1;
47         cal_month_calendar_day_type_t d_type;
48 };
49
50 typedef struct {
51         int calendar_id;
52         int line;
53         int width;
54         int showed;
55         char title[512];
56         time_t start_time;
57         time_t end_time;
58 }cal_month_calendar_weekly_event;
59
60 typedef struct {
61         const char *name;
62         struct appdata *ad;
63         Evas_Object *parent;
64         Evas_Object *weekly_events_ly[WEEKS_OF_MONTH];
65         Evas_Object *month;
66         Eina_List *event_list;
67         Evas_Object *gl;
68         Evas_Object *popup;
69
70         int base_pos_for_weekly;
71         int index_for_press;
72         struct _day day[DAYS_OF_WEEKLY_MONTHS_VIEW];
73         int pos_today;
74         int pos_selected;
75         int pos_start;
76         int pos_end;
77         int pos_down;
78         GList* week_event_list[WEEKS_OF_MONTH][DAYS_OF_WEEK];
79         int weekline;
80         int down_x;
81         int down_y;
82 } cal_month_calendar_data;
83
84 static const char *_name = NULL;
85 static Calendar_color calendar_color;
86
87 static Evas_Object *__cal_month_calendar_get_genlist_item_icon(void *data, Evas_Object *obj, const char *part);
88 static char* __cal_month_calendar_get_genlist_item_label(void *data, Evas_Object *obj, const char *part);
89 static void __cal_month_calendar_signal_week(cal_month_calendar_data *p, Evas_Object *obj, int index);
90 static int __cal_month_calendar_get_weekly_events(cal_month_calendar_data *p);
91
92 static void __cal_month_calendar_events_of_one_weekday(void *data);
93 static void __cal_month_calendar_get_events(cal_month_calendar_data *p);
94 static int __cal_month_calendar_get_day_time_by_pos(cal_month_calendar_data *p, int *first_day, int *last_day, struct tm *start_time, struct tm *end_time, int day_pos);
95 static void __cal_month_calendar_create_event_lists(Evas_Object *ly, cal_month_calendar_data *p);
96 static void __cal_month_calendar_signal_all_week(cal_month_calendar_data *p);
97 static void __cal_month_calendar_signal_all_clean(cal_month_calendar_data *p);
98 static void __cal_month_calendar_set_more_text(Evas_Object *ly, int count, int index);
99 static int __cal_month_calendar_clean_list(cal_month_calendar_data *p);
100 static void __cal_month_calendar_set_check_text(Evas_Object *ly, cal_month_calendar_data *p, int count, int index);
101 static void __cal_month_calendar_set_event_rect_color(Evas_Object *obj, cal_month_calendar_data *p, int line, int pos, int calendar_id);
102 static void __cal_month_calendar_set_day_default_color(cal_month_calendar_data* p, Evas_Object *eo, int pos);
103 static void __cal_month_calendar_fill_week_number(Evas_Object *ly);
104
105 static Elm_Genlist_Item_Class itc = {
106         .item_style = "3text.5icon",
107         .func.content_get = __cal_month_calendar_get_genlist_item_icon,
108         .func.text_get = __cal_month_calendar_get_genlist_item_label,
109 };
110
111 static Evas_Object *__cal_month_calendar_get_genlist_item_icon(void *data, Evas_Object *obj, const char *part)
112 {
113         c_retvm_if(!data, NULL, "data is null");
114         c_retvm_if(!obj, NULL, "obj is null");
115
116         cal_struct *cs = data;
117
118         cal_month_calendar_data* p = CAL_UTIL_GET_PRIV_DATA(obj);
119         c_retvm_if(!p, NULL, "p is null");
120
121         int r;
122         Evas_Object *icon = NULL;
123         cal_struct *calendar = NULL;
124
125         if (!CAL_STRCMP(part, "elm.swallow.colorbar"))
126         {
127                 r = CALENDAR_SVC_GET(CAL_STRUCT_CALENDAR, CALENDAR_SVC_STRUCT_GET_INT(cs,CAL_VALUE_INT_CALENDAR_ID), NULL, &calendar);
128                 if (r != CAL_SUCCESS)
129                 {
130                         ERR("CALENDAR_SVC_GET fail. %d", r);
131                         return NULL;
132                 }
133
134                 icon = evas_object_rectangle_add(evas_object_evas_get(obj));
135                 evas_object_size_hint_align_set(icon, EVAS_HINT_FILL, EVAS_HINT_FILL);
136
137                 CALENDAR_SVC_GET_CALENDAR_COLOR(calendar, &calendar_color);
138
139                 evas_object_color_set(icon, calendar_color.red, calendar_color.green, calendar_color.blue, calendar_color.alpha);
140
141                 CALENDAR_SVC_STRUCT_FREE(&calendar);
142
143                 return icon;
144         }
145
146         return NULL;
147 }
148
149 static void __cal_month_calendar_make_time_text(struct tm *tm_start, struct tm *tm, char *buf, int sz)
150 {
151         const char* date;
152         const char* time;
153
154         time = CAL_UTIL_TIME_FORMAT_6;
155
156         if (tm_start->tm_year != tm->tm_year)
157                 date = CAL_UTIL_DATE_FORMAT_11;
158         else if (tm_start->tm_mon != tm->tm_mon)
159                 date = CAL_UTIL_DATE_FORMAT_10;
160         else if (tm_start->tm_mday != tm->tm_mday)
161                 date = CAL_UTIL_DATE_FORMAT_9;
162         else
163                 date = NULL;
164
165         cal_util_get_time_text(buf, sz, NULL, time, tm_start);
166 }
167
168
169 static char* __cal_month_calendar_get_time_text(cal_struct *cs, cal_month_calendar_data *p)
170 {
171         char buf[512];
172         char stime[512];
173
174         struct tm tm_start;
175         cal_util_convert_lli_to_tm(NULL, CALENDAR_SVC_STRUCT_GET_LLI(cs, CALS_VALUE_LLI_DTSTART_UTIME), &tm_start);
176         __cal_month_calendar_make_time_text(&tm_start, &p->ad->base_tm, stime, sizeof(stime));
177
178         snprintf(buf, sizeof(buf), "%s", stime);
179
180         return strdup(buf);
181 }
182
183 static char* __cal_month_calendar_get_genlist_item_label(void *data, Evas_Object *obj, const char *part)
184 {
185         c_retvm_if(!data, NULL, "data is null");
186
187         const char *str;
188
189         cal_struct *cs = data;
190
191         if (!CAL_STRCMP(part, "elm.text.1")) {
192
193                 str = CALENDAR_SVC_STRUCT_GET_STR(cs, CAL_VALUE_TXT_SUMMARY);
194                 if (str)
195                         return strdup(str);
196
197                 return strdup(C_("IDS_CLD_BODY_NO_TITLE"));
198         }
199         else if (!CAL_STRCMP(part, "elm.text.2")) {
200
201                 str = CALENDAR_SVC_STRUCT_GET_STR(cs, CAL_VALUE_TXT_LOCATION);
202                 if (str)
203                         return strdup(str);
204
205                 return strdup(C_("IDS_CLD_BODY_NO_LOCATION_SELECTED"));
206         }
207         else if (!CAL_STRCMP(part, "elm.text.3")) {
208
209                 if (CALENDAR_SVC_STRUCT_GET_INT(cs, CALS_VALUE_INT_DTSTART_TYPE) == CALS_TIME_LOCALTIME)
210                         return strdup(C_("IDS_COM_BODY_ALL_DAY"));
211
212                 cal_month_calendar_data *p = CAL_UTIL_GET_PRIV_DATA(obj);
213                 c_retvm_if(!p, NULL, "p is null");
214
215                 return __cal_month_calendar_get_time_text(cs, p);
216         }
217
218         return NULL;
219 }
220
221 static int __cal_month_calendar_get_first_wday(int mday, int wday)
222 {
223         return CAL_UTIL_GET_WDAY(wday - mday + 1);
224 }
225
226 static void __cal_month_calendar_delete_layout(void *data, Evas *e, Evas_Object *obj, void *ei)
227 {
228         CAL_FN_START;
229
230         c_retm_if(!data, "data is null");
231         cal_month_calendar_data *p = data;
232
233         struct appdata *ad = p->ad;
234         c_retm_if(!ad, "ad is null");
235
236         if (ad->today_edj && ad->today_edj == CAL_UTIL_GET_EDJ_DATA(obj))
237                 ad->today_edj = NULL;
238
239         if (p->popup) {
240                 evas_object_del(p->popup);
241         }
242
243         __cal_month_calendar_clean_list(p);
244
245         free(p);
246
247         CAL_FN_END;
248 }
249
250 static inline void __cal_month_calendar_set_color(Evas_Object *ly, cal_month_calendar_data *p, int pos, int wday)
251 {
252         c_retm_if(!p, "p is null");
253
254         struct _day *d = &p->day[pos];
255
256         const char *day_color;
257
258         switch (wday) {
259         case 0:
260                 day_color = "sunday";
261                 d->d_type = CAL_MONTH_CALENDAR_DAY_TYPE_SUNDAY;
262                 break;
263         case 6:
264                 day_color = "satday";
265                 d->d_type = CAL_MONTH_CALENDAR_DAY_TYPE_SATDAY;
266                 break;
267         default:
268                 d->d_type = CAL_MONTH_CALENDAR_DAY_TYPE_WEEKDAY;
269                 day_color = "weekday";
270                 break;
271         }
272
273         cal_util_emit_signal(CAL_UTIL_GET_EDJ_DATA(ly), "%s,%d", day_color, pos);
274 }
275
276 static inline void __cal_month_calendar_set_disabled(Evas_Object *ly, cal_month_calendar_data *p, int pos)
277 {
278         struct _day *d = &p->day[pos];
279
280         cal_util_emit_signal(CAL_UTIL_GET_EDJ_DATA(ly), "disable,%d", pos);
281
282         d->enabled = 0;
283 }
284
285 static inline void __cal_month_calendar_set_enabled(Evas_Object *ly, cal_month_calendar_data *p, int pos, int wday)
286 {
287         struct _day *d = &p->day[pos];
288
289         if (!d->enabled) {
290                 cal_util_emit_signal(CAL_UTIL_GET_EDJ_DATA(ly), "enable,%d", pos);
291
292                 __cal_month_calendar_set_color(ly, p, pos, wday);
293                 d->enabled = 1;
294         }
295 }
296
297 static inline void __cal_month_calendar_set_today(Evas_Object *eo, int pos)
298 {
299         if (pos == -1)
300                 return;
301
302         cal_util_emit_signal(eo, "today,%d", pos);
303 }
304
305 static inline void __cal_month_calendar_unset_today(Evas_Object *eo, int *pos)
306 {
307         if (*pos == -1)
308                 return;
309
310         cal_util_emit_signal(eo, "notoday,%d", *pos);
311         *pos = -1;
312 }
313
314 static inline void __cal_month_calendar_set_selected(Evas_Object *eo, int pos)
315 {
316         if (pos < 0 || DAYS_OF_WEEKLY_MONTHS_VIEW <= pos)
317                 return;
318
319         cal_util_emit_signal(eo, "select,%d", pos);
320 }
321
322 static inline void __cal_month_calendar_set_unselected(cal_month_calendar_data* p, Evas_Object *eo, int *pos)
323 {
324         c_retm_if(!p, "p is NULL");
325         c_retm_if(-1 == *pos, "pos is invalid");
326         c_retm_if(!eo, "eo is invalid");
327
328         cal_util_emit_signal(eo, "unselect,%d", *pos);
329
330         __cal_month_calendar_set_day_default_color(p, eo, *pos);
331
332         *pos = -1;
333 }
334
335 static inline int __cal_month_calendar_get_start_day(int *st, struct tm *tm, int start, int max)
336 {
337         int day;
338         int prev_day;
339
340         prev_day = CAL_UTIL_GET_WDAY(__cal_month_calendar_get_first_wday(tm->tm_mday, tm->tm_wday) - start);
341         if (prev_day > 0) {
342                 day = max - prev_day + 1;
343                 *st = ST_PREV;
344         } else {
345                 day = 1;
346                 *st = ST_CURR;
347         }
348
349         return day;
350 }
351
352 static int __cal_month_calendar_update_today(Evas_Object *eo, cal_month_calendar_data *p)
353 {
354         c_retv_if(!eo, -1);
355         c_retv_if(!p, -1);
356
357         struct appdata *ad = p->ad;
358         c_retv_if(!ad, -1);
359
360         struct tm *base_tm = &ad->base_tm;
361         c_retv_if(!base_tm, -1);
362
363         __cal_month_calendar_unset_today(eo, &p->pos_today);
364
365         ad->today_edj = NULL;
366
367         if (base_tm->tm_year == ad->today_tm.tm_year && base_tm->tm_mon == ad->today_tm.tm_mon) {
368                 p->pos_today = p->pos_start + ad->today_tm.tm_mday - 1;
369                 __cal_month_calendar_set_today(eo, p->pos_today);
370                 ad->today_edj = eo;
371         }
372
373         return 0;
374 }
375
376 void cal_month_calendar_update_select(Evas_Object *ly)
377 {
378         CAL_ASSERT(ly);
379         Evas_Object* eo = CAL_UTIL_GET_EDJ_DATA(ly);
380
381         cal_month_calendar_data* p = CAL_UTIL_GET_PRIV_DATA(ly);
382         CAL_ASSERT(p);
383         CAL_ASSERT(p->ad);
384
385         cal_main_update_title_text(p->ad->title, CV_MONTH, &p->ad->base_tm, p->ad->wday_start);
386
387         __cal_month_calendar_set_unselected(p, eo, &p->pos_selected);
388         p->pos_selected = p->pos_start + p->ad->base_tm.tm_mday - 1;
389         __cal_month_calendar_set_selected(eo, p->pos_selected);
390
391 }
392
393 static void __cal_month_calendar_get_simple_check(cal_month_calendar_data *p, struct tm *tm_start, struct tm *tm_end, char *map, int map_sz)
394 {
395         c_ret_if(!p);
396
397         struct appdata *ad = p->ad;
398         c_ret_if(!ad);
399
400         int i = 0;
401         int *month = CALENDAR_SVC_GET_SIMPLE_CS(ad->acct_id, tm_start, tm_end);
402         c_ret_if(!month);
403
404         struct tm base_tm = ad->base_tm;
405
406         for (i = 0; i < cal_util_get_max_days(base_tm.tm_year, base_tm.tm_mon); i++) {
407                 if (month[i])
408                         map[i] = month[i];
409         }
410
411         free(month);
412 }
413
414 static void __cal_month_calendar_update_check(Evas_Object *ly, cal_month_calendar_data *p)
415 {
416         c_ret_if(!ly);
417         c_ret_if(!p);
418
419         struct appdata *ad = p->ad;
420         c_ret_if(!ad);
421
422         char m[DAYS_OF_WEEKLY_MONTHS_VIEW] = { 0 };
423
424         struct tm base_tm = ad->base_tm;
425
426         struct tm tm_start = base_tm;
427         tm_start.tm_hour = 0;
428         tm_start.tm_min = 0;
429         tm_start.tm_sec = 0;
430         cal_util_update_tm_day(&tm_start, 1 - tm_start.tm_mday);
431
432         struct tm tm_end = tm_start;
433         tm_end.tm_hour = 23;
434         tm_end.tm_min = 59;
435         tm_end.tm_sec = 59;
436         cal_util_update_tm_month(&tm_end, 1);
437         cal_util_update_tm_day(&tm_end, -1);
438
439         int max = cal_util_get_max_days(base_tm.tm_year, base_tm.tm_mon);
440
441         __cal_month_calendar_get_simple_check(p, &tm_start, &tm_end, &m[p->pos_start], max);
442
443         int i;
444         for (i = 0; i < DAYS_OF_WEEKLY_MONTHS_VIEW; i++) {
445                 if (p->ad->is_weekly || p->ad ->is_landscape_mode) {
446                         __cal_month_calendar_set_more_text(ly, m[i], i);
447                 } else {
448                         __cal_month_calendar_set_check_text(ly, p, m[i], i);
449                 }
450         }
451 }
452
453 static int __cal_month_calendar_fill_calendar(Evas_Object *ly, int wday)
454 {
455         c_retv_if(!ly, -1);
456
457         cal_month_calendar_data *p = CAL_UTIL_GET_PRIV_DATA(ly);
458         c_retv_if(!p, -1);
459
460         struct appdata *ad = p->ad;
461         c_retv_if(!ad, -1);
462
463         struct tm base_tm = ad->base_tm;
464
465         int prev_max = cal_util_get_max_days(base_tm.tm_year, base_tm.tm_mon - 1);
466         int cur_max = cal_util_get_max_days(base_tm.tm_year, base_tm.tm_mon);
467
468         int st;
469         int day = __cal_month_calendar_get_start_day(&st, &base_tm, wday, prev_max);
470
471         p->pos_start = 0;
472         p->pos_end = 41;
473
474         int i;
475         int line = WEEKS_OF_MONTH;
476
477         for (i = 0; i < DAYS_OF_WEEKLY_MONTHS_VIEW; i++) {
478                 cal_util_set_text(CAL_UTIL_GET_EDJ_DATA(ly), cal_util_get_part_text("db/%d/text", i), "%d", day);
479
480                 switch (st) {
481
482                 case ST_PREV:
483                         __cal_month_calendar_set_disabled(ly, p, i);
484                         if (day == prev_max) {
485                                 st = ST_CURR;
486                                 day = 0;
487                                 p->pos_start = i + 1;
488                         }
489                         break;
490
491                 case ST_CURR:
492                         __cal_month_calendar_set_enabled(ly, p, i, wday);
493                         if (day == cur_max) {
494                                 st = ST_NEXT;
495                                 day = 0;
496                                 line = (int)(i / DAYS_OF_WEEK) + 1;
497                                 p->pos_end = i;
498                         }
499                         break;
500
501                 case ST_NEXT:
502                         __cal_month_calendar_set_disabled(ly, p, i);
503                         break;
504                 }
505
506                 day++;
507                 wday = CAL_UTIL_GET_WDAY(wday + 1);
508         }
509
510         __cal_month_calendar_update_today(CAL_UTIL_GET_EDJ_DATA(ly), p);
511
512         __cal_month_calendar_fill_week_number(ly);
513
514         return line;
515 }
516
517 static void __cal_month_calendar_click_event_callback(cal_month_calendar_data *p, Evas_Object *obj, int pos)
518 {
519         c_ret_if(!p);
520
521         struct appdata *ad = p->ad;
522         c_ret_if(!ad);
523
524         if (p->pos_selected == pos) {
525                 DBG("cal_cb: double clicked %d", pos);
526
527                 if (p->ad->is_weekly || p->ad ->is_landscape_mode)
528                         return;
529
530                 if (p->day[pos].checked) {
531                         __cal_month_calendar_events_of_one_weekday(p);
532                 } else {
533                         ad->base_hour = -1;
534                         ad->cid = 0;
535
536                         cal_edit_create_view(ad, p->parent);
537                 }
538
539                 return;
540         }
541
542         ad->base_tm.tm_mday = pos - p->pos_start + 1;
543
544         cal_month_calendar_update_select(p->month);
545
546         edje_object_signal_emit(obj, "changed", "prog");
547 }
548
549 static void __cal_month_calendar_cal_event_callback(void *data, Evas_Object *obj, const char *e, const char *src)
550 {
551         cal_month_calendar_data *p = data;
552         c_retm_if(!p, "p is null");
553
554         struct appdata *ad = p->ad;
555         c_retm_if(!ad, "ad is null");
556
557         int pos = atoi(&e[3]);
558         c_retm_if((p->pos_end < pos) || (pos < p->pos_start), "pos is diabled");
559
560         if (!strncmp(e, "up,", 3)) {
561
562                 if (p->pos_down == pos) {
563                         __cal_month_calendar_click_event_callback(p, obj, pos);
564                 }
565
566                 edje_object_signal_emit(obj, e, "prog");
567
568         }else if (!strncmp(e, "dn,", 3)) {
569
570                 p->pos_down = pos;
571
572                 edje_object_signal_emit(obj, e, "prog");
573         }
574 }
575
576 static void __cal_month_calendar_prog_event_callback(void *data, Evas_Object *obj, const char *e, const char *src)
577 {
578         cal_month_calendar_data *p = data;
579
580         if (!CAL_STRCMP(e, "update_today")) {
581                 __cal_month_calendar_update_today(obj, p);
582                 return;
583         }
584
585         if (CAL_STRCMP(e, "moved")) {
586                 return;
587         }
588
589         if (p->pos_down == -1) {
590                 return;
591         }
592
593         cal_util_emit_signal(obj, "up,%d", p->pos_down);
594         if (p->pos_selected!= p->pos_down) {
595                 __cal_month_calendar_set_day_default_color(p, obj, p->pos_down);
596                 cal_util_emit_signal(obj, "unselect,%d", p->pos_down);
597         }
598         p->pos_down = -1;
599 }
600
601 static void __cal_month_calendar_set_wday_text(Evas_Object *ly, int start)
602 {
603         c_ret_if(!ly);
604
605         cal_month_calendar_data* p = CAL_UTIL_GET_PRIV_DATA(ly);
606         c_ret_if(!p);
607
608         struct appdata *ad = p->ad;
609         c_ret_if(!ad);
610
611         struct tm base_tm = ad->base_tm;
612
613         cal_util_update_tm_day(&base_tm, base_tm.tm_wday*(-1)+start);
614
615         int i;
616         for (i = 0; i < DAYS_OF_WEEK; i++) {
617                 cal_util_set_time_text(CAL_UTIL_GET_EDJ_DATA(ly), cal_util_get_part_text("wday/%d/text", i), CAL_UTIL_DATE_FORMAT_2, NULL, &base_tm);
618
619                 if (base_tm.tm_wday == 6)
620                         cal_util_emit_signal(CAL_UTIL_GET_EDJ_DATA(ly), "satday,%d", i);
621
622                 if (base_tm.tm_wday == 0)
623                         cal_util_emit_signal(CAL_UTIL_GET_EDJ_DATA(ly), "sunday,%d", i);
624
625                 cal_util_update_tm_day(&base_tm, 1);
626         }
627
628         edje_object_part_text_set(CAL_UTIL_GET_EDJ_DATA(ly),  "wday/weeknumber/text", "W");
629 }
630
631 static gint __cal_month_calendar_events_compare(gconstpointer a,gconstpointer b)
632 {
633         cal_month_calendar_weekly_event *p1 = (cal_month_calendar_weekly_event *)a;
634         cal_month_calendar_weekly_event *p2 = (cal_month_calendar_weekly_event *)b;
635
636         if (p2->start_time < p1->start_time)
637                 return 1;
638         else if(p1->start_time < p2->start_time)
639                 return -1;
640         else
641                 return 0;
642 }
643
644 static void __cal_month_calendar_signal_clean(cal_month_calendar_data *p,Evas_Object *eo)
645 {
646         c_retm_if(!p, "p is null");
647         c_retm_if(!eo, "eo is null");
648
649         int i = 0;
650         int line = 0;
651
652         for (i = 0; i < DAYS_OF_WEEK; i++) {
653                 for (line = 1; line <= WEEKS_OF_MONTH; line++) {
654                         cal_util_emit_signal(eo, "%d,%d,%d", line, 0, i);
655                         cal_util_emit_signal(eo, "%d,%s,%d", line, "nocolor", i);
656                 }
657         }
658
659 }
660
661 static int __cal_month_calendar_clean_list(cal_month_calendar_data *p)
662 {
663         c_retvm_if(!p, -1, "p is null");
664
665         int i = 0;
666         int k = 0;
667
668         for (k = 0; k < WEEKS_OF_MONTH; k++) {
669                 for (i = 0; i < DAYS_OF_WEEK; i++) {
670                         g_list_free(p->week_event_list[k][i]);
671                         p->week_event_list[k][i] = NULL;
672                 }
673         }
674         return 0;
675 }
676
677 static int __cal_month_calendar_get_week_time(cal_month_calendar_data *p, int *first_day, int *last_day)
678 {
679         int day = 0;
680         int today = 0;
681         int start_day = 0;
682
683         if(-1 == p->pos_selected)
684                 day = p->pos_today;
685         else
686                 day = p->pos_selected;
687
688         today = day - p->pos_start + 1;
689         start_day = day - ((day + 1) % DAYS_OF_WEEK) + 1;
690
691         if (day < DAYS_OF_WEEK) {
692                 *first_day = 1;
693                 *last_day = DAYS_OF_WEEK - p->pos_start;
694         } else if (0 == ((day + 1) % DAYS_OF_WEEK)) {
695                 *first_day = today - DAYS_OF_WEEK + 1;
696                 *last_day = today;
697         } else {
698                 *first_day = today - (day % DAYS_OF_WEEK);
699                 if ((start_day + DAYS_OF_WEEK - 1) > p->pos_end) {
700                         *last_day = p->pos_end - p->pos_start + 1;
701                 } else {
702                         *last_day = *first_day + DAYS_OF_WEEK - 1;
703                 }
704         }
705
706         return 0;
707 }
708
709 static bool __cal_month_calendar_is_last(GList* event_list[][DAYS_OF_WEEK], int list_index)
710 {
711         c_retvm_if(!event_list, FALSE, "event_list is null");
712         c_retvm_if(WEEKS_OF_MONTH <= list_index, FALSE, "list_index is invalid");
713
714         int i = 0;
715
716         for (i = 0; i < DAYS_OF_WEEK; i++) {
717                 if (event_list[list_index][i])
718                         return TRUE;
719         }
720
721         return FALSE;
722 }
723
724 static void __cal_month_calendar_line_arrange(GList* event_list[][DAYS_OF_WEEK],int index,const int line, int list_index)
725 {
726         c_retm_if(!event_list, "event_list is null");
727         c_retm_if(DAYS_OF_WEEK <= index, "index is invalid");
728         c_retm_if(WEEKS_OF_MONTH <= list_index, "list_index is invalid");
729
730         cal_month_calendar_weekly_event *temp = NULL;
731         GList *list_temp = event_list[list_index][index];
732
733         if (list_temp && list_temp->data) {
734                 temp = list_temp->data;
735                 temp->line = line;
736                 temp->showed = 1;
737
738                 if (0 == temp->width)
739                         temp->width = 1;
740
741                 if (DAYS_OF_WEEK <= index + temp->width)
742                         return;
743
744                 __cal_month_calendar_line_arrange(event_list, index + temp->width, line, list_index);
745         } else {
746                 if (DAYS_OF_WEEK <= index + 1)
747                         return;
748
749                 __cal_month_calendar_line_arrange(event_list, index + 1, line, list_index);
750         }
751 }
752
753 static void __cal_month_calendar_get_next(GList* event_list[][DAYS_OF_WEEK], int list_index)
754 {
755         c_retm_if(!event_list, "event_list is null");
756
757         int i = 0;
758         cal_month_calendar_weekly_event *temp = NULL;
759
760         for (i = 0; i < DAYS_OF_WEEK; i++) {
761
762                 if (event_list[list_index][i] && event_list[list_index][i]->data) {
763
764                         temp = (cal_month_calendar_weekly_event*)event_list[list_index][i]->data;
765
766                         if (temp->showed)
767                                 event_list[list_index][i] = event_list[list_index][i]->next;
768                 }
769         }
770 }
771
772 static int __cal_month_calendar_get_weekly_events(cal_month_calendar_data *p)
773 {
774         c_retv_if(!p, -1);
775
776         struct appdata *ad = p->ad;
777         c_retv_if(!ad, -1);
778
779         int week = 0;
780
781         __cal_month_calendar_signal_all_clean(p);
782
783         __cal_month_calendar_clean_list(p);
784
785         for (week = 0; week < WEEKS_OF_MONTH; week++) {
786
787                 int line = 1;
788                 int start_day = 0;
789                 int end_day = 0;
790
791                 cal_iter *iter = NULL;
792                 cal_struct *record = NULL;
793                 cal_month_calendar_weekly_event *event = NULL;
794                 struct tm end_time = {0};
795                 struct tm start_time = {0};
796                 struct tm st = {0};
797                 struct tm et = {0};
798
799                 int wday = 0;
800                 int wday_start = ad->wday_start;
801                 long long int lli_start, lli_end;
802
803                 __cal_month_calendar_get_day_time_by_pos(p, &start_day, &end_day, &start_time, &end_time, (week + 1) * DAYS_OF_WEEK - 1);
804
805                 int day_num = end_time.tm_wday - start_time.tm_wday + 1;
806
807                 cal_util_convert_tm_to_lli(NULL, &start_time, &lli_start);
808                 cal_util_convert_tm_to_lli(NULL, &end_time, &lli_end);
809
810 // TODO: Change calendar_id to defined constants
811
812                 int r = calendar_svc_event_get_normal_list_by_period(-1, CALS_LIST_PERIOD_NORMAL_OSP, lli_start, lli_end, &iter);
813                 c_retvm_if(r != CAL_SUCCESS, -1, "calendar_svc_event_get_normal_list_by_period is failed(%d)", r);
814
815                 while (CAL_SUCCESS == CALENDAR_SVC_ITER_NEXT(iter)) {
816
817                         CALENDAR_SVC_ITER_GET_INFO(iter,&record);
818
819                         event = calloc(1, sizeof(cal_month_calendar_weekly_event));
820                         c_retvm_if(!event, -1, "event is null");
821
822                         event->calendar_id = CALENDAR_SVC_STRUCT_GET_INT(record, CAL_VALUE_INT_CALENDAR_ID);
823
824                         g_snprintf(event->title, sizeof(event->title), "%s", CALENDAR_SVC_STRUCT_GET_STR(record,CAL_VALUE_TXT_SUMMARY));
825
826                         cal_util_convert_lli_to_time_t(NULL, CALENDAR_SVC_STRUCT_GET_LLI(record, CALS_VALUE_LLI_DTSTART_UTIME), &event->start_time);
827                         cal_util_convert_lli_to_time_t(NULL, CALENDAR_SVC_STRUCT_GET_LLI(record, CALS_VALUE_LLI_DTEND_UTIME), &event->end_time);
828                         cal_util_convert_lli_to_tm(NULL, CALENDAR_SVC_STRUCT_GET_LLI(record, CALS_VALUE_LLI_DTSTART_UTIME), &st);
829                         cal_util_convert_lli_to_tm(NULL, CALENDAR_SVC_STRUCT_GET_LLI(record, CALS_VALUE_LLI_DTSTART_UTIME), &et);
830
831                         event->width = et.tm_wday - st.tm_wday + 1;
832                         if (event->width < 1)
833                                 event->width = 1;
834
835                         wday = st.tm_wday - wday_start;
836                         if (wday < 0)
837                                 wday += 7;
838
839                         p->week_event_list[week][wday] = g_list_append(p->week_event_list[week][wday], event);
840                 }
841
842                 if (record)
843                         r = CALENDAR_SVC_STRUCT_FREE(&record);
844
845                 if (iter)
846                         CALENDAR_SVC_ITER_REMOVE(&iter);
847
848                 st.tm_hour = 0;
849                 st.tm_min = 0;
850                 st.tm_sec = 0;
851
852                 et.tm_hour = 23;
853                 et.tm_min = 59;
854                 et.tm_sec = 59;
855
856                 record = NULL;
857
858                 r = calendar_svc_event_get_allday_list_by_period(-1, CALS_LIST_PERIOD_ALLDAY_OSP,
859                         start_time.tm_year + 1900, start_time.tm_mon + 1, start_time.tm_mday,
860                         end_time.tm_year + 1900, end_time.tm_mon + 1, end_time.tm_mday, &iter);
861                 c_retvm_if(r != CAL_SUCCESS, -1, "calendar_svc_event_get_allday_list_by_period is failed(%d)", r);
862
863                 while (CAL_SUCCESS == CALENDAR_SVC_ITER_NEXT(iter)) {
864
865                         r = CALENDAR_SVC_ITER_GET_INFO(iter, &record);
866                         c_retvm_if(r != CAL_SUCCESS, -1, "CALENDAR_SVC_ITER_GET_INFO is failed(%d)", r);
867
868                         event = calloc(1, sizeof(cal_month_calendar_weekly_event));
869                         c_retvm_if(!event, -1, "event is null");
870
871                         event->calendar_id = CALENDAR_SVC_STRUCT_GET_INT(record, CAL_VALUE_INT_CALENDAR_ID);
872
873                         g_snprintf(event->title, sizeof(event->title), "%s", CALENDAR_SVC_STRUCT_GET_STR(record,CAL_VALUE_TXT_SUMMARY));
874
875                         st.tm_year = et.tm_year = CALENDAR_SVC_STRUCT_GET_INT(record, CALS_VALUE_INT_DTSTART_YEAR) - 1900;
876                         st.tm_mon = et.tm_mon = CALENDAR_SVC_STRUCT_GET_INT(record, CALS_VALUE_INT_DTSTART_MONTH) - 1;
877                         st.tm_mday = et.tm_mday = CALENDAR_SVC_STRUCT_GET_INT(record, CALS_VALUE_INT_DTSTART_MDAY);
878
879                         event->start_time = mktime(&st);
880                         event->end_time = mktime(&et);
881
882                         st = *localtime(&event->start_time);
883
884                         event->width = 1;
885
886                         wday = st.tm_wday - wday_start;
887                         if (wday < 0)
888                                 wday += 7;
889
890                         p->week_event_list[week][wday] = g_list_append(p->week_event_list[week][wday], event);
891                 }
892
893                 if (record)
894                         CALENDAR_SVC_STRUCT_FREE(&record);
895
896                 if (iter)
897                         CALENDAR_SVC_ITER_REMOVE(&iter);
898
899                 for (wday = 0; wday < day_num; wday++) {
900                         if (p->week_event_list[week][wday])
901                                 p->week_event_list[week][wday] = g_list_sort(p->week_event_list[week][wday], __cal_month_calendar_events_compare);
902                 }
903
904                 GList* list_t[WEEKS_OF_MONTH][DAYS_OF_WEEK];
905
906                 for (wday = 0 ; wday < DAYS_OF_WEEK; wday++)
907                         list_t[week][wday] = p->week_event_list[week][wday];
908
909                 while (__cal_month_calendar_is_last(p->week_event_list, week)) {
910
911                         __cal_month_calendar_line_arrange(p->week_event_list, 0, line, week);
912
913                         line++;
914
915                         if ( (p->ad->is_landscape_mode ? LINES_OF_WEEKLY_MONTHS_EVENT_LANDSCAPE : LINES_OF_WEEKLY_MONTHS_EVENT) < line)
916                                 break;
917
918                         __cal_month_calendar_get_next(p->week_event_list, week);
919                 }
920
921                 for (wday = 0; wday < DAYS_OF_WEEK; wday++)
922                         p->week_event_list[week][wday] = list_t[week][wday];
923         }
924
925         return 0;
926 }
927
928 static void __cal_month_calendar_signal_week(cal_month_calendar_data *p, Evas_Object *obj, int week)
929 {
930         c_ret_if(!p);
931         c_ret_if(!obj);
932
933         int wday = 0;
934         cal_month_calendar_weekly_event *event = NULL;
935         char text[20] = {0};
936         GList* event_list = NULL;
937
938         Evas_Object *eo = CAL_UTIL_GET_EDJ_DATA(obj);
939         c_ret_if(!eo);
940
941         for (wday = 0; wday < DAYS_OF_WEEK; wday++) {
942
943                 if (!p->week_event_list[week][wday])
944                         continue;
945
946                 event_list = g_list_first( p->week_event_list[week][wday]);
947
948                 while (event_list && event_list->data) {
949                         event = event_list->data;
950
951                         cal_util_emit_signal(eo, "%d,%d,%d", event->line, event->width, wday);
952                         cal_util_emit_signal(eo, "%d,show,%d", event->line, wday);
953
954                         __cal_month_calendar_set_event_rect_color(obj, p, event->line, wday, event->calendar_id);
955
956                         memset(text,0x00,sizeof(text));
957                         g_snprintf(text, sizeof(text), "%d/text/%d", event->line, wday);
958                         edje_object_part_text_set(eo, text, event->title);
959
960                         event_list = event_list->next;
961                 }
962         }
963 }
964
965 static void __cal_month_calendar_mouse_down(void *data, Evas *e, Evas_Object *ly, void *ei)
966 {
967         c_retm_if(!data, "p is null");
968         c_retm_if(!ly, "ly is null");
969         c_retm_if(!ei, "ei is null");
970
971         cal_month_calendar_data *p = data;
972         Evas_Event_Mouse_Down *ev = ei;
973         char eve[8] = {0};
974         int offset = 0;
975
976         int list_index = (int)evas_object_data_get(ly, "list_index");
977         p->base_pos_for_weekly = list_index * DAYS_OF_WEEK;
978
979         Evas_Coord_Rectangle r;
980         cal_util_get_geometry(&r, ly);
981         offset = ev->canvas.x / (r.w / DAYS_OF_WEEK);
982         if (DAYS_OF_WEEK <= offset)
983                 offset = DAYS_OF_WEEK - 1;
984
985         p->down_x = ev->canvas.x;
986         p->down_y = ev->canvas.y;
987
988         if (p->day[p->base_pos_for_weekly + offset].enabled) {
989                 p->index_for_press = p->base_pos_for_weekly + offset;
990                 snprintf(eve, sizeof(eve) , "dn,%d", p->index_for_press);
991                 edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(p->month), eve, "cal");
992         }
993 }
994
995 static void __cal_month_calendar_mouse_move(void *data, Evas *e, Evas_Object *ly, void *ei)
996 {
997         c_retm_if(!data, "data is null");
998         c_retm_if(!ly, "ly is null");
999         c_retm_if(!ei, "ei is null");
1000
1001         cal_month_calendar_data *p = data;
1002         Evas_Event_Mouse_Move *ev = ei;
1003         char eve[8] = {0};
1004         Evas_Coord th = elm_finger_size_get();
1005         Evas_Coord dx;
1006         Evas_Coord dy;
1007
1008         dx = ev->cur.canvas.x - p->down_x ;
1009         dy = p->down_y - ev->cur.canvas.y;
1010         if (dy > th ||  dy < (th * -1) || dx > th ||  dx < (th * -1)) {
1011
1012                 if( -1 != p->index_for_press) {
1013                         snprintf(eve, sizeof(eve) , "up,%d", p->index_for_press);
1014                         edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(p->month), eve, "prog");
1015                         if (p->pos_selected != p->index_for_press) {
1016                                 __cal_month_calendar_set_day_default_color(p, CAL_UTIL_GET_EDJ_DATA(p->month), p->index_for_press);
1017                                 cal_util_emit_signal(CAL_UTIL_GET_EDJ_DATA(p->month), "unselect,%d", p->index_for_press);
1018                         }
1019                         p->index_for_press = -1;
1020                 }
1021         }
1022 }
1023
1024 static bool __cal_month_calendar_check_event_exists(GList* event_list[][DAYS_OF_WEEK], int index, int list_index)
1025 {
1026         c_retvm_if(!event_list, FALSE, "data is null");
1027         c_retvm_if(DAYS_OF_WEEK <= index, FALSE, "index is invalid");
1028         c_retvm_if(WEEKS_OF_MONTH <= list_index, FALSE, "list_index is invalid");
1029
1030         int i = 0;
1031         GList *list_temp = NULL;
1032         cal_month_calendar_weekly_event *event = NULL;
1033
1034         for (i=0; i<=index; i++) {
1035                 if (NULL == event_list[list_index][i])
1036                         continue;
1037
1038                 list_temp = g_list_first(event_list[list_index][i]);
1039                 while (NULL != list_temp) {
1040                         event = list_temp->data;
1041                         if (NULL == event) {
1042                                 list_temp = g_list_next(list_temp);
1043                                 continue;
1044                         }
1045
1046                         if (index - i + 1 <= event->width)
1047                                 return TRUE;
1048
1049                         list_temp = g_list_next(list_temp);
1050                 }
1051         }
1052
1053         return FALSE;
1054 }
1055
1056 static void __cal_month_calendar_genlist_item_select_callback(void *data, Evas_Object *obj, void *ei)
1057 {
1058         c_ret_if(!data);
1059         c_ret_if(!obj);
1060
1061         cal_struct *cs = data;
1062
1063         Elm_Object_Item *it = elm_genlist_selected_item_get(obj);
1064         if (it)
1065                 elm_genlist_item_selected_set(it, EINA_FALSE);
1066
1067         cal_month_calendar_data *p = CAL_UTIL_GET_PRIV_DATA(obj);
1068         c_ret_if(!p);
1069
1070         cal_main_set_cs(p->ad, cs);
1071
1072         cal_detail_create_view(p->ad, p->parent);
1073
1074         if (p->popup)
1075                 evas_object_hide(p->popup);
1076 }
1077
1078 static void __cal_month_calendar_get_events(cal_month_calendar_data *p)
1079 {
1080         struct tm tm_start = p->ad->base_tm;
1081         tm_start.tm_hour = 0;
1082         tm_start.tm_min = 0;
1083         tm_start.tm_sec = 0;
1084
1085         struct tm tm_end = tm_start;
1086         tm_end.tm_hour = 23;
1087         tm_end.tm_min = 59;
1088         tm_end.tm_sec = 59;
1089
1090         p->event_list = CALENDAR_SVC_GET_EVENT_LIST(&tm_start, &tm_end);
1091 }
1092
1093 static void __cal_month_calendar_update_genlist(cal_month_calendar_data *p)
1094 {
1095         CAL_FN_START;
1096
1097         c_retm_if(!p, "p is null");
1098         c_retm_if(!p->gl, "p->gl is null");
1099
1100         Eina_List *l;
1101         cal_struct *cs = NULL;
1102         Elm_Object_Item *it = NULL;
1103         elm_genlist_clear(p->gl);
1104
1105         CALENDAR_SVC_FREE_CS_LIST(&p->event_list);
1106
1107         __cal_month_calendar_get_events(p);
1108         c_retm_if(!p->event_list, "p->event_list is null");
1109
1110         EINA_LIST_FOREACH(p->event_list, l, cs) {
1111                 if (cs) {
1112                         it = elm_genlist_item_append(p->gl, &itc, cs, NULL, ELM_GENLIST_ITEM_NONE, __cal_month_calendar_genlist_item_select_callback, cs);
1113                         c_retm_if(!it, "elm_genlist_item_append() returned null");
1114                 }
1115         }
1116
1117         CAL_FN_END;
1118 }
1119
1120 static void __cal_month_calendar_popup_response_callback(void *data, Evas_Object *obj, void *ei)
1121 {
1122         c_retm_if(!data, "data is null");
1123
1124         Evas_Object *popup = data;
1125
1126         evas_object_hide(popup);
1127 }
1128
1129 static void __cal_month_calendar_events_of_one_weekday(void *data)
1130 {
1131         c_retm_if(!data, "data is null");
1132
1133         cal_month_calendar_data *p = data;
1134         c_retm_if(!p->parent, "p->parent is null");
1135
1136         struct appdata *ad = p->ad;
1137         c_ret_if(!ad);
1138
1139         char title[128] = {0};
1140         cal_struct *cs = NULL;
1141
1142         if (!p->event_list) {
1143                 CALENDAR_SVC_FREE_CS_LIST(&p->event_list);
1144         }
1145
1146         __cal_month_calendar_get_events(p);
1147         c_retm_if(!p->event_list, "p->event_list is null");
1148
1149         int count = eina_list_count(p->event_list);
1150         if (2 <= count) {
1151                 cal_util_get_time_text(title, sizeof(title), CAL_UTIL_DATE_FORMAT_13, NULL, &p->ad->base_tm);
1152
1153                 if (!p->popup) {
1154                         p->popup = cal_util_add_popup(ad->win, "menustyle", title, NULL,
1155                                 __cal_month_calendar_popup_response_callback, p,
1156                                 S_("IDS_COM_BODY_CLOSE"), NULL);
1157
1158                         c_retm_if(!p->popup, "cal_util_add_popup returned null");
1159                 } else {
1160                         elm_object_part_text_set(p->popup, "title,text", title);
1161                         evas_object_show(p->popup);
1162                 }
1163
1164                 if (!p->gl) {
1165                         p->gl = elm_genlist_add(p->popup);
1166                         evas_object_data_set(p->gl, "priv", p);
1167                         evas_object_show(p->gl);
1168                         elm_object_content_set(p->popup, p->gl);
1169                 }
1170         } else if (1 == count) {
1171                 cs = eina_list_data_get(p->event_list);
1172                 c_retm_if(!cs, "cs is null");
1173
1174                 cal_main_set_cs(p->ad, cs);
1175
1176                 cal_detail_create_view(p->ad, p->parent);
1177         }
1178         __cal_month_calendar_update_genlist(p);
1179 }
1180
1181 static void __cal_month_calendar_mouse_up(void *data, Evas *e, Evas_Object *ly, void *ei)
1182 {
1183         c_retm_if(!data, "data is null");
1184         c_retm_if(!ly, "ly is null");
1185
1186         cal_month_calendar_data *p = data;
1187         Evas_Event_Mouse_Down *ev = ei;
1188         int start_day = 0;
1189         int end_day = 0;
1190         int num_of_enable = 0;
1191         char eve[8] = {0};
1192         int list_index = 0;
1193         int i = 0;
1194
1195         list_index = (int)evas_object_data_get(ly, "list_index");
1196
1197         c_retm_if(-1 == p->index_for_press, "p->index_for_press is -1");
1198
1199         Evas_Coord_Rectangle r;
1200         cal_util_get_geometry (&r, ly);
1201         int day_width = r.w / DAYS_OF_WEEK;
1202
1203         snprintf(eve, sizeof(eve) , "up,%d", p->index_for_press);
1204         edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(p->month), eve, "cal");
1205
1206         if (p->pos_selected != p->index_for_press) {
1207                 p->index_for_press = -1;
1208                 return;
1209         }
1210
1211         p->index_for_press = -1;
1212
1213         __cal_month_calendar_get_week_time(p,&start_day,&end_day);
1214
1215         if (DAYS_OF_WEEK != (num_of_enable = end_day - start_day + 1)) {
1216
1217                 if (end_day < DAYS_OF_WEEK) {
1218
1219                         if (ev->canvas.x < (DAYS_OF_WEEK- num_of_enable) * day_width)
1220                                 return;
1221
1222                         start_day -= (DAYS_OF_WEEK - num_of_enable);
1223                 } else if (DAYS_OF_WEEK < start_day) {
1224
1225                         if (ev->canvas.x > num_of_enable * day_width)
1226                                 return;
1227                 }
1228         }
1229
1230         for (i = 0; i < DAYS_OF_WEEK; i++) {
1231                 if (ev->canvas.x > i*day_width && ev->canvas.x < (i+1)*day_width) {
1232                         p->ad->base_tm.tm_mday = start_day + i;
1233                         if (!__cal_month_calendar_check_event_exists(p->week_event_list, i, list_index)) {
1234                                 p->ad->base_hour = -1;
1235                                 p->ad->cid = 0;
1236                                 cal_edit_create_view(p->ad, p->parent);
1237                         } else {
1238                                 __cal_month_calendar_events_of_one_weekday(p);
1239                         }
1240                 }
1241         }
1242 }
1243
1244 Evas_Object* cal_month_calendar_create_view(struct appdata *ad,
1245                 Evas_Object *main, Eina_Bool tmp)
1246 {
1247         c_retv_if(!ad, NULL);
1248         c_retv_if(!main, NULL);
1249
1250         cal_month_calendar_data *p = calloc(1, sizeof(cal_month_calendar_data));
1251         c_retv_if(!p, NULL);
1252
1253         p->ad = ad;
1254         p->parent = main;
1255         p->pos_down = p->pos_today = p->pos_selected = -1;
1256         p->pos_start = p->pos_end = -1;
1257         p->index_for_press = -1;
1258
1259         if (ad->is_weekly || ad ->is_landscape_mode) {
1260                 p->name = _name = "main/month/cal/weekly";
1261         } else {
1262                 p->name = _name = "main/month/cal";
1263         }
1264
1265         Evas_Object *ly = cal_util_add_layout(ad->nv, p->name);
1266         if (!ly) {
1267                 ERR("ly is null");
1268                 free(p);
1269                 return NULL;
1270         }
1271
1272         p->month = ly;
1273         evas_object_data_set(ly, "priv", p);
1274         edje_object_signal_callback_add(CAL_UTIL_GET_EDJ_DATA(ly), "*", "cal", __cal_month_calendar_cal_event_callback, p);
1275         edje_object_signal_callback_add(CAL_UTIL_GET_EDJ_DATA(ly), "*", "prog", __cal_month_calendar_prog_event_callback, p);
1276
1277         __cal_month_calendar_set_wday_text(ly, ad->wday_start);
1278
1279         if (tmp == EINA_TRUE) {
1280                 p->weekline = __cal_month_calendar_fill_calendar(ly, ad->wday_start);
1281                 __cal_month_calendar_update_check(ly, p);
1282         }
1283
1284         if (p->ad->is_weekly || p->ad ->is_landscape_mode) {
1285                 __cal_month_calendar_create_event_lists(ly, p);
1286
1287                 __cal_month_calendar_get_weekly_events(p);
1288         }
1289
1290         if (ad->is_display_weeknumber)
1291                 cal_util_emit_signal(CAL_UTIL_GET_EDJ_DATA(ly), "display_week_number");
1292
1293         evas_object_event_callback_add(ly, EVAS_CALLBACK_DEL, __cal_month_calendar_delete_layout, p);
1294
1295         return ly;
1296 }
1297
1298 void cal_month_calendar_update_view(Evas_Object *ly)
1299 {
1300         CAL_FN_START;
1301
1302         c_ret_if(!ly);
1303
1304         cal_month_calendar_data *p = CAL_UTIL_GET_PRIV_DATA(ly);
1305         if (!p || CAL_STRCMP(p->name, _name)) {
1306                 ERR("update month calendar: Invalid object");
1307                 return;
1308         }
1309
1310         struct appdata *ad = p->ad;
1311         c_ret_if(!ad);
1312
1313         p->weekline = __cal_month_calendar_fill_calendar(ly, ad->wday_start);
1314
1315         __cal_month_calendar_update_check(ly, p);
1316
1317         if (p->ad->is_weekly || p->ad ->is_landscape_mode) {
1318                 __cal_month_calendar_get_weekly_events(p);
1319
1320                 __cal_month_calendar_signal_all_week(p);
1321         }
1322
1323         cal_month_calendar_update_select(ly);
1324
1325         CAL_FN_END;
1326 }
1327
1328 int cal_month_calendar_get_weekline(Evas_Object *ly)
1329 {
1330         cal_month_calendar_data *p;
1331
1332         CAL_ASSERT(ly);
1333
1334         p = CAL_UTIL_GET_PRIV_DATA(ly);
1335         if (!p || CAL_STRCMP(p->name, _name)) {
1336                 ERR("get weekline: Invalid object");
1337                 return 6;
1338         }
1339
1340         return p->weekline;
1341 }
1342
1343 static int __cal_month_calendar_get_day_time_by_pos(cal_month_calendar_data *p, int *first_day, int *last_day, struct tm *start_time, struct tm *end_time, int day_pos)
1344 {
1345         c_retv_if(!p, -1);
1346
1347         int day = 0;
1348         int today = 0;
1349         int start_day = 0;
1350         int r = 0;
1351         int day_tmp = 0;
1352
1353         if (-1 != day_pos) {
1354                 day = CAL_MONTH_CALENDAR_LAST_LINE_POS_INDEX <= day_pos ? p->pos_end : day_pos;
1355         } else if (-1 == p->pos_selected) {
1356                 day = p->pos_today;
1357         } else {
1358                 day = p->pos_selected;
1359         }
1360
1361         day_tmp = day + 1;
1362         today = day - p->pos_start + 1;
1363         start_day = day - (day_tmp % DAYS_OF_WEEK) + 1;
1364
1365         if (day < DAYS_OF_WEEK) {
1366                 *first_day = 1;
1367                 *last_day = DAYS_OF_WEEK - p->pos_start;
1368         } else if (0 == (day_tmp % DAYS_OF_WEEK)) {
1369                 *first_day = today - DAYS_OF_WEEK + 1;
1370                 *last_day = today;
1371         } else {
1372                 *first_day = today - (day % DAYS_OF_WEEK);
1373                 if (p->pos_end < (start_day + DAYS_OF_WEEK - 1))
1374                         *last_day = p->pos_end - p->pos_start + 1;
1375                 else
1376                         *last_day = *first_day + DAYS_OF_WEEK - 1;
1377         }
1378
1379         struct appdata *ad = p->ad;
1380         c_retv_if(!ad, -1);
1381
1382         *start_time = ad->base_tm;
1383         start_time->tm_mday = *first_day;
1384         start_time->tm_hour = 0;
1385         start_time->tm_min = 0;
1386         start_time->tm_sec = 0;
1387
1388         *end_time = ad->base_tm;
1389         end_time->tm_mday = *last_day;
1390         end_time->tm_hour = 23;
1391         end_time->tm_min = 59;
1392         end_time->tm_sec = 59;
1393
1394         if (0 < p->pos_start && day < DAYS_OF_WEEK)
1395                 cal_util_update_tm_day(start_time, -p->pos_start);
1396         else if ((0 != (day_tmp % DAYS_OF_WEEK)) && (p->pos_end < (start_day + DAYS_OF_WEEK - 1)))
1397                 cal_util_update_tm_day(end_time, start_day + DAYS_OF_WEEK - 1 - p->pos_end);
1398
1399         if (p->pos_end < day_pos && p->pos_end <= CAL_MONTH_CALENDAR_LAST_LINE_POS_INDEX  && CAL_MONTH_CALENDAR_LAST_LINE_POS_INDEX  < day_pos) {
1400                 r = cal_util_update_tm_day(start_time, DAYS_OF_WEEK);
1401                 c_retvm_if(-1 == r, -1, "start_time is out of range.");
1402
1403                 r = cal_util_update_tm_day(end_time, DAYS_OF_WEEK);
1404                 c_retvm_if(-1 == r, -1, "end_time is out of range.");
1405         }
1406
1407         return 0;
1408 }
1409
1410 static void __cal_month_calendar_set_more_text(Evas_Object *ly, int count, int index)
1411 {
1412         c_retm_if(!ly, "ly is null");
1413         c_retm_if(index < 0 , "index is wrong");
1414
1415         cal_month_calendar_data* p = CAL_UTIL_GET_PRIV_DATA(ly);
1416         c_retm_if(!p, "p is null");
1417         c_retm_if(!p->ad, "p->ad is null");
1418
1419         char part[32] = {0};
1420         char text[32] = {0};
1421
1422         if (count <= (p->ad->is_landscape_mode ? LINES_OF_WEEKLY_MONTHS_EVENT_LANDSCAPE : LINES_OF_WEEKLY_MONTHS_EVENT)) {
1423                 cal_util_emit_signal(CAL_UTIL_GET_EDJ_DATA(ly), "hide_count,%d", index);
1424         } else {
1425                 cal_util_emit_signal(CAL_UTIL_GET_EDJ_DATA(ly), "show_count,%d", index);
1426                 snprintf(text, sizeof text, "+%d", count - (p->ad->is_landscape_mode ? LINES_OF_WEEKLY_MONTHS_EVENT_LANDSCAPE : LINES_OF_WEEKLY_MONTHS_EVENT));
1427                 snprintf(part, sizeof part, "db/%d/count", index);
1428                 edje_object_part_text_set(CAL_UTIL_GET_EDJ_DATA(ly), part, text);
1429         }
1430 }
1431
1432 static void __cal_month_calendar_create_event_lists(Evas_Object *ly, cal_month_calendar_data *p)
1433 {
1434         c_ret_if(!p);
1435         c_ret_if(!ly);
1436
1437         char part[32] = {0};
1438         int week = 0;
1439
1440         for (week = 0; week < WEEKS_OF_MONTH; week++) {
1441                 snprintf(part, sizeof part, "list/sw/%d", week * DAYS_OF_WEEK);
1442                 Evas_Object *events = NULL;
1443
1444                 if (p->ad->is_landscape_mode) {
1445                         events = cal_util_add_layout(p->ad->nv, "main/month/week/events/l");
1446                 } else {
1447                         events = cal_util_add_layout(p->ad->nv, "main/month/week/events");
1448                 }
1449
1450                 c_retm_if(!events, "events is null");
1451
1452                 evas_object_data_set(events, "list_index", (void*)week);
1453
1454                 elm_object_part_content_set(ly, part, events);
1455                 evas_object_event_callback_add(events, EVAS_CALLBACK_MOUSE_DOWN, __cal_month_calendar_mouse_down, p);
1456                 evas_object_event_callback_add(events, EVAS_CALLBACK_MOUSE_UP, __cal_month_calendar_mouse_up, p);
1457                 evas_object_event_callback_add(events, EVAS_CALLBACK_MOUSE_MOVE, __cal_month_calendar_mouse_move, p);
1458
1459                 p->weekly_events_ly[week] = events;
1460         }
1461 }
1462
1463 static void __cal_month_calendar_signal_all_week(cal_month_calendar_data *p)
1464 {
1465         c_retm_if(!p, "p is null");
1466
1467         int week = 0;
1468         for (week = 0; week < WEEKS_OF_MONTH; week++)
1469                 __cal_month_calendar_signal_week(p, p->weekly_events_ly[week], week);
1470 }
1471
1472 static void __cal_month_calendar_signal_all_clean(cal_month_calendar_data *p)
1473 {
1474         c_retm_if(!p, "p is null");
1475
1476         int i = 0;
1477         for (i = 0; i < WEEKS_OF_MONTH; i++)
1478                 __cal_month_calendar_signal_clean(p,CAL_UTIL_GET_EDJ_DATA(p->weekly_events_ly[i]));
1479 }
1480
1481 static void __cal_month_calendar_set_check_text(Evas_Object *ly, cal_month_calendar_data *p, int count, int index)
1482 {
1483         c_retm_if(!ly, "ly is null");
1484         c_retm_if(index < 0 , "index is wrong");
1485
1486         char part[32] = {0};
1487         char text[32] = {0};
1488
1489         if (count <= 0) {
1490                 p->day[index].checked = 0;
1491                 snprintf(part, sizeof part, "db/%d/count", index);
1492                 edje_object_part_text_set(CAL_UTIL_GET_EDJ_DATA(ly), part, "");
1493         } else {
1494                 cal_util_emit_signal(CAL_UTIL_GET_EDJ_DATA(ly), "show_count,%d", index);
1495                 p->day[index].checked = 1;
1496                 snprintf(text, sizeof text, "+%d", count);
1497                 snprintf(part, sizeof part, "db/%d/count", index);
1498                 edje_object_part_text_set(CAL_UTIL_GET_EDJ_DATA(ly), part, text);
1499         }
1500 }
1501
1502 static void __cal_month_calendar_set_event_rect_color(Evas_Object *obj, cal_month_calendar_data *p, int line, int pos, int calendar_id)
1503 {
1504         c_retm_if(!obj, "obj is null");
1505         c_retm_if(!p, "p is null");
1506
1507         int r;
1508         cal_struct *calendar = NULL;
1509         Calendar_color calendar_color;
1510         Evas_Object *event_content = NULL;
1511         char part[20] = {0};
1512
1513         snprintf(part, sizeof part, "%d/bgcolor/%d", line, pos);
1514
1515         r = CALENDAR_SVC_GET(CAL_STRUCT_CALENDAR, calendar_id, NULL, &calendar);
1516         c_retm_if(CAL_SUCCESS != r , "CALENDAR_SVC_GET is failed");
1517
1518         CALENDAR_SVC_GET_CALENDAR_COLOR(calendar, &calendar_color);
1519
1520         event_content = cal_util_add_rectangle(obj);
1521         c_retm_if(!event_content, "event_content is null");
1522
1523         evas_object_size_hint_align_set(event_content, EVAS_HINT_FILL, 0);
1524         evas_object_size_hint_weight_set(event_content, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1525         evas_object_color_set(event_content, calendar_color.red, calendar_color.green, calendar_color.blue, calendar_color.alpha);
1526
1527         elm_object_part_content_set(obj, part, event_content);
1528
1529         CALENDAR_SVC_STRUCT_FREE(&calendar);
1530
1531 }
1532
1533 static void __cal_month_calendar_set_day_default_color(cal_month_calendar_data* p, Evas_Object *eo, int pos)
1534 {
1535         c_retm_if(!p, "p is null");
1536         c_retm_if(!eo, "eo is null");
1537
1538         struct _day *d = &p->day[pos];
1539         c_retm_if(!d, "d is null");
1540
1541         switch (d->d_type) {
1542         case CAL_MONTH_CALENDAR_DAY_TYPE_SUNDAY:
1543                 cal_util_emit_signal(eo, "sunday,%d", pos);
1544                 break;
1545         case CAL_MONTH_CALENDAR_DAY_TYPE_SATDAY:
1546                 cal_util_emit_signal(eo, "satday,%d", pos);
1547                 break;
1548         case CAL_MONTH_CALENDAR_DAY_TYPE_WEEKDAY:
1549                 cal_util_emit_signal(eo, "weekday,%d", pos);
1550                 break;
1551         default:
1552                 cal_util_emit_signal(eo, "weekday,%d", pos);
1553                 break;
1554         }
1555 }
1556
1557 static void __cal_month_calendar_fill_week_number(Evas_Object *ly)
1558 {
1559         c_retm_if(!ly, "ly is null");
1560
1561         int k = 0;
1562         cal_month_calendar_data *p = CAL_UTIL_GET_PRIV_DATA(ly);
1563         c_retm_if(!p, "p is null");
1564
1565         for (k = 0; k < WEEKS_OF_MONTH; k++) {
1566                 int start_day = 0;
1567                 int end_day = 0;
1568                 char week[8] = {0};
1569                 struct tm end_time = {0};
1570                 struct tm start_time = {0};
1571                 __cal_month_calendar_get_day_time_by_pos(p, &start_day, &end_day, &start_time, &end_time, (k + 1) * DAYS_OF_WEEK - 1);
1572                 cal_util_get_week_number_text(&start_time, week, sizeof(week) - 1);
1573                 cal_util_set_text(CAL_UTIL_GET_EDJ_DATA(ly), cal_util_get_part_text("wn/%d/text", k), "%s", week);
1574         }
1575 }