7945f9f7369defb3f7e68a75e812bf014b0aeb86
[framework/pim/calendar-service.git] / common / cal_vcalendar_make.c
1 /*
2  * Calendar Service
3  *
4  * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <stdlib.h>
21
22 #include "calendar_list.h"
23
24 #include "cal_internal.h"
25 #include "cal_typedef.h"
26 #include "cal_record.h"
27 #include "cal_view.h"
28 #include "cal_time.h"
29
30 #include "cal_vcalendar.h"
31 #include "cal_vcalendar_make.h"
32
33 typedef enum
34 {
35         EVENT_ATTENDEE_REQ_PARTICIPANT_ROLE=0,
36         EVENT_ATTENDEE_OPT_PARTICIPANT_ROLE,
37         EVENT_ATTENDEE_NON_PARTICIPANT_ROLE,
38         EVENT_ATTENDEE_CHAIR_ROLE,
39 } cal_event_attendee_role_type_t;
40
41 typedef enum
42 {
43         EVENT_ATTENDEE_NEEDS_ACTION_AT_STATUS=0,
44         EVENT_ATTENDEE_ACCEPTED_AT_STATUS,
45         EVENT_ATTENDEE_DECLINED_AT_STATUS,
46         EVENT_ATTENDEE_TENTATIVE_AT_STATUS,
47         EVENT_ATTENDEE_DELEGATED_AT_STATUS,
48         EVENT_ATTENDEE_COMPLETED_AT_STATUS,
49         EVENT_ATTENDEE_IN_PROCESS_AT_STATUS
50 } cal_event_attendee_status_type_t;
51
52
53 static const char *_att_role[] = {
54         [EVENT_ATTENDEE_REQ_PARTICIPANT_ROLE] = "REQ-PARTICIPANT",
55         [EVENT_ATTENDEE_OPT_PARTICIPANT_ROLE] = "OPT-PARTICIPANT",
56         [EVENT_ATTENDEE_NON_PARTICIPANT_ROLE] = "NON-PARTICIPANT",
57         [EVENT_ATTENDEE_CHAIR_ROLE] = "CHAIR",
58 };
59
60 static const char *_att_st[] = {
61         [EVENT_ATTENDEE_NEEDS_ACTION_AT_STATUS] = "NEEDS-ACTION",
62         [EVENT_ATTENDEE_ACCEPTED_AT_STATUS] = "ACCEPTED",
63         [EVENT_ATTENDEE_DECLINED_AT_STATUS] = "DECLINED",
64         [EVENT_ATTENDEE_TENTATIVE_AT_STATUS] = "TENTATIVE",
65         [EVENT_ATTENDEE_DELEGATED_AT_STATUS] = "DELEGATED",
66         [EVENT_ATTENDEE_COMPLETED_AT_STATUS] = "COMPLETED",
67         [EVENT_ATTENDEE_IN_PROCESS_AT_STATUS] = "IN-PROCESS",
68 };
69
70 #define _strlen(s) (((s) && *(s)) ? strlen(s) : 0)
71
72 static inline int __cal_vcalendar_make_alloc(cal_make_s *b, int n)
73 {
74         b->data = realloc(b->data, b->size + n);
75
76         retvm_if(!b->data, CALENDAR_ERROR_OUT_OF_MEMORY,
77                         "Failed to realloc");
78         b->size += n;
79
80         return CALENDAR_ERROR_NONE;
81 }
82
83 cal_make_s *_cal_vcalendar_make_new(void)
84 {
85         cal_make_s *b;
86
87         b = calloc(1, sizeof(cal_make_s));
88         if (!b) {
89                 return NULL;
90         }
91
92         b->data = calloc(1, sizeof(char));
93         if (!b->data) {
94                 free(b);
95                 return NULL;
96         }
97
98         *b->data = '\0';
99         b->size = 1;
100
101         return b;
102 }
103
104 static inline int __cal_vcalendar_make_folding(cal_make_s *b)
105 {
106         int ret;
107         ret = __cal_vcalendar_make_alloc(b, _strlen(b->lbuf) + 3);
108         retv_if(ret != CALENDAR_ERROR_NONE, ret);
109
110         strncat(b->data, b->lbuf, b->size - _strlen(b->data) - 1);
111         strncat(b->data, "\r\n ", b->size - _strlen(b->data) - 1);
112         *b->lbuf = '\0';
113         return CALENDAR_ERROR_NONE;
114 }
115
116 static inline int __cal_vcalendar_make_set_str(cal_make_s *b, const char *s)
117 {
118         int remain_lbuf;
119         int remain_str;
120         int k;
121         int ret;
122
123         remain_lbuf = sizeof(b->lbuf) - _strlen(b->lbuf);
124         remain_str = _strlen(s);
125
126         k = 0;
127         while ( remain_lbuf - 1 < remain_str) {
128                 strncat(b->lbuf, s + k, remain_lbuf - 1);
129                 k += remain_lbuf - 1;
130                 remain_str -= remain_lbuf - 1;
131                 ret = __cal_vcalendar_make_folding(b);
132                 retv_if(ret != CALENDAR_ERROR_NONE, ret);
133                 remain_lbuf = sizeof(b->lbuf);
134         }
135
136         strncat(b->lbuf, s + k, remain_lbuf - 1);
137         return CALENDAR_ERROR_NONE;
138 }
139
140 static inline int __cal_vcalendar_make_flush(cal_make_s *b)
141 {
142         int ret;
143         ret = __cal_vcalendar_make_alloc(b, _strlen(b->lbuf) + 2);
144         retv_if(ret != CALENDAR_ERROR_NONE, ret);
145
146         strncat(b->data, b->lbuf, b->size - _strlen(b->data) - 1);
147         strncat(b->data, "\r\n", b->size - _strlen(b->data) - 1);
148         *b->lbuf = '\0';
149         return CALENDAR_ERROR_NONE;
150 }
151
152 static int __cal_vcalendar_make_printf(cal_make_s *b, const char *s1, const char *s2)
153 {
154         int ret;
155
156         if (s1) {
157                 ret = __cal_vcalendar_make_set_str(b, s1);
158                 retv_if(ret != CALENDAR_ERROR_NONE, ret);
159         }
160
161         if (s2) {
162                 ret = __cal_vcalendar_make_set_str(b, s2);
163                 retv_if(ret != CALENDAR_ERROR_NONE, ret);
164         }
165
166         return __cal_vcalendar_make_flush(b);
167 }
168
169 char *_cal_vcalendar_make_get_data(cal_make_s *b)
170 {
171         if (!b || !b->data)
172                 return NULL;
173         return strdup(b->data);
174 }
175
176 void _cal_vcalendar_make_free(cal_make_s **b)
177 {
178         if (!b || !*b)
179                 return;
180
181         if ((*b)->data)
182                 free((*b)->data);
183
184         free(*b);
185         b = NULL;
186 }
187
188 static const char *__cal_vcalendar_make_itos(int y, int m, int d)
189 {
190         static char buf[9];
191         snprintf(buf, sizeof(buf), "%04d%02d%02d", y, m, d);
192         return buf;
193 }
194
195 /////////////////////////////////////////////////////////////////////////////
196 static inline int __cal_vcalendar_make_class(cal_make_s *b, int v)
197 {
198         const char *c;
199         // TODO : Need to define enumeration of class property
200         switch(v) {
201                 case 0:
202                         c = "PUBLIC"; break;
203                 case 1:
204                         c = "PRIVATE"; break;
205                 case 2:
206                         c = "CONFIDENTIAL"; break;
207                 default:
208                         c = "PUBLIC"; break;
209         }
210         __cal_vcalendar_make_printf(b, "CLASS:", c);
211         return CALENDAR_ERROR_NONE;
212 }
213
214 static inline int __cal_vcalendar_make_transp(cal_make_s *b, int v)
215 {
216         // TODO : Need to define enumeration of transp property
217         __cal_vcalendar_make_printf(b, "TRANSP:", v? "OPAQUE":"TRANSPARENT");
218         return CALENDAR_ERROR_NONE;
219 }
220
221 static inline int __cal_vcalendar_make_created(cal_make_s *b, long long int t)
222 {
223     char* tmp_tzid = NULL;
224     tmp_tzid = _cal_time_convert_ltos(NULL, t);
225     if (tmp_tzid)
226     {
227         __cal_vcalendar_make_printf(b, "CREATED:", tmp_tzid);
228         CAL_FREE(tmp_tzid);
229     }
230         return CALENDAR_ERROR_NONE;
231 }
232
233 static inline int __cal_vcalendar_make_dtstart(int version, cal_make_s *b, char *tzid, calendar_time_s *caltime)
234 {
235         retvm_if(caltime == NULL, -1, "Invalid argument: calendar_time_s is NULL");
236
237         if (caltime->time.utime == CALENDAR_TODO_NO_START_DATE)
238         {
239                 DBG("No start date");
240                 return CALENDAR_ERROR_NONE;
241         }
242
243         switch (caltime->type)
244         {
245         case CALENDAR_TIME_UTIME:
246         {
247                         char* str_time = NULL;
248                         if (version != 1 && NULL != tzid && strlen(tzid) > 0)
249                         {
250                                 str_time = _cal_time_convert_ltos(tzid, caltime->time.utime);
251                                 if (str_time)
252                                 {
253                                         char buf[128] = {0};
254                                         snprintf(buf, sizeof(buf), "DTSTART;TZID=%s:", tzid);
255                                         __cal_vcalendar_make_printf(b, buf, str_time);
256                                         CAL_FREE(str_time);
257                                 }
258                         }
259                         else
260                         {
261                                 str_time = _cal_time_convert_ltos(NULL, caltime->time.utime);
262                                 if (str_time)
263                                 {
264                                         __cal_vcalendar_make_printf(b, "DTSTART:", str_time);
265                                         CAL_FREE(str_time);
266                                 }
267                         }
268         }
269                 break;
270
271         case CALENDAR_TIME_LOCALTIME:
272                 if (version == 1)
273                 {
274                         char buf[16] = {0};
275                         snprintf(buf, sizeof(buf), "%04d%02d%02dT000000",
276                                         caltime->time.date.year, caltime->time.date.month, caltime->time.date.mday);
277                         __cal_vcalendar_make_printf(b, "DTSTART:", buf);
278
279                 }
280                 else
281                 {
282                         __cal_vcalendar_make_printf(b, "DTSTART;VALUE=DATE:",
283                                         __cal_vcalendar_make_itos(caltime->time.date.year,
284                                                 caltime->time.date.month, caltime->time.date.mday));
285                 }
286                 break;
287         }
288
289         return CALENDAR_ERROR_NONE;
290 }
291
292 static inline int __cal_vcalendar_make_last_mod(cal_make_s *b, long long int lli)
293 {
294     char* tmp_tzid = NULL;
295     tmp_tzid = _cal_time_convert_ltos(NULL, lli);
296     if (tmp_tzid)
297     {
298         __cal_vcalendar_make_printf(b, "LAST-MODIFIED:",tmp_tzid);
299         CAL_FREE(tmp_tzid);
300     }
301         return CALENDAR_ERROR_NONE;
302 }
303
304 int __cal_vcalendar_make_organizer(cal_make_s *b, char *cn, char *address)
305 {
306         int ret;
307
308         ret = __cal_vcalendar_make_set_str(b, "ORGANIZER");
309         retv_if(ret != CALENDAR_ERROR_NONE, ret);
310         if (cn && *cn)
311         {
312                 ret = __cal_vcalendar_make_set_str(b, ";CN=");
313                 ret = __cal_vcalendar_make_set_str(b, cn);
314                 retv_if(ret != CALENDAR_ERROR_NONE, ret);
315         }
316
317         if (address && *address)
318         {
319                 ret = __cal_vcalendar_make_set_str(b, ":mailto:");
320                 ret = __cal_vcalendar_make_set_str(b, address);
321         }
322         __cal_vcalendar_make_flush(b);
323         return CALENDAR_ERROR_NONE;
324 }
325
326 static inline int __cal_vcalendar_make_priority(cal_make_s *b, int v)
327 {
328         char tmp[2];
329         snprintf(tmp, sizeof(tmp), "%d", v);
330         __cal_vcalendar_make_printf(b, "PRIORITY:", tmp);
331         return CALENDAR_ERROR_NONE;
332 }
333
334 int __cal_vcalendar_make_dtstamp(cal_make_s *b, char *tzid)
335 {
336     char* tmp_tzid = NULL;
337     tmp_tzid = _cal_time_convert_ltos(tzid, _cal_time_get_now());
338     if (tmp_tzid)
339     {
340         __cal_vcalendar_make_printf(b, "DTSTAMP:", tmp_tzid);
341         CAL_FREE(tmp_tzid);
342     }
343
344         return CALENDAR_ERROR_NONE;
345 }
346
347 static inline int __cal_vcalendar_make_dtend(int version, cal_make_s *b, char *tzid, calendar_time_s *caltime)
348 {
349         retvm_if(caltime == NULL, -1, "Invalid argument: calendar_time_s is NULL");
350
351         if (caltime->time.utime == CALENDAR_TODO_NO_DUE_DATE)
352         {
353                 DBG("No start date");
354                 return CALENDAR_ERROR_NONE;
355         }
356
357         switch (caltime->type)
358         {
359         case CALENDAR_TIME_UTIME:
360         {
361                         char* str_time = NULL;
362                         if (version != 1 && NULL != tzid && strlen(tzid) > 0)
363                         {
364                                 str_time = _cal_time_convert_ltos(tzid, caltime->time.utime);
365                                 if (str_time)
366                                 {
367                                         char buf[128] = {0};
368                                         snprintf(buf, sizeof(buf), "DTEND;TZID=%s:", tzid);
369                                         __cal_vcalendar_make_printf(b, buf, str_time);
370                                         CAL_FREE(str_time);
371                                 }
372                         }
373                         else
374                         {
375                                 str_time = _cal_time_convert_ltos(NULL, caltime->time.utime);
376                                 if (str_time)
377                                 {
378                                         __cal_vcalendar_make_printf(b, "DTEND:", str_time);
379                                         CAL_FREE(str_time);
380                                 }
381                         }
382         }
383                 break;
384
385         case CALENDAR_TIME_LOCALTIME:
386                 if (version == 1)
387                 {
388                         char buf[16] = {0};
389                         snprintf(buf, sizeof(buf), "%04d%02d%02dT000000",
390                                         caltime->time.date.year, caltime->time.date.month, caltime->time.date.mday);
391                         __cal_vcalendar_make_printf(b, "DTEND:", buf);
392
393                 }
394                 else
395                 {
396                         __cal_vcalendar_make_printf(b, "DTEND;VALUE=DATE:",
397                                         __cal_vcalendar_make_itos(caltime->time.date.year,
398                                                 caltime->time.date.month, caltime->time.date.mday));
399                 }
400                 break;
401         }
402
403         return CALENDAR_ERROR_NONE;
404 }
405
406 static inline int __cal_vcalendar_make_due(int version, cal_make_s *b, char *tzid,  calendar_time_s *caltime)
407 {
408         retvm_if(caltime == NULL, -1, "Invalid argument: calendar_time_s is NULL");
409
410         if (caltime->time.utime == CALENDAR_TODO_NO_DUE_DATE)
411         {
412                 DBG("No due date");
413                 return CALENDAR_ERROR_NONE;
414         }
415
416         switch (caltime->type)
417         {
418         case CALENDAR_TIME_UTIME:
419         {
420                         char* str_time = NULL;
421                         if (version != 1 && NULL != tzid && strlen(tzid) > 0)
422                         {
423                                 str_time = _cal_time_convert_ltos(tzid, caltime->time.utime);
424                                 if (str_time)
425                                 {
426                                         char buf[128] = {0};
427                                         snprintf(buf, sizeof(buf), "DUE;TZID=%s:", tzid);
428                                         __cal_vcalendar_make_printf(b, buf, str_time);
429                                         CAL_FREE(str_time);
430                                 }
431                         }
432                         else
433                         {
434                                 str_time = _cal_time_convert_ltos(NULL, caltime->time.utime);
435                                 if (str_time)
436                                 {
437                                         __cal_vcalendar_make_printf(b, "DUE:", str_time);
438                                         CAL_FREE(str_time);
439                                 }
440                         }
441         }
442                 break;
443
444         case CALENDAR_TIME_LOCALTIME:
445                 if (version == 1)
446                 {
447                         char buf[16] = {0};
448                         snprintf(buf, sizeof(buf), "%04d%02d%02dT000000",
449                                         caltime->time.date.year, caltime->time.date.month, caltime->time.date.mday);
450                         __cal_vcalendar_make_printf(b, "DUE:", buf);
451
452                 }
453                 else
454                 {
455                         __cal_vcalendar_make_printf(b, "DUE:",
456                                         __cal_vcalendar_make_itos(caltime->time.date.year,
457                                                 caltime->time.date.month, caltime->time.date.mday));
458                 }
459                 break;
460         }
461
462         return CALENDAR_ERROR_NONE;
463 }
464
465 static inline int __cal_vcalendar_make_exdate(cal_make_s *b, char *s)
466 {
467         __cal_vcalendar_make_printf(b, "EXDATE:", s);
468         return CALENDAR_ERROR_NONE;
469 }
470
471 int __cal_vcalendar_make_attendee(cal_make_s *b, calendar_record_h attendee)
472 {
473         int ret;
474         int role, status, rsvp;
475         char *group = NULL;
476         char *delegate_uri = NULL;
477         char *delegator_uri = NULL;
478         char *name = NULL;
479         char *email = NULL;
480
481         retvm_if(attendee == NULL, CALENDAR_ERROR_INVALID_PARAMETER,
482                         "Invalid argument: attendee is NULL");
483
484         ret = __cal_vcalendar_make_set_str(b, "ATTENDEE");
485         retv_if(ret != CALENDAR_ERROR_NONE, ret);
486
487         ret = calendar_record_get_str_p(attendee, _calendar_attendee.group, &group);
488
489         if (group && *group) {
490                 ret = __cal_vcalendar_make_set_str(b, ";CUTYPE=");
491                 ret = __cal_vcalendar_make_set_str(b, group);
492                 retv_if(ret != CALENDAR_ERROR_NONE, ret);
493         }
494
495         // TODO : NO 'member' member in cal_participant_info_t
496
497         ret = calendar_record_get_int(attendee, _calendar_attendee.role, &role);
498         {
499                 ret = __cal_vcalendar_make_set_str(b, ";ROLE=");
500                 ret = __cal_vcalendar_make_set_str(b, _att_role[role]);
501                 retv_if(ret != CALENDAR_ERROR_NONE, ret);
502         }
503
504         ret = calendar_record_get_int(attendee, _calendar_attendee.status, &status);
505         {
506                 ret = __cal_vcalendar_make_set_str(b, ";PARTSTAT=");
507                 ret = __cal_vcalendar_make_set_str(b, _att_st[status]);
508                 retv_if(ret != CALENDAR_ERROR_NONE, ret);
509         }
510
511         ret = calendar_record_get_int(attendee, _calendar_attendee.rsvp, &rsvp);
512         {
513                 ret = __cal_vcalendar_make_set_str(b, ";RSVP=");
514                 ret = __cal_vcalendar_make_set_str(b, rsvp ? "TRUE" : "FALSE");
515                 retv_if(ret != CALENDAR_ERROR_NONE, ret);
516         }
517
518         ret = calendar_record_get_str_p(attendee,       _calendar_attendee.delegate_uri, &delegate_uri);
519         if (delegate_uri && *delegate_uri)
520         {
521                 ret = __cal_vcalendar_make_set_str(b, ";DELEGATED-TO=");
522                 ret = __cal_vcalendar_make_set_str(b, delegate_uri);
523                 retv_if(ret != CALENDAR_ERROR_NONE, ret);
524         }
525
526         ret = calendar_record_get_str_p(attendee, _calendar_attendee.delegator_uri, &delegator_uri);
527         if (delegator_uri && *delegator_uri)
528         {
529                 ret = __cal_vcalendar_make_set_str(b, ";DELEGATED-FROM=");
530                 ret = __cal_vcalendar_make_set_str(b, delegator_uri);
531                 retv_if(ret != CALENDAR_ERROR_NONE, ret);
532         }
533
534         // TODO : No 'sentby' member in cal_participant_info_t
535
536         ret = calendar_record_get_str_p(attendee, _calendar_attendee.name, &name);
537         if (name && *name) {
538                 ret = __cal_vcalendar_make_set_str(b, ";CN=");
539                 ret = __cal_vcalendar_make_set_str(b, name);
540                 retv_if(ret != CALENDAR_ERROR_NONE, ret);
541         }
542
543         ret = calendar_record_get_str_p(attendee,       _calendar_attendee.email, &email);
544         if (email && *email)
545         {
546                 ret = __cal_vcalendar_make_set_str(b, ":mailto:");
547                 ret = __cal_vcalendar_make_set_str(b, email);
548                 retv_if(ret != CALENDAR_ERROR_NONE, ret);
549         }
550         __cal_vcalendar_make_flush(b);
551         return CALENDAR_ERROR_NONE;
552 }
553
554 static const char *vl_dur(calendar_alarm_time_unit_type_e unit, int dur)
555 {
556         static char buf[8];
557         int i = 0;
558         char d[5];
559
560         if (dur < 0) {
561                 *buf = '-';
562                 i++;
563                 dur = -dur;
564         }
565
566         snprintf(d, sizeof(d), "%d", dur);
567
568         *(buf + i) = 'P';
569         i++;
570
571         switch (unit) {
572                 case CALENDAR_ALARM_TIME_UNIT_WEEK:
573                         snprintf(buf + i, sizeof(buf) - i, "%sW", d);
574                         break;
575                 case CALENDAR_ALARM_TIME_UNIT_DAY:
576                         snprintf(buf + i, sizeof(buf) - i, "%sD", d);
577                         break;
578                 case CALENDAR_ALARM_TIME_UNIT_HOUR:
579                         snprintf(buf + i, sizeof(buf) - i, "T%sH", d);
580                         break;
581                 case CALENDAR_ALARM_TIME_UNIT_MINUTE:
582                         snprintf(buf + i, sizeof(buf) - i, "T%sM", d);
583                         break;
584                 default:
585                         buf[0] = '\0';
586         }
587
588         return buf;
589 }
590
591 int __cal_vcalendar_make_trigger(cal_make_s *b, int unit, int dur, long long int t)
592 {
593         retvm_if(unit < 0, CALENDAR_ERROR_NO_DATA, "tick unit is invalid");
594
595         if (unit == CALENDAR_ALARM_TIME_UNIT_SPECIFIC)
596         {
597             char* tmp_tzid = NULL;
598             tmp_tzid = _cal_time_convert_ltos(NULL, t);
599             if (tmp_tzid)
600             {
601                 __cal_vcalendar_make_printf(b, "TRIGGER;VALUE=DATE-TIME:",tmp_tzid);
602                 CAL_FREE(tmp_tzid);
603             }
604
605         }
606         else
607         {
608                 __cal_vcalendar_make_printf(b, "TRIGGER:", vl_dur(unit, dur));
609         }
610         return CALENDAR_ERROR_NONE;
611 }
612
613 int __cal_vcalendar_make_action(cal_make_s *b)
614 {
615         return __cal_vcalendar_make_printf(b, "ACTION:", "AUDIO");
616 }
617
618 int __cal_vcalendar_make_audio(cal_make_s *b, calendar_record_h alarm)
619 {
620         int ret;
621         int tick, unit;
622         long long int utime;
623
624         ret = __cal_vcalendar_make_action(b);
625         retv_if(ret != CALENDAR_ERROR_NONE, ret);
626
627         ret = calendar_record_get_int(alarm, _calendar_alarm.tick, &tick);
628         ret = calendar_record_get_int(alarm, _calendar_alarm.tick_unit, &unit);
629         ret = calendar_record_get_lli(alarm, _calendar_alarm.time, &utime);
630
631         ret = __cal_vcalendar_make_trigger(b, unit, tick, utime);
632         retv_if(ret != CALENDAR_ERROR_NONE, ret);
633
634         // TODO : Support duration
635         // TODO : Support repeat (snooze)
636         return CALENDAR_ERROR_NONE;
637 }
638
639 // ver 1.0 aalarm
640 int __cal_vcalendar_make_aalarm(cal_make_s *b, calendar_record_h record, calendar_record_h alarm)
641 {
642         int ret;
643         int type;
644         int tick, unit;
645         char *uri = NULL;
646         long long int utime;
647         calendar_time_s caltime = {0};
648         retvm_if(alarm == NULL, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid argument: alarm is NULL");
649
650         ret = calendar_record_get_uri_p(record, &uri);
651         if (CALENDAR_ERROR_NONE != ret)
652         {
653                 ERR("calendar_record_get_uri_p() failed");
654                 return ret;
655         }
656
657         if (!strncmp(uri, _calendar_event._uri, strlen(_calendar_event._uri)))
658         {
659                 type = CALENDAR_RECORD_TYPE_EVENT;
660         }
661         else if (!strncmp(uri, _calendar_todo._uri, strlen(_calendar_todo._uri)))
662         {
663                 type = CALENDAR_RECORD_TYPE_TODO;
664         }
665         else
666         {
667                 ERR("Invalid type(%s)", uri);
668                 return CALENDAR_ERROR_INVALID_PARAMETER;
669         }
670
671         ret = calendar_record_get_int(alarm, _calendar_alarm.tick_unit, &unit);
672         if (CALENDAR_ERROR_NONE != ret)
673         {
674                 ERR("calendar_record_get_int() failed");
675                 return ret;
676         }
677         ret = calendar_record_get_int(alarm, _calendar_alarm.tick, &tick);
678         if (CALENDAR_ERROR_NONE != ret)
679         {
680                 ERR("calendar_record_get_int() failed");
681                 return ret;
682         }
683
684         switch (unit)
685         {
686         case CALENDAR_ALARM_TIME_UNIT_SPECIFIC:
687                 ret = calendar_record_get_lli(alarm, _calendar_alarm.time, &utime);
688                 if (CALENDAR_ERROR_NONE != ret)
689                 {
690                         ERR("calendar_record_get_lli() failed");
691                         return ret;
692                 }
693                 break;
694
695         default:
696                 switch (type)
697                 {
698                 case CALENDAR_RECORD_TYPE_EVENT:
699                         ret = calendar_record_get_caltime(record, _calendar_event.start_time, &caltime);
700                         if (CALENDAR_ERROR_NONE != ret)
701                         {
702                                 ERR("calendar_record_get_caltime() failed");
703                                 return ret;
704                         }
705                         switch (caltime.type)
706                         {
707                         case CALENDAR_TIME_UTIME:
708                                 utime = caltime.time.utime - (tick * unit);
709                                 break;
710
711                         case CALENDAR_TIME_LOCALTIME:
712                                 utime = _cal_time_convert_itol(NULL, caltime.time.date.year,
713                                                 caltime.time.date.month, caltime.time.date.mday, 0, 0, 0);
714                                 utime -= (tick * unit);
715                                 break;
716                         }
717                         break;
718
719                 case CALENDAR_RECORD_TYPE_TODO:
720                         ret = calendar_record_get_caltime(record, _calendar_todo.due_time, &caltime);
721                         if (CALENDAR_ERROR_NONE != ret)
722                         {
723                                 ERR("calendar_record_get_caltime() failed");
724                                 return ret;
725                         }
726                         switch (caltime.type)
727                         {
728                         case CALENDAR_TIME_UTIME:
729                                 utime = caltime.time.utime - (tick * unit);
730                                 break;
731
732                         case CALENDAR_TIME_LOCALTIME:
733                                 utime = _cal_time_convert_itol(NULL, caltime.time.date.year,
734                                                 caltime.time.date.month, caltime.time.date.mday, 0, 0, 0);
735                                 utime -= (tick * unit);
736                                 break;
737                         }
738                         break;
739                 }
740                 break;
741         }
742
743         char *calstr = _cal_time_convert_ltos(NULL, utime);
744         DBG("[%s]", calstr);
745
746         ret = __cal_vcalendar_make_printf(b, "AALARM:", calstr);
747         CAL_FREE(calstr);
748
749         return CALENDAR_ERROR_NONE;
750 }
751
752 int __cal_vcalendar_make_alarm(cal_make_s *b, calendar_record_h alarm)
753 {
754         int ret;
755         retvm_if(alarm == NULL, CALENDAR_ERROR_INVALID_PARAMETER,
756                         "Invalid argument: alarm is NULL");
757
758         // TODO : No action type is defined
759         ret = __cal_vcalendar_make_printf(b, "BEGIN:VALARM", NULL);
760         retv_if(ret != CALENDAR_ERROR_NONE, ret);
761
762         ret = __cal_vcalendar_make_audio(b, alarm);
763         retv_if(ret != CALENDAR_ERROR_NONE, ret);
764
765         // TODO : Display
766         // TODO : Email
767         // TODO : Proc
768
769         __cal_vcalendar_make_printf(b, "END:VALARM", NULL);
770         return CALENDAR_ERROR_NONE;
771 }
772
773 int __cal_vcalendar_make_rrule_append_mday(char *buf, char *mday)
774 {
775         int i;
776         int num;
777         int length = 0;
778         char **t;
779         char *p;
780
781         if (NULL == buf || NULL == mday)
782         {
783                 ERR("Invalid parameter");
784                 return CALENDAR_ERROR_INVALID_PARAMETER;
785         }
786
787         t = g_strsplit(mday, ",", -1);
788         if (!t) {
789                 ERR("g_strsplit failed");
790                 g_strfreev(t);
791                 return CALENDAR_ERROR_OUT_OF_MEMORY;
792         }
793         length = g_strv_length(t);
794         for (i = 0; i < length; i++)
795         {
796                 p = t[i];
797                 while (*p == ' ')
798                 {
799                         p++;
800                 }
801                 num = atoi(p);
802                 if (num > 0)
803                 {
804                         strcat(buf, p);
805                 }
806                 else
807                 {
808                         strcat(buf, p + 1);
809                         strcat(buf, "-");
810                 }
811                 strcat(buf, " ");
812         }
813         g_strfreev(t);
814
815         return CALENDAR_ERROR_NONE;
816 }
817
818 int __cal_vcalendar_make_rrule_append_wday(char *buf, char *wday)
819 {
820         int i, j;
821         int num, num_past;
822         int length = 0;
823         char **t;
824         char *p;
825         char buf_temp[8] = {0};
826
827         num_past = 0;
828         t = g_strsplit(wday, ",", -1);
829         if (!t) {
830                 ERR("g_strsplit failed");
831                 g_strfreev(t);
832                 return CALENDAR_ERROR_OUT_OF_MEMORY;
833         }
834         length = g_strv_length(t);
835         for (i = 0; i < length; i++)
836         {
837                 p = t[i];
838                 while (*p == ' ') // del space
839                 {
840                         p++;
841                 }
842                 j = 0; // get number
843                 while (p[j] == '+' || p[j] == '-' || (p[j] >= '1' && p[j] <= '9'))
844                 {
845                         j++;
846                 }
847                 if (j > 0)
848                 {
849                         if (*p == '-')
850                         {
851                                 snprintf(buf_temp, j, "%s", p + 1);
852                                 num = atoi(buf_temp);
853                                 if (0 == i)
854                                 {
855                                         num_past = num;
856                                         strcat(buf, buf_temp);
857                                         strcat(buf, "-");
858                                         strcat(buf, " ");
859                                 }
860                         }
861                         else
862                         {
863                                 snprintf(buf_temp, j + 1, "%s", p);
864                                 num = atoi(buf_temp);
865                                 if (0 == i)
866                                 {
867                                         num_past = num;
868                                         strcat(buf, buf_temp);
869                                         strcat(buf, " ");
870                                 }
871                         }
872                         if (num_past == num)
873                         {
874                                 strcat(buf, p + j);
875                                 strcat(buf, " ");
876                         }
877                         else
878                         {
879                                 ERR("Out of 1.0 spec");
880                         }
881                         DBG("%d num(%d) val[%s]", i, num, p + j);
882                 }
883                 else
884                 {
885                         strcat(buf, p);
886                         strcat(buf, " ");
887                 }
888         }
889         g_strfreev(t);
890
891         return CALENDAR_ERROR_NONE;
892 }
893
894 int __cal_vcalendar_make_rrule_append_until(char *buf, calendar_record_h record)
895 {
896         int ret;
897         int range_type = 0;
898         int count;
899         char *until_str = NULL;
900         char buf_range[256] = {0};
901         calendar_time_s caltime;
902
903         ret = calendar_record_get_int(record, _calendar_event.range_type, &range_type);
904         if (CALENDAR_ERROR_NONE != ret)
905         {
906                 ERR("calendar_record_get_int() failed");
907                 return ret;
908         }
909
910         switch (range_type)
911         {
912         case CALENDAR_RANGE_COUNT:
913                 ret = calendar_record_get_int(record, _calendar_event.count, &count);
914                 if (CALENDAR_ERROR_NONE != ret)
915                 {
916                         ERR("calendar_record_get_int() failed");
917                         return ret;
918                 }
919                 snprintf(buf_range, sizeof(buf_range), "#%d", count);
920                 break;
921
922         case CALENDAR_RANGE_UNTIL:
923                 memset(&caltime, 0x0, sizeof(calendar_time_s));
924                 ret = calendar_record_get_caltime(record, _calendar_event.until_time, &caltime);
925                 if (CALENDAR_ERROR_NONE != ret)
926                 {
927                         ERR("calendar_record_get_caltime() failed");
928                         return ret;
929                 }
930                 switch (caltime.type)
931                 {
932                 case CALENDAR_TIME_UTIME:
933                         until_str = _cal_time_convert_ltos(NULL, caltime.time.utime);
934                         snprintf(buf_range, sizeof(buf_range), "%s", until_str);
935                         CAL_FREE(until_str);
936                         break;
937
938                 case CALENDAR_TIME_LOCALTIME:
939                         snprintf(buf_range, sizeof(buf_range), "%04d%02d%02dT000000Z",
940                                         caltime.time.date.year, caltime.time.date.month, caltime.time.date.mday);
941                         break;
942                 }
943                 break;
944
945         case CALENDAR_RANGE_NONE:
946                 snprintf(buf_range, sizeof(buf_range), "#0");
947                 break;
948         }
949         strcat(buf, buf_range);
950
951         return CALENDAR_ERROR_NONE;
952 }
953
954 static int __cal_vcalendar_make_rrule_ver1(cal_make_s *b, calendar_record_h record)
955 {
956         int ret;
957         int freq;
958         int interval = 0;
959         char *byyearday = NULL;
960         char *bymonth = NULL;
961         char *bymonthday = NULL;
962         char *byday = NULL;
963         char buf[512] = {0};
964
965         ret = calendar_record_get_int(record, _calendar_event.freq, &freq);
966         if (CALENDAR_ERROR_NONE != ret)
967         {
968                 ERR("calendar_record_get_int() failed");
969                 return ret;
970         }
971         ret = calendar_record_get_int(record, _calendar_event.interval, &interval);
972         if (CALENDAR_ERROR_NONE != ret)
973         {
974                 ERR("calendar_record_get_int() failed");
975                 return ret;
976         }
977         ret = calendar_record_get_str_p(record, _calendar_event.bymonthday, &byyearday);
978         if (CALENDAR_ERROR_NONE != ret)
979         {
980                 ERR("calendar_record_get_str_p() failed");
981                 return ret;
982         }
983         ret = calendar_record_get_str_p(record, _calendar_event.bymonth, &bymonth);
984         if (CALENDAR_ERROR_NONE != ret)
985         {
986                 ERR("calendar_record_get_str_p() failed");
987                 return ret;
988         }
989         ret = calendar_record_get_str_p(record, _calendar_event.byday, &byday);
990         if (CALENDAR_ERROR_NONE != ret)
991         {
992                 ERR("calendar_record_get_str_p() failed");
993                 return ret;
994         }
995         ret = calendar_record_get_str_p(record, _calendar_event.bymonthday, &bymonthday);
996         if (CALENDAR_ERROR_NONE != ret)
997         {
998                 ERR("calendar_record_get_str_p() failed");
999                 return ret;
1000         }
1001
1002         switch (freq) {
1003         case CALENDAR_RECURRENCE_DAILY:
1004                 snprintf(buf, sizeof(buf), "D%d ", interval);
1005                 break;
1006
1007         case CALENDAR_RECURRENCE_WEEKLY:
1008                 snprintf(buf, sizeof(buf), "W%d ", interval);
1009                 __cal_vcalendar_make_rrule_append_wday(buf, byday);
1010                 break;
1011
1012         case CALENDAR_RECURRENCE_MONTHLY:
1013                 if (byday)
1014                 {
1015                         snprintf(buf, sizeof(buf), "MP%d ", interval);
1016                         __cal_vcalendar_make_rrule_append_wday(buf, byday);
1017                 }
1018                 else if (bymonthday)
1019                 {
1020                         snprintf(buf, sizeof(buf), "MD%d ", interval);
1021                         __cal_vcalendar_make_rrule_append_mday(buf, bymonthday);
1022                 }
1023                 else
1024                 {
1025                         ERR("Invalid parameter");
1026                 }
1027                 break;
1028
1029         case CALENDAR_RECURRENCE_YEARLY:
1030                 if (bymonth)
1031                 {
1032                         snprintf(buf, sizeof(buf), "YM%d ", interval);
1033                         __cal_vcalendar_make_rrule_append_mday(buf, bymonth);
1034                 }
1035                 else if (byyearday)
1036                 {
1037                         snprintf(buf, sizeof(buf), "YD%d ", interval);
1038                         __cal_vcalendar_make_rrule_append_mday(buf, byyearday);
1039                 }
1040                 else
1041                 {
1042                         ERR("Invalid parameter");
1043                 }
1044                 break;
1045
1046         default:
1047                 ERR("Invalid parameter");
1048                 break;
1049         }
1050
1051         __cal_vcalendar_make_rrule_append_until(buf, record);
1052
1053         return __cal_vcalendar_make_printf(b, "RRULE:", buf);
1054 }
1055
1056 static int __cal_vcalendar_make_rrule(cal_make_s *b, int freq, calendar_record_h record)
1057 {
1058         int ret;
1059         int num;
1060         char *text = NULL;
1061         char buf[1024] = {0};
1062         char tmp[32] = {0};
1063         calendar_time_s caltime = {0};
1064
1065         switch (freq) {
1066         case CALENDAR_RECURRENCE_DAILY:
1067                 strcat(buf, "FREQ=DAILY");
1068                 break;
1069         case CALENDAR_RECURRENCE_WEEKLY:
1070                 strcat(buf, "FREQ=WEEKLY");
1071                 break;
1072         case CALENDAR_RECURRENCE_MONTHLY:
1073                 strcat(buf, "FREQ=MONTHLY");
1074                 break;
1075         case CALENDAR_RECURRENCE_YEARLY:
1076                 strcat(buf, "FREQ=YEARLY");
1077                 break;
1078         default:
1079                 break;
1080         }
1081
1082         ret = calendar_record_get_int(record, _calendar_event.interval, &num);
1083         snprintf(tmp, sizeof(tmp), "%d", num);
1084         strcat(buf, ";INTERVAL=");
1085         strcat(buf, tmp);
1086
1087         ret = calendar_record_get_str_p(record, _calendar_event.bysecond, &text);
1088         if (text) {
1089                 strcat(buf, ";BYSECOND=");
1090                 strcat(buf, text);
1091                 text = NULL;
1092         }
1093
1094         ret = calendar_record_get_str_p(record, _calendar_event.byminute, &text);
1095         if (text) {
1096                 strcat(buf, ";BYMINUTE=");
1097                 strcat(buf, text);
1098                 text = NULL;
1099         }
1100
1101         ret = calendar_record_get_str_p(record, _calendar_event.byhour, &text);
1102         if (text) {
1103                 strcat(buf, ";BYHOUR=");
1104                 strcat(buf, text);
1105                 text = NULL;
1106         }
1107
1108         ret = calendar_record_get_str_p(record, _calendar_event.byday, &text);
1109         if (text) {
1110                 strcat(buf, ";BYDAY=");
1111                 strcat(buf, text);
1112                 text = NULL;
1113         }
1114
1115         ret = calendar_record_get_str_p(record, _calendar_event.bymonthday, &text);
1116         if (text) {
1117                 strcat(buf, ";BYMONTHDAY=");
1118                 strcat(buf, text);
1119                 text = NULL;
1120         }
1121
1122         ret = calendar_record_get_str_p(record, _calendar_event.byyearday, &text);
1123         if (text) {
1124                 strcat(buf, ";BYYEARDAY=");
1125                 strcat(buf, text);
1126                 text = NULL;
1127         }
1128
1129         ret = calendar_record_get_str_p(record, _calendar_event.byweekno, &text);
1130         if (text) {
1131                 strcat(buf, ";BYWEEKNO=");
1132                 strcat(buf, text);
1133                 text = NULL;
1134         }
1135
1136         ret = calendar_record_get_str_p(record, _calendar_event.bymonth, &text);
1137         if (text) {
1138                 strcat(buf, ";BYMONTH=");
1139                 strcat(buf, text);
1140                 text = NULL;
1141         }
1142
1143         ret = calendar_record_get_str_p(record, _calendar_event.bysetpos, &text);
1144         if (text) {
1145                 strcat(buf, ";BYSETPOS=");
1146                 strcat(buf, text);
1147                 text = NULL;
1148         }
1149
1150         num = CALENDAR_SUNDAY; // default set
1151         ret = calendar_record_get_int(record, _calendar_event.wkst, &num);
1152         strcat(buf, ";WKST=");
1153         switch (num) {
1154         case CALENDAR_SUNDAY:
1155                 strcat(buf, "SU");
1156                 break;
1157         case CALENDAR_MONDAY:
1158                 strcat(buf, "MO");
1159                 break;
1160         case CALENDAR_TUESDAY:
1161                 strcat(buf, "TU");
1162                 break;
1163         case CALENDAR_WEDNESDAY:
1164                 strcat(buf, "WE");
1165                 break;
1166         case CALENDAR_THURSDAY:
1167                 strcat(buf, "TH");
1168                 break;
1169         case CALENDAR_FRIDAY:
1170                 strcat(buf, "FR");
1171                 break;
1172         case CALENDAR_SATURDAY:
1173                 strcat(buf, "SA");
1174                 break;
1175         }
1176
1177         ret = calendar_record_get_int(record, _calendar_event.range_type, &num);
1178         switch (num) {
1179         case CALENDAR_RANGE_COUNT:
1180                 ret = calendar_record_get_int(record, _calendar_event.count, &num);
1181                 snprintf(tmp, sizeof(tmp), "%d", num);
1182                 strcat(buf, ";COUNT=");
1183                 strcat(buf, tmp);
1184                 break;
1185
1186         case CALENDAR_RANGE_UNTIL:
1187                 ret = calendar_record_get_caltime(record, _calendar_event.until_time, &caltime);
1188
1189                 if (caltime.type == CALENDAR_TIME_UTIME)
1190                 {
1191                     char *tmp_tzid = NULL;
1192                     tmp_tzid = _cal_time_convert_ltos(NULL, caltime.time.utime);
1193                     if (tmp_tzid)
1194                     {
1195                         snprintf(tmp, sizeof(tmp), "%s", tmp_tzid);
1196                         CAL_FREE(tmp_tzid);
1197                     }
1198                 }
1199                 else
1200                 {
1201                         snprintf(tmp, sizeof(tmp), "%04d%02d%02dT000000Z",
1202                                         caltime.time.date.year,
1203                                         caltime.time.date.month,
1204                                         caltime.time.date.mday);
1205                 }
1206                 strcat(buf, ";UNTIL=");
1207                 strcat(buf, tmp);
1208                 break;
1209
1210         case CALENDAR_RANGE_NONE:
1211                 break;
1212         default:
1213                 break;
1214         }
1215         return __cal_vcalendar_make_printf(b, "RRULE:", buf);
1216 }
1217 /////////////////////////////////////////////////////////////////////////////
1218
1219 int __cal_vcalendar_make_child_extended(cal_make_s *b, calendar_record_h child)
1220 {
1221         int ret;
1222         char *key = NULL;
1223         char *value = NULL;
1224         if (NULL == child)
1225         {
1226                 ERR("Invalid argument: child is NULL");
1227                 return CALENDAR_ERROR_INVALID_PARAMETER;
1228         }
1229
1230         ret = calendar_record_get_str_p(child, _calendar_extended_property.key, &key);
1231         if (CALENDAR_ERROR_NONE != ret)
1232         {
1233                 ERR("calendar_record_get_str_p() failed");
1234                 return ret;
1235         }
1236         if (NULL == key || strncmp(key, "X-", strlen("X-")))
1237         {
1238                 DBG("Not extended for vcalendar[%s]", key);
1239                 return CALENDAR_ERROR_NONE;
1240         }
1241
1242         ret = calendar_record_get_str_p(child, _calendar_extended_property.value, &value);
1243         if (CALENDAR_ERROR_NONE != ret)
1244         {
1245                 ERR("calendar_record_get_str_p() failed");
1246                 return ret;
1247         }
1248         ret = __cal_vcalendar_make_printf(b, key, value);
1249         if (CALENDAR_ERROR_NONE != ret)
1250         {
1251                 ERR("__cal_vcalendar_make_printf() failed");
1252                 return ret;
1253         }
1254
1255         return CALENDAR_ERROR_NONE;
1256 }
1257
1258 int __cal_vcalendar_make_printf_str_p(calendar_record_h record, unsigned int property_id, cal_make_s *b, const char *property_str)
1259 {
1260         int ret;
1261         char *strval = NULL;
1262
1263         ret = calendar_record_get_str_p(record, property_id, &strval);
1264         if (CALENDAR_ERROR_NONE != ret)
1265         {
1266                 ERR("calendar_record_get_str_p() failed(ret:%d): categories", ret);
1267                 return ret;
1268         }
1269         if (strval && (strlen(strval) > 0))
1270         {
1271                 ret = __cal_vcalendar_make_printf(b, property_str, strval);
1272                 if (CALENDAR_ERROR_NONE != ret)
1273                 {
1274                         ERR("__cal_vcalendar_make_printf() failed(ret:%d)", ret);
1275                         return ret;
1276                 }
1277         }
1278         return CALENDAR_ERROR_NONE;
1279 }
1280
1281 int __cal_vcalendar_make_schedule(int version, cal_make_s *b, calendar_record_h record)
1282 {
1283         int ret;
1284         int freq;
1285         int intval;
1286         char *strval = NULL;
1287         char *strval2 = NULL;
1288         calendar_time_s caltime = {0};
1289         char *uri = NULL;
1290         char *tzid = NULL;
1291
1292         ret = calendar_record_get_uri_p(record, &uri);
1293
1294         //_cal_db_rrule_fill_record(record);
1295
1296         ret = __cal_vcalendar_make_printf(b, "BEGIN:VEVENT", NULL);
1297         retv_if(ret != CALENDAR_ERROR_NONE, ret);
1298
1299         // sensitivity
1300         ret = calendar_record_get_int(record, _calendar_event.sensitivity, &intval);
1301         retvm_if(ret != CALENDAR_ERROR_NONE, -1,
1302                         "Failed to get sensitivity(%d)", ret);
1303
1304         __cal_vcalendar_make_class(b, intval);
1305         retv_if(ret != CALENDAR_ERROR_NONE, ret);
1306
1307         // busy_status
1308         ret = calendar_record_get_int(record, _calendar_event.busy_status, &intval);
1309         retvm_if(ret != CALENDAR_ERROR_NONE, -1,
1310                         "Failed to get busy_status(%d)", ret);
1311
1312         ret = __cal_vcalendar_make_transp(b, intval);
1313         retv_if(ret != CALENDAR_ERROR_NONE, ret);
1314
1315         // dtstart_type
1316         ret = calendar_record_get_str_p(record, _calendar_event.start_tzid, &tzid);
1317         ret = calendar_record_get_caltime(record, _calendar_event.start_time, &caltime);
1318         if (ret != CALENDAR_ERROR_NONE) {
1319                 ERR("Failed to get start_time(%d)", ret);
1320                 return -1;
1321         }
1322         ret = __cal_vcalendar_make_dtstart(version, b, tzid, &caltime);
1323         retvm_if(ret != CALENDAR_ERROR_NONE, -1, "Failed to get dtstart(%d)", ret);
1324
1325
1326         // created_time
1327 /* keis want to skip for there potential error.
1328         ret = calendar_record_get_lli(record, _calendar_event.created_time, &llival);
1329         retvm_if(ret != CALENDAR_ERROR_NONE, -1,
1330                         "Failed to get created_time(%d)", ret);
1331
1332         ret = __cal_vcalendar_make_created(b, llival);
1333         retv_if(ret != CALENDAR_ERROR_NONE, ret);
1334 */
1335
1336         // description
1337         __cal_vcalendar_make_printf_str_p(record, _calendar_event.description, b, "DESCRIPTION:");
1338
1339         // rrule
1340         ret = calendar_record_get_int(record, _calendar_event.freq, &freq);
1341         retvm_if(ret != CALENDAR_ERROR_NONE, ret,
1342                         "Failed to get last_modified_time(%d)", ret);
1343         if (freq)
1344         {
1345                 switch (version)
1346                 {
1347                 case 1:
1348                         ret = __cal_vcalendar_make_rrule_ver1(b, record);
1349                         break;
1350
1351                 default:
1352                         __cal_vcalendar_make_rrule(b, freq, record);
1353                 }
1354         }
1355
1356         // last_mod
1357 /* keis want to skip for there potential error.
1358         ret = calendar_record_get_lli(record, _calendar_event.last_modified_time, &llival);
1359         retvm_if(ret != CALENDAR_ERROR_NONE, -1,
1360                         "Failed to get last_modified_time(%d)", ret);
1361
1362         ret = __cal_vcalendar_make_last_mod(b, llival);
1363         retv_if(ret != CALENDAR_ERROR_NONE, ret);
1364 */
1365         // location
1366         __cal_vcalendar_make_printf_str_p(record, _calendar_event.location, b, "LOCATION:");
1367
1368         // organizer email
1369         strval = NULL;
1370         strval2 = NULL;
1371         ret = calendar_record_get_str_p(record, _calendar_event.organizer_name, &strval);
1372         retvm_if(ret != CALENDAR_ERROR_NONE, -1,
1373                         "Failed to get organizer_name(%d)", ret);
1374
1375         ret = calendar_record_get_str_p(record, _calendar_event.organizer_email, &strval2);
1376         retvm_if(ret != CALENDAR_ERROR_NONE, -1,
1377                         "Failed to get organizer_email(%d)", ret);
1378
1379         if (strval || strval2) {
1380                 ret = __cal_vcalendar_make_organizer(b, strval, strval2);
1381                 retv_if(ret != CALENDAR_ERROR_NONE, ret);
1382
1383         } else {
1384                 DBG("No organizer name or email");
1385         }
1386
1387         // priority
1388         ret = calendar_record_get_int(record, _calendar_event.priority, &intval);
1389         retvm_if(ret != CALENDAR_ERROR_NONE, -1,
1390                         "Failed to get priority(%d)", ret);
1391
1392         DBG("priority(%d)", intval);
1393         ret = __cal_vcalendar_make_priority(b, intval);
1394         retv_if(ret != CALENDAR_ERROR_NONE, ret);
1395
1396         // TODO : seq
1397
1398         // dtstamp
1399 /* keis want to skip for there potential error.
1400         ret = __cal_vcalendar_make_dtstamp(b, tzid);
1401         retv_if(ret != CALENDAR_ERROR_NONE, ret);
1402 */
1403
1404         // summary
1405         __cal_vcalendar_make_printf_str_p(record, _calendar_event.summary, b, "SUMMARY:");
1406
1407         // dtend
1408         ret = calendar_record_get_caltime(record, _calendar_event.end_time, &caltime);
1409         retvm_if(ret != CALENDAR_ERROR_NONE, -1,
1410                         "Failed to get end_time(%d)", ret);
1411
1412         ret = __cal_vcalendar_make_dtend(version, b, tzid, &caltime);
1413         retvm_if(ret != CALENDAR_ERROR_NONE, -1, "Failed to get end(%d)", ret);
1414
1415         // categories
1416         __cal_vcalendar_make_printf_str_p(record, _calendar_event.categories, b, "CATEGORIES:");
1417
1418         // uid
1419         __cal_vcalendar_make_printf_str_p(record, _calendar_event.uid, b, "UID:");
1420
1421         // exdate
1422         __cal_vcalendar_make_printf_str_p(record, _calendar_event.exdate, b, "EXDATE:");
1423
1424         unsigned int count;
1425         calendar_record_h child = NULL;
1426
1427         // attendee
1428         count = 0;
1429         ret = calendar_record_get_child_record_count(record,
1430                         _calendar_event.calendar_attendee, &count);
1431         retvm_if(ret != CALENDAR_ERROR_NONE, -1,
1432                         "Failed to get child count(%d)", ret);
1433
1434         while (count > 0)
1435         {
1436                 count--;
1437                 ret = calendar_record_get_child_record_at_p(record,
1438                                 _calendar_event.calendar_attendee, count, &child);
1439                 retvm_if(ret != CALENDAR_ERROR_NONE, -1,
1440                                 "Failed to get child attendee(%d)", ret);
1441
1442                 ret = __cal_vcalendar_make_attendee(b, child);
1443                 retv_if(ret != CALENDAR_ERROR_NONE, ret);
1444         }
1445         if (count <= 0)
1446         {
1447                 DBG("No attendee");
1448         }
1449
1450         // alarm
1451         count = 0;
1452         switch (version)
1453         {
1454         case 1:
1455                 // In ver 1.0, only first alarm will be dealt with.
1456                 ret = calendar_record_get_child_record_count(record, _calendar_event.calendar_alarm, &count);
1457                 retvm_if(ret != CALENDAR_ERROR_NONE, -1, "Failed to get child count(%d)", ret);
1458                 if (count > 0)
1459                 {
1460                         ret = calendar_record_get_child_record_at_p(record, _calendar_event.calendar_alarm, 0, &child);
1461                         retvm_if(ret != CALENDAR_ERROR_NONE, -1, "Failed to get child alarm(%d)", ret);
1462
1463                         ret = __cal_vcalendar_make_aalarm(b, record, child);
1464                         retv_if(ret != CALENDAR_ERROR_NONE, ret);
1465                 }
1466                 else
1467                 {
1468                         DBG("No alarm in ver1.0");
1469                 }
1470                 break;
1471
1472         default:
1473                 ret = calendar_record_get_child_record_count(record, _calendar_event.calendar_alarm, &count);
1474                 retvm_if(ret != CALENDAR_ERROR_NONE, -1, "Failed to get child count(%d)", ret);
1475
1476                 while (count > 0)
1477                 {
1478                         count--;
1479                         ret = calendar_record_get_child_record_at_p(record, _calendar_event.calendar_alarm, count, &child);
1480                         retvm_if(ret != CALENDAR_ERROR_NONE, -1, "Failed to get child alarm(%d)", ret);
1481
1482                         ret = __cal_vcalendar_make_alarm(b, child);
1483                         retv_if(ret != CALENDAR_ERROR_NONE, ret);
1484                 }
1485
1486                 if (count <= 0)
1487                 {
1488                         DBG("No alarm in ver2.0");
1489                 }
1490         }
1491
1492         // extended
1493         count = 0;
1494         ret = calendar_record_get_child_record_count(record, _calendar_event.extended, &count);
1495         retvm_if(ret != CALENDAR_ERROR_NONE, -1, "Failed to get child count(%d)", ret);
1496
1497         while (count > 0)
1498         {
1499                 count--;
1500                 ret = calendar_record_get_child_record_at_p(record, _calendar_event.extended, count, &child);
1501                 retvm_if(ret != CALENDAR_ERROR_NONE, -1, "Failed to get child alarm(%d)", ret);
1502
1503                 ret = __cal_vcalendar_make_child_extended(b, child);
1504                 retv_if(ret != CALENDAR_ERROR_NONE, ret);
1505         }
1506
1507         if (count <= 0)
1508         {
1509                 DBG("No extended");
1510         }
1511
1512         return __cal_vcalendar_make_printf(b, "END:VEVENT", NULL);
1513 }
1514
1515 int __cal_vcalendar_make_todo(int version, cal_make_s *b, calendar_record_h record)
1516 {
1517         int ret;
1518         int intval;
1519         calendar_time_s caltime = {0};
1520         char *uri = NULL;
1521         char *tzid = NULL;
1522
1523         ret = calendar_record_get_uri_p(record, &uri);
1524
1525         //_cal_db_rrule_fill_record(record);
1526
1527         ret = __cal_vcalendar_make_printf(b, "BEGIN:VTODO", NULL);
1528         retv_if(ret != CALENDAR_ERROR_NONE, ret);
1529
1530         // sensitivity
1531         ret = calendar_record_get_int(record, _calendar_todo.sensitivity, &intval);
1532         retvm_if(ret != CALENDAR_ERROR_NONE, -1,
1533                         "Failed to get sensitivity(%d)", ret);
1534
1535         __cal_vcalendar_make_class(b, intval);
1536         retv_if(ret != CALENDAR_ERROR_NONE, ret);
1537
1538         // dtstart_type
1539         ret = calendar_record_get_str_p(record, _calendar_todo.start_tzid, &tzid);
1540         ret = calendar_record_get_caltime(record, _calendar_todo.start_time, &caltime);
1541         if (ret != CALENDAR_ERROR_NONE) {
1542                 ERR("Failed to get start_time(%d)", ret);
1543                 return -1;
1544         }
1545         ret = __cal_vcalendar_make_dtstart(version, b, tzid, &caltime);
1546         retvm_if(ret != CALENDAR_ERROR_NONE, -1,
1547                         "Failed to get dtstart(%d)", ret);
1548
1549         // created_time
1550 /* keis want to skip for there potential error.
1551         ret = calendar_record_get_lli(record, _calendar_todo.created_time, &llival);
1552         retvm_if(ret != CALENDAR_ERROR_NONE, -1,
1553                         "Failed to get created_time(%d)", ret);
1554
1555         ret = __cal_vcalendar_make_created(b, llival);
1556         retv_if(ret != CALENDAR_ERROR_NONE, ret);
1557 */
1558
1559         // description
1560         __cal_vcalendar_make_printf_str_p(record, _calendar_todo.description, b, "DESCRIPTION:");
1561
1562
1563         // TODO : geo
1564
1565         // last_mod
1566 /* keis want to skip for there potential error.
1567         ret = calendar_record_get_lli(record, _calendar_todo.last_modified_time, &llival);
1568         retvm_if(ret != CALENDAR_ERROR_NONE, -1,
1569                         "Failed to get last_modified_time(%d)", ret);
1570
1571         ret = __cal_vcalendar_make_last_mod(b, llival);
1572         retv_if(ret != CALENDAR_ERROR_NONE, ret);
1573 */
1574
1575         // location
1576         __cal_vcalendar_make_printf_str_p(record, _calendar_todo.location, b, "LOCATION:");
1577
1578         // priority
1579         ret = calendar_record_get_int(record, _calendar_todo.priority, &intval);
1580         retvm_if(ret != CALENDAR_ERROR_NONE, -1,
1581                         "Failed to get priority(%d)", ret);
1582
1583         DBG("priority(%d)", intval);
1584         ret = __cal_vcalendar_make_priority(b, intval);
1585         retv_if(ret != CALENDAR_ERROR_NONE, ret);
1586
1587         // TODO : seq
1588
1589         // dtstamp
1590 /* keis want to skip for there potential error.
1591         ret = __cal_vcalendar_make_dtstamp(b, tzid);
1592         retv_if(ret != CALENDAR_ERROR_NONE, ret);
1593 */
1594
1595         // summary
1596         __cal_vcalendar_make_printf_str_p(record, _calendar_todo.summary, b, "SUMMARY:");
1597
1598         // dtend
1599         ret = calendar_record_get_caltime(record, _calendar_todo.due_time, &caltime);
1600         retvm_if(ret != CALENDAR_ERROR_NONE, -1,
1601                         "Failed to get due_time(%d)", ret);
1602
1603         ret = __cal_vcalendar_make_due(version, b, tzid, &caltime);
1604         retvm_if(ret != CALENDAR_ERROR_NONE, -1, "__cal_vcalendar_make_due() failed(%d)", ret);
1605
1606         // categories
1607         __cal_vcalendar_make_printf_str_p(record, _calendar_todo.categories, b, "CATEGORIES:");
1608
1609         // uid
1610         __cal_vcalendar_make_printf_str_p(record, _calendar_todo.uid, b, "UID:");
1611
1612         // alarm
1613         unsigned int count;
1614         calendar_record_h child = NULL;
1615
1616         switch (version)
1617         {
1618         case 1:
1619                 // In ver 1.0, only first alarm will be dealt with.
1620                 ret = calendar_record_get_child_record_count(record, _calendar_todo.calendar_alarm, &count);
1621                 retvm_if(ret != CALENDAR_ERROR_NONE, -1, "Failed to get child count(%d)", ret);
1622                 if (count > 0)
1623                 {
1624                         ret = calendar_record_get_child_record_at_p(record, _calendar_todo.calendar_alarm, 0, &child);
1625                         retvm_if(ret != CALENDAR_ERROR_NONE, -1, "Failed to get child alarm(%d)", ret);
1626
1627                         ret = __cal_vcalendar_make_aalarm(b, record, child);
1628                         retv_if(ret != CALENDAR_ERROR_NONE, ret);
1629                 }
1630                 else
1631                 {
1632                         DBG("No alarm in ver1.0");
1633                 }
1634                 break;
1635
1636         default:
1637                 ret = calendar_record_get_child_record_count(record, _calendar_todo.calendar_alarm, &count);
1638                 retvm_if(ret != CALENDAR_ERROR_NONE, -1, "Failed to get child count(%d)", ret);
1639
1640                 while (count > 0)
1641                 {
1642                         count--;
1643                         ret = calendar_record_get_child_record_at_p(record, _calendar_todo.calendar_alarm, count, &child);
1644                         retvm_if(ret != CALENDAR_ERROR_NONE, -1, "Failed to get child alarm(%d)", ret);
1645
1646                         ret = __cal_vcalendar_make_alarm(b, child);
1647                         retv_if(ret != CALENDAR_ERROR_NONE, ret);
1648                 }
1649
1650                 if (count <= 0)
1651                 {
1652                         DBG("No alarm in ver2.0");
1653                 }
1654         }
1655
1656         // extended
1657         count = 0;
1658         ret = calendar_record_get_child_record_count(record, _calendar_todo.extended, &count);
1659         retvm_if(ret != CALENDAR_ERROR_NONE, -1, "Failed to get child count(%d)", ret);
1660
1661         while (count > 0)
1662         {
1663                 count--;
1664                 ret = calendar_record_get_child_record_at_p(record, _calendar_todo.extended, count, &child);
1665                 retvm_if(ret != CALENDAR_ERROR_NONE, -1, "Failed to get child alarm(%d)", ret);
1666
1667                 ret = __cal_vcalendar_make_child_extended(b, child);
1668                 retv_if(ret != CALENDAR_ERROR_NONE, ret);
1669         }
1670         if (count <= 0)
1671         {
1672                 DBG("No extended");
1673         }
1674
1675         return __cal_vcalendar_make_printf(b, "END:VTODO", NULL);
1676 }
1677
1678 int __cal_vcalendar_make_parent_extended(cal_make_s *b, calendar_list_h list, int *has_extended, int *version)
1679 {
1680         int ret = CALENDAR_ERROR_NONE;
1681         GList *l = NULL;
1682         cal_list_s *cal_list = (cal_list_s *)list;
1683
1684         if (NULL == list)
1685         {
1686                 ERR("Invalid parameter: list is NULL");
1687                 return CALENDAR_ERROR_DB_FAILED;
1688         }
1689
1690         l = g_list_first(cal_list->record);
1691         while (l)
1692         {
1693                 char *uri = NULL;
1694                 calendar_record_h record = (calendar_record_h)l->data;
1695                 calendar_record_get_uri_p(record, &uri);
1696                 if (strncmp(uri, _calendar_extended_property._uri, strlen(_calendar_extended_property._uri)))
1697                 {
1698                         l = g_list_next(l);
1699                         continue;
1700                 }
1701
1702                 *has_extended = 1;
1703                 cal_extended_s *extended = (cal_extended_s *)record;
1704                 if (NULL == extended)
1705                 {
1706                         ERR("extended is NULL");
1707                         return CALENDAR_ERROR_DB_FAILED;
1708                 }
1709                 ret = __cal_vcalendar_make_printf(b, extended->key, extended->value);
1710                 DBG("extended key[%s] value[%s]", extended->key, extended->value);
1711                 if (!strncmp(extended->key, "VERSION", strlen("VERSION")))
1712                 {
1713                         if (strstr(extended->value, "1.0"))
1714                         {
1715                                 *version = 1;
1716                         }
1717                         else
1718                         {
1719                                 *version = 2;
1720                         }
1721
1722                         DBG("version (%s)", extended->value);
1723                         break;
1724                 }
1725                 l = g_list_next(l);
1726         }
1727         return CALENDAR_ERROR_NONE;
1728 }
1729
1730 int _cal_vcalendar_make_vcalendar(cal_make_s *b, calendar_list_h list)
1731 {
1732         int ret;
1733         int version = 0;
1734         int has_extended = 0;
1735         char *uri = NULL;
1736         calendar_record_h record;
1737
1738         ret = __cal_vcalendar_make_printf(b, "BEGIN:VCALENDAR", NULL);
1739         retv_if(ret != CALENDAR_ERROR_NONE, ret);
1740
1741         ret = __cal_vcalendar_make_parent_extended(b, list, &has_extended, &version);
1742         retv_if(ret != CALENDAR_ERROR_NONE, ret);
1743
1744         if (has_extended == 0)
1745         {
1746 /* keis want to skip for there potential error.
1747                 ret = __cal_vcalendar_make_printf(b, "CALSCALE:GREGORIAN", NULL);
1748                 retv_if(ret != CALENDAR_ERROR_NONE, ret);
1749
1750                 ret = __cal_vcalendar_make_printf(b, "PRODID:-//Samsung Electronics//Calendar//EN", NULL);
1751                 retv_if(ret != CALENDAR_ERROR_NONE, ret);
1752 */
1753
1754                 ret = __cal_vcalendar_make_printf(b, "VERSION:2.0", NULL);
1755                 retv_if(ret != CALENDAR_ERROR_NONE, ret);
1756         }
1757
1758         ret = calendar_list_first(list);
1759         retvm_if(ret != CALENDAR_ERROR_NONE, ret,
1760                         "calendar_list_first() Failed");
1761
1762         do
1763         {
1764                 ret = calendar_list_get_current_record_p(list, &record);
1765                 if (ret != CALENDAR_ERROR_NONE)
1766                 {
1767                         ERR("Failed to get current record(%d)", ret);
1768                         break;
1769                 }
1770                 ret = calendar_record_get_uri_p(record, &uri);
1771                 if (!strcmp(uri, CALENDAR_VIEW_EVENT))
1772                 {
1773                         ret = __cal_vcalendar_make_schedule(version, b, record);
1774
1775                 }
1776                 else if (!strcmp(uri, CALENDAR_VIEW_TODO))
1777                 {
1778                         ret = __cal_vcalendar_make_todo(version, b, record);
1779
1780                 }
1781
1782                 if (ret != CALENDAR_ERROR_NONE)
1783                 {
1784                         ERR("__cal_vcalendar_make_schedule() Failed(%d)", ret);
1785                         break;
1786                 }
1787         } while(calendar_list_next(list) != CALENDAR_ERROR_NO_DATA);
1788
1789         __cal_vcalendar_make_printf(b, "END:VCALENDAR", NULL);
1790
1791         return CALENDAR_ERROR_NONE;
1792 }
1793