remove return on void function
[framework/osp/social.git] / src / FScl_CalEventImpl.cpp
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 /**
17  * @file                FScl_CalEventImpl.cpp
18  * @brief               This is the implementation for _CalEventImpl class.
19  *
20  * This file contains definitions of @e _CalEventImpl class.
21  */
22
23 #include <new>
24 #include <string.h>
25 #include <FBaseColArrayList.h>
26 #include <FSysSystemTime.h>
27 #include <FLclTimeZone.h>
28 #include <FLclGregorianCalendar.h>
29 #include <FLclCalendar.h>
30 #include <FSclAttendee.h>
31 #include <FSclRecord.h>
32 #include <FSclCalEvent.h>
33 #include <FBaseSysLog.h>
34 #include <FApp_AppInfo.h>
35 #include <FBase_StringConverter.h>
36 #include "FScl_RecordImpl.h"
37 #include "FScl_CalEventImpl.h"
38 #include "FScl_RecurrenceImpl.h"
39 #include "FScl_CalendarbookImpl.h"
40 #include "FScl_CalendarbookDbConnector.h"
41
42 using namespace Tizen::Base;
43 using namespace Tizen::Base::Collection;
44 using namespace Tizen::Base::Utility;
45 using namespace Tizen::App;
46 using namespace Tizen::System;
47 using namespace Tizen::Locales;
48
49 namespace Tizen { namespace Social
50 {
51
52 static const int _DEFAULT_ADDED_HOUR = 1;
53 static const int _INVALID_ATTENDEE_INDEX = -1;
54
55 static const int _TERM_LIMIT_DAILY = 1;
56 static const int _TERM_LIMIT_WEEKLY = 7;
57 static const int _TERM_LIMIT_MONTHLY = 31;
58 static const int _TERM_LIMIT_YEARLY = 366;
59 static const int _NUMBER_OF_DAYS_OF_WEEK = 7;
60
61 static const wchar_t* _EVENT_CATEGORY_APPOINTMENT_STRING = L"Appointment";
62 static const wchar_t* _EVENT_CATEGORY_ANNIVERSARY_STRING = L"Anniversary";
63
64 static const wchar_t* _RECURRENCE_KEYWORD_SUNDAY = L"SU";
65 static const wchar_t* _RECURRENCE_KEYWORD_MONDAY = L"MO";
66 static const wchar_t* _RECURRENCE_KEYWORD_TUESDAY = L"TU";
67 static const wchar_t* _RECURRENCE_KEYWORD_WEDNESDAY = L"WE";
68 static const wchar_t* _RECURRENCE_KEYWORD_THURSDAY = L"TH";
69 static const wchar_t* _RECURRENCE_KEYWORD_FRIDAY = L"FR";
70 static const wchar_t* _RECURRENCE_KEYWORD_SATURDAY = L"SA";
71
72 static const wchar_t* _RECURRENCE_DELIMITER = L",";
73 static const int _RECURRENCE_DELIMITER_LENGTH = 1;
74 static const wchar_t _RECURRENCE_BY_DAY_CHAR_PLUS = L'+';
75 static const wchar_t _RECURRENCE_BY_DAY_CHAR_MINUS = L'-';
76 static const wchar_t _RECURRENCE_BY_DAY_CHAR_ONE = L'1';
77 static const int _RECURRENCE_BY_DAY_FIRST_INDEX = 0;
78 static const int _RECURRENCE_BY_DAY_SECOND_INDEX = 1;
79 static const int _MAX_WEEK_OF_MONTH = 5;
80
81 static const double _MIN_LATITUDE = -90.0;
82 static const double _MAX_LATITUDE = 90.0;
83 static const double _MIN_LONGITUDE = -180.0;
84 static const double _MAX_LONGITUDE = 180.0;
85
86 _CalEventImpl::_CalEventImpl(void)
87         : __originalEventId(INVALID_RECORD_ID)
88         , __isInstance(false)
89         , __reminderListUpdated(false)
90 {
91         // Set default start and end time
92         result r = E_SUCCESS;
93         DateTime startTime;
94         SystemTime::GetCurrentTime(startTime);
95         if (IsFailed(GetLastResult()))
96         {
97                 startTime = _CalendarbookImpl::GetMinDateTime();
98                 ClearLastResult();
99         }
100
101         DateTime endTime(startTime);
102         r = endTime.AddHours(_DEFAULT_ADDED_HOUR);
103         SysTryReturnVoidResult(NID_SCL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
104
105         calendar_time_s startCalendarTime;
106         calendar_time_s endCalendarTime;
107         startCalendarTime.type = CALENDAR_TIME_UTIME;
108         endCalendarTime.type = CALENDAR_TIME_UTIME;
109         startCalendarTime.time.utime = _CalendarbookUtil::ConvertDateTimeToEpochTime(startTime);
110         endCalendarTime.time.utime = _CalendarbookUtil::ConvertDateTimeToEpochTime(endTime);
111
112         int errorCode = CALENDAR_ERROR_NONE;
113         calendar_record_h eventHandle = null;
114
115         r = _CalendarbookDbConnector::Connect();
116         SysTryReturnVoidResult(NID_SCL, r == E_SUCCESS, E_SYSTEM, "[E_SYSTEM] A system error has been occurred.");
117
118         errorCode = calendar_record_create(_calendar_event._uri, &eventHandle);
119         SysTryReturnVoidResult(NID_SCL, errorCode == CALENDAR_ERROR_NONE, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
120
121         __eventRecord.ResetHandle(eventHandle);
122
123         calendar_record_set_caltime(eventHandle, _calendar_event.start_time, startCalendarTime);
124         calendar_record_set_caltime(eventHandle, _calendar_event.end_time, endCalendarTime);
125
126         // default value
127         calendar_record_set_int(eventHandle, _calendar_event.event_status, CALENDAR_EVENT_STATUS_NONE);
128         calendar_record_set_int(eventHandle, _calendar_event.busy_status, CALENDAR_EVENT_BUSY_STATUS_FREE);
129         calendar_record_set_int(eventHandle, _calendar_event.priority, CALENDAR_EVENT_PRIORITY_NORMAL);
130         calendar_record_set_int(eventHandle, _calendar_event.sensitivity, CALENDAR_SENSITIVITY_PUBLIC);
131
132         r = __reminderList.Construct();
133         SysTryReturnVoidResult(NID_SCL, r == E_SUCCESS, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
134 }
135
136 _CalEventImpl::_CalEventImpl(const _CalEventImpl& rhs)
137         : __originalEventId(rhs.__originalEventId)
138         , __isInstance(rhs.__isInstance)
139         , __reminderListUpdated(false)
140 {
141         int errorCode = CALENDAR_ERROR_NONE;
142         calendar_record_h eventHandle = null;
143
144         result r = _CalendarbookDbConnector::Connect();
145         SysTryReturnVoidResult(NID_SCL, r == E_SUCCESS, E_SYSTEM, "[E_SYSTEM] A system error has been occurred.");
146
147         errorCode = calendar_record_clone(rhs.__eventRecord.GetHandle(), &eventHandle);
148         SysTryReturnVoidResult(NID_SCL, errorCode == CALENDAR_ERROR_NONE, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
149
150         __eventRecord.ResetHandle(eventHandle);
151
152         r = __reminderList.Construct();
153         SysTryReturnVoidResult(NID_SCL, r == E_SUCCESS, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
154 }
155
156 _CalEventImpl::~_CalEventImpl(void)
157 {
158         calendar_record_destroy(__eventRecord.ReleaseHandle(), true);
159
160         __reminderList.RemoveAll(true);
161
162         result r = _CalendarbookDbConnector::Disconnect();
163         SysTryReturnVoidResult(NID_SCL, r == E_SUCCESS, E_SYSTEM, "[E_SYSTEM] A system error has been occurred.");
164 }
165
166 _CalEventImpl&
167 _CalEventImpl::operator =(const _CalEventImpl& rhs)
168 {
169         if (this == &rhs)
170         {
171                 return *this;
172         }
173
174         __originalEventId = rhs.__originalEventId;
175         __isInstance = rhs.__isInstance;
176         __reminderList.RemoveAll(true);
177         __reminderListUpdated = false;
178
179         int errorCode = CALENDAR_ERROR_NONE;
180         calendar_record_h eventHandle = null;
181
182         errorCode = calendar_record_clone(rhs.__eventRecord.GetHandle(), &eventHandle);
183         SysTryReturn(NID_SCL, errorCode == CALENDAR_ERROR_NONE, *this, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
184
185         __eventRecord.ResetHandle(eventHandle);
186
187         return *this;
188 }
189
190 bool
191 _CalEventImpl::IsInstance(void) const
192 {
193         return __isInstance;
194 }
195
196 bool
197 _CalEventImpl::IsRecurring(void) const
198 {
199         int recurrenceFreq = CALENDAR_RECURRENCE_NONE;
200
201         calendar_record_get_int(__eventRecord.GetHandle(), _calendar_event.freq, &recurrenceFreq);
202
203         if (recurrenceFreq == CALENDAR_RECURRENCE_NONE)
204         {
205                 return false;
206         }
207
208         return true;
209 }
210
211 RecordId
212 _CalEventImpl::GetOriginalCalEventId(void)  const
213 {
214         return __originalEventId;
215 }
216
217 bool
218 _CalEventImpl::IsAllDayEvent(void)  const
219 {
220         calendar_time_s startCalendarTime;
221
222         calendar_record_get_caltime(__eventRecord.GetHandle(), _calendar_event.start_time, &startCalendarTime);
223         if (startCalendarTime.type == CALENDAR_TIME_UTIME)
224         {
225                 return false;
226         }
227
228         return true;
229 }
230
231 void
232 _CalEventImpl::SetAllDayEvent(bool isAllDayEvent)
233 {
234         if (GetCategory() == EVENT_CATEGORY_ANNIVERSARY)
235         {
236                 return;
237         }
238
239         int errorCode = CALENDAR_ERROR_NONE;
240         calendar_time_s startCalendarTime;
241         calendar_time_s tmpStartCalendarTime;
242         calendar_time_s endCalendarTime;
243         calendar_time_s tmpEndCalendarTime;
244
245         bool isChanged = false;
246
247         calendar_record_get_caltime(__eventRecord.GetHandle(), _calendar_event.start_time, &startCalendarTime);
248         calendar_record_get_caltime(__eventRecord.GetHandle(), _calendar_event.end_time, &endCalendarTime);
249
250         if (isAllDayEvent && startCalendarTime.type == CALENDAR_TIME_UTIME)
251         {
252                 tmpStartCalendarTime.type = CALENDAR_TIME_LOCALTIME;
253                 DateTime tmpStartTime = _CalendarbookUtil::ConvertEpochTimeToDateTime(startCalendarTime.time.utime);
254                 tmpStartCalendarTime.time.date.year = tmpStartTime.GetYear();
255                 tmpStartCalendarTime.time.date.month = tmpStartTime.GetMonth();
256                 tmpStartCalendarTime.time.date.mday = tmpStartTime.GetDay();
257
258                 tmpEndCalendarTime.type = CALENDAR_TIME_LOCALTIME;
259                 DateTime tmpEndTime = _CalendarbookUtil::ConvertEpochTimeToDateTime(endCalendarTime.time.utime);
260                 tmpEndCalendarTime.time.date.year = tmpEndTime.GetYear();
261                 tmpEndCalendarTime.time.date.month = tmpEndTime.GetMonth();
262                 tmpEndCalendarTime.time.date.mday = tmpEndTime.GetDay();
263
264                 calendar_record_set_caltime(__eventRecord.GetHandle(), _calendar_event.start_time, tmpStartCalendarTime);
265                 calendar_record_set_caltime(__eventRecord.GetHandle(), _calendar_event.end_time, tmpEndCalendarTime);
266
267                 isChanged = true;
268         }
269         else if (!isAllDayEvent && startCalendarTime.type == CALENDAR_TIME_LOCALTIME)
270         {
271                 tmpStartCalendarTime.type = CALENDAR_TIME_UTIME;
272                 DateTime tmpStartTime;
273                 tmpStartTime.SetValue(startCalendarTime.time.date.year, startCalendarTime.time.date.month, startCalendarTime.time.date.mday);
274                 tmpStartCalendarTime.time.utime = _CalendarbookUtil::ConvertDateTimeToEpochTime(tmpStartTime);
275
276                 tmpEndCalendarTime.type = CALENDAR_TIME_UTIME;
277                 DateTime tmpEndTime;
278                 tmpEndTime.SetValue(endCalendarTime.time.date.year, endCalendarTime.time.date.month, endCalendarTime.time.date.mday);
279                 tmpEndCalendarTime.time.utime = _CalendarbookUtil::ConvertDateTimeToEpochTime(tmpEndTime);
280
281                 calendar_record_set_caltime(__eventRecord.GetHandle(), _calendar_event.start_time, tmpStartCalendarTime);
282                 calendar_record_set_caltime(__eventRecord.GetHandle(), _calendar_event.end_time, tmpEndCalendarTime);
283
284                 isChanged = true;
285         }
286
287         if (IsRecurring())
288         {
289                 int rangeType = CALENDAR_RANGE_NONE;
290                 calendar_record_get_int(__eventRecord.GetHandle(), _calendar_event.range_type, &rangeType);
291
292                 if (rangeType == CALENDAR_RANGE_UNTIL)
293                 {
294                         calendar_time_s untilCalendarTime;
295                         calendar_time_s tmpUntilCalendarTime;
296
297                         calendar_record_get_caltime(__eventRecord.GetHandle(), _calendar_event.until_time, &untilCalendarTime);
298                         if (isAllDayEvent && untilCalendarTime.type == CALENDAR_TIME_UTIME)
299                         {
300                                 tmpUntilCalendarTime.type = CALENDAR_TIME_LOCALTIME;
301                                 DateTime tmpUntilTime = _CalendarbookUtil::ConvertEpochTimeToDateTime(untilCalendarTime.time.utime);
302                                 tmpUntilCalendarTime.time.date.year = tmpUntilTime.GetYear();
303                                 tmpUntilCalendarTime.time.date.month = tmpUntilTime.GetMonth();
304                                 tmpUntilCalendarTime.time.date.mday = tmpUntilTime.GetDay();
305
306                                 calendar_record_set_caltime(__eventRecord.GetHandle(), _calendar_event.until_time, tmpUntilCalendarTime);
307                         }
308                         else if (!isAllDayEvent && untilCalendarTime.type == CALENDAR_TIME_LOCALTIME)
309                         {
310                                 tmpUntilCalendarTime.type = CALENDAR_TIME_UTIME;
311                                 DateTime tmpUntilTime;
312                                 tmpUntilTime.SetValue(untilCalendarTime.time.date.year, untilCalendarTime.time.date.month, untilCalendarTime.time.date.mday);
313                                 tmpUntilCalendarTime.time.utime = _CalendarbookUtil::ConvertDateTimeToEpochTime(tmpUntilTime);
314
315                                 calendar_record_set_caltime(__eventRecord.GetHandle(), _calendar_event.until_time, tmpUntilCalendarTime);
316                         }
317                 }
318
319                 if (isChanged)
320                 {
321                         if (__pRecurrence == null)
322                         {
323                                 __pRecurrence.reset(ConvertEventHandleToRecurrenceN(__eventRecord.GetHandle()));
324                         }
325
326                         std::unique_ptr<char[]> pExDates(_StringConverter::CopyToCharArrayN(ConvertRecurrenceToRRuleExDateString(*__pRecurrence.get(), isAllDayEvent)));
327                         errorCode = calendar_record_set_str(__eventRecord.GetHandle(), _calendar_event.exdate, pExDates.get());
328                         SysTryReturnVoidResult(NID_SCL, errorCode == CALENDAR_ERROR_NONE, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
329                 }
330         }
331 }
332
333 ByteBuffer*
334 _CalEventImpl::GetUIDN(void) const
335 {
336         ClearLastResult();
337
338         char* pStrUid = null;
339         calendar_record_get_str_p(__eventRecord.GetHandle(), _calendar_event.uid, &pStrUid);
340
341         if (pStrUid == null || strlen(pStrUid) == 0)
342         {
343                 return null;
344         }
345
346         ByteBuffer* pConvertedUidBuffer = _CalendarbookUtil::ConvertCharArrayToByteBufferN(pStrUid);
347         SysTryReturn(NID_SCL, pConvertedUidBuffer != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
348
349         return pConvertedUidBuffer;
350 }
351
352 result
353 _CalEventImpl::SetUID(const ByteBuffer* pUid)
354 {
355         int errorCode = CALENDAR_ERROR_NONE;
356
357         if (pUid != null)
358         {
359                 std::unique_ptr<char[]> pConvertedUidArray(_CalendarbookUtil::ConvertByteBufferToCharArrayN(*pUid));
360                 SysTryReturn(NID_SCL, pConvertedUidArray != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
361
362                 errorCode = calendar_record_set_str(__eventRecord.GetHandle(), _calendar_event.uid, pConvertedUidArray.get());
363                 SysTryReturnResult(NID_SCL, errorCode == CALENDAR_ERROR_NONE, E_OUT_OF_MEMORY, "Memory allocation failed.");
364         }
365         else
366         {
367                 errorCode = calendar_record_set_str(__eventRecord.GetHandle(), _calendar_event.uid, null);
368                 SysTryReturnResult(NID_SCL, errorCode == CALENDAR_ERROR_NONE, E_OUT_OF_MEMORY, "Memory allocation failed.");
369         }
370
371         return E_SUCCESS;
372 }
373
374 Tizen::Base::String
375 _CalEventImpl::GetUid(void) const
376 {
377         char* pStrUid = null;
378         calendar_record_get_str_p(__eventRecord.GetHandle(), _calendar_event.uid, &pStrUid);
379
380         return String(pStrUid);
381 }
382
383 void
384 _CalEventImpl::SetUid(const Tizen::Base::String& uid)
385 {
386         int errorCode = CALENDAR_ERROR_NONE;
387
388         std::unique_ptr<char[]> pStrUid(_StringConverter::CopyToCharArrayN(uid));
389         SysTryReturnVoidResult(NID_SCL, pStrUid != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
390
391         errorCode = calendar_record_set_str(__eventRecord.GetHandle(), _calendar_event.uid, pStrUid.get());
392         SysTryReturnVoidResult(NID_SCL, errorCode == CALENDAR_ERROR_NONE, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
393 }
394
395 EventStatus
396 _CalEventImpl::GetStatus(void) const
397 {
398         int srcEventStatus = CALENDAR_EVENT_STATUS_NONE;
399
400         EventStatus eventStatus = EVENT_STATUS_NONE;
401
402         calendar_record_get_int(__eventRecord.GetHandle(), _calendar_event.event_status, &srcEventStatus);
403
404         switch (srcEventStatus)
405         {
406         case CALENDAR_EVENT_STATUS_NONE:
407                 eventStatus = EVENT_STATUS_NONE;
408                 break;
409         case CALENDAR_EVENT_STATUS_TENTATIVE:
410                 eventStatus = EVENT_STATUS_TENTATIVE;
411                 break;
412         case CALENDAR_EVENT_STATUS_CONFIRMED:
413                 eventStatus = EVENT_STATUS_CONFIRMED;
414                 break;
415         case CALENDAR_EVENT_STATUS_CANCELLED:
416                 eventStatus = EVENT_STATUS_CANCELLED;
417                 break;
418         default :
419                 SysLog(NID_SCL, "The status value is invalid.");
420                 return EVENT_STATUS_NONE;
421         }
422
423         return eventStatus;
424 }
425
426 void
427 _CalEventImpl::SetStatus(EventStatus status)
428 {
429         calendar_record_set_int(__eventRecord.GetHandle(), _calendar_event.event_status, _CalendarbookUtil::ConvertEventStatusToCSEventStatus(status));
430 }
431
432 BusyStatus
433 _CalEventImpl::GetBusyStatus(void) const
434 {
435         int srcEventBusyStatus = CALENDAR_EVENT_BUSY_STATUS_FREE;
436
437         BusyStatus busyStatus = BUSY_STATUS_FREE;
438
439         calendar_record_get_int(__eventRecord.GetHandle(), _calendar_event.busy_status, &srcEventBusyStatus);
440
441         switch (srcEventBusyStatus)
442         {
443         case CALENDAR_EVENT_BUSY_STATUS_FREE:
444                 busyStatus = BUSY_STATUS_FREE;
445                 break;
446         case CALENDAR_EVENT_BUSY_STATUS_BUSY:
447                 busyStatus = BUSY_STATUS_BUSY;
448                 break;
449         case CALENDAR_EVENT_BUSY_STATUS_UNAVAILABLE:
450                 busyStatus = BUSY_STATUS_UNAVAILABLE;
451                 break;
452         case CALENDAR_EVENT_BUSY_STATUS_TENTATIVE:
453                 busyStatus = BUSY_STATUS_TENTATIVE;
454                 break;
455         default :
456                 SysLog(NID_SCL, "The busy status value is invalid.");
457                 busyStatus = BUSY_STATUS_FREE;
458                 break;
459         }
460
461         return busyStatus;
462 }
463
464 void
465 _CalEventImpl::SetBusyStatus(BusyStatus busyStatus)
466 {
467         calendar_record_set_int(__eventRecord.GetHandle(), _calendar_event.busy_status, _CalendarbookUtil::ConvertBusyStatusToCSEventBusyStatus(busyStatus));
468 }
469
470 EventPriority
471 _CalEventImpl::GetPriority(void) const
472 {
473         int srcPriority = CALENDAR_EVENT_PRIORITY_LOW;
474
475         EventPriority priority = EVENT_PRIORITY_NORMAL;
476
477         calendar_record_get_int(__eventRecord.GetHandle(), _calendar_event.priority, &srcPriority);
478
479         switch (srcPriority)
480         {
481         case CALENDAR_EVENT_PRIORITY_LOW:
482                 priority = EVENT_PRIORITY_LOW;
483                 break;
484         case CALENDAR_EVENT_PRIORITY_NONE:
485                 // fall through
486         case CALENDAR_EVENT_PRIORITY_NORMAL:
487                 priority = EVENT_PRIORITY_NORMAL;
488                 break;
489         case CALENDAR_EVENT_PRIORITY_HIGH:
490                 priority = EVENT_PRIORITY_HIGH;
491                 break;
492         default :
493                 SysLog(NID_SCL, "The priority value is invalid.");
494                 priority = EVENT_PRIORITY_NORMAL;
495         }
496
497         return priority;
498 }
499
500 void
501 _CalEventImpl::SetPriority(EventPriority priority)
502 {
503         calendar_record_set_int(__eventRecord.GetHandle(), _calendar_event.priority, _CalendarbookUtil::ConvertEventPriorityToCSEventPriority(priority));
504 }
505
506 result
507 _CalEventImpl::AddAttendee(const Attendee& attendee)
508 {
509         if (_AppInfo::GetApiVersion() == _API_VERSION_2_0)
510         {
511                 SysTryReturnResult(NID_SCL, !attendee.GetEmail().IsEmpty(), E_OBJ_ALREADY_EXIST
512                                         , "The attendee's email string is empty.");
513         }
514         else
515         {
516                 SysTryReturnResult(NID_SCL, !attendee.GetEmail().IsEmpty(), E_INVALID_ARG
517                                         , "The attendee's email string is empty.");
518         }
519
520         std::unique_ptr<char[]> pConvertedEmail(_StringConverter::CopyToCharArrayN(attendee.GetEmail()));
521         SysTryReturnResult(NID_SCL, pConvertedEmail != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
522
523         SysTryReturnResult(NID_SCL, GetAttendeeIndex(pConvertedEmail.get()) == _INVALID_ATTENDEE_INDEX, E_OBJ_ALREADY_EXIST
524                                 , "The specified attendee already exists as this email is already registered.");
525
526         int errorCode = CALENDAR_ERROR_NONE;
527
528         std::unique_ptr<char[]> pConvertedName(_StringConverter::CopyToCharArrayN(attendee.GetName()));
529         SysTryReturnResult(NID_SCL, pConvertedName != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
530
531         std::unique_ptr<char[]> pConvertedPhoneNumber(_StringConverter::CopyToCharArrayN(attendee.GetPhoneNumber()));
532         SysTryReturnResult(NID_SCL, pConvertedPhoneNumber != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
533
534         calendar_attendee_status_e convertedStatus = CALENDAR_ATTENDEE_STATUS_TENTATIVE;
535         switch (attendee.GetStatus())
536         {
537         case ATTENDEE_STATUS_NONE:
538                 convertedStatus = CALENDAR_ATTENDEE_STATUS_COMPLETED;
539                 break;
540         case ATTENDEE_STATUS_NOT_RESPONDED:
541                 convertedStatus = CALENDAR_ATTENDEE_STATUS_PENDING;
542                 break;
543         case ATTENDEE_STATUS_ACCEPTED:
544                 convertedStatus = CALENDAR_ATTENDEE_STATUS_ACCEPTED;
545                 break;
546         case ATTENDEE_STATUS_DECLINED:
547                 convertedStatus = CALENDAR_ATTENDEE_STATUS_DECLINED;
548                 break;
549         case ATTENDEE_STATUS_TENTATIVE:
550                 convertedStatus = CALENDAR_ATTENDEE_STATUS_TENTATIVE;
551                 break;
552         default:
553                 SysLog(NID_SCL, "The attendee status value is invalid. attendee status = %d", attendee.GetStatus());
554                 convertedStatus = CALENDAR_ATTENDEE_STATUS_TENTATIVE;
555                 break;
556         }
557
558         calendar_attendee_role_e convertedRole = CALENDAR_ATTENDEE_ROLE_NON_PARTICIPANT;
559         switch (attendee.GetRole())
560         {
561         case ATTENDEE_ROLE_ATTENDEE:
562                 convertedRole = CALENDAR_ATTENDEE_ROLE_OPT_PARTICIPANT;
563                 break;
564         case ATTENDEE_ROLE_REQUIRED_ATTENDEE:
565                 convertedRole = CALENDAR_ATTENDEE_ROLE_REQ_PARTICIPANT;
566                 break;
567         case ATTENDEE_ROLE_ORGANIZER:
568                 convertedRole = CALENDAR_ATTENDEE_ROLE_CHAIR;
569                 break;
570         default:
571                 SysLog(NID_SCL, "The attendee role value is invalid. attendee role = %d", attendee.GetRole());
572                 convertedRole = CALENDAR_ATTENDEE_ROLE_OPT_PARTICIPANT;
573                 break;
574         }
575
576         calendar_record_h attendeeHandle = null;
577         errorCode = calendar_record_create(_calendar_attendee._uri, &attendeeHandle);
578         SysTryReturnResult(NID_SCL, errorCode == CALENDAR_ERROR_NONE, E_OUT_OF_MEMORY, "Memory allocation failed.");
579
580         errorCode = calendar_record_set_str(attendeeHandle, _calendar_attendee.name, pConvertedName.get());
581         SysTryReturnResult(NID_SCL, errorCode == CALENDAR_ERROR_NONE, E_OUT_OF_MEMORY, "Memory allocation failed.");
582         errorCode = calendar_record_set_str(attendeeHandle, _calendar_attendee.email, pConvertedEmail.get());
583         SysTryReturnResult(NID_SCL, errorCode == CALENDAR_ERROR_NONE, E_OUT_OF_MEMORY, "Memory allocation failed.");
584         errorCode = calendar_record_set_str(attendeeHandle, _calendar_attendee.number, pConvertedPhoneNumber.get());
585         SysTryReturnResult(NID_SCL, errorCode == CALENDAR_ERROR_NONE, E_OUT_OF_MEMORY, "Memory allocation failed.");
586         calendar_record_set_int(attendeeHandle, _calendar_attendee.status, convertedStatus);
587         calendar_record_set_int(attendeeHandle, _calendar_attendee.role, convertedRole);
588         calendar_record_set_int(attendeeHandle, _calendar_attendee.person_id, attendee.GetPersonId());
589
590         errorCode = calendar_record_add_child_record(__eventRecord.GetHandle(), _calendar_event.calendar_attendee, attendeeHandle);
591         SysTryReturnResult(NID_SCL, errorCode == CALENDAR_ERROR_NONE, E_OUT_OF_MEMORY, "Memory allocation failed.");
592
593         return E_SUCCESS;
594 }
595
596 result
597 _CalEventImpl::RemoveAttendee(const Attendee& attendee)
598 {
599         int index = _INVALID_ATTENDEE_INDEX;
600
601         std::unique_ptr<char[]> pConvertedEmail(_StringConverter::CopyToCharArrayN(attendee.GetEmail()));
602         SysTryReturnResult(NID_SCL, pConvertedEmail != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
603
604         index = GetAttendeeIndex(pConvertedEmail.get());
605         SysTryReturnResult(NID_SCL, index != _INVALID_ATTENDEE_INDEX, E_OBJ_NOT_FOUND, "The specified attendee does not exist.")
606
607         calendar_record_h tmpAttendeeHandle = null;
608         calendar_record_get_child_record_at_p(__eventRecord.GetHandle(), _calendar_event.calendar_attendee, index, &tmpAttendeeHandle);
609         calendar_record_remove_child_record(__eventRecord.GetHandle(), _calendar_event.calendar_attendee, tmpAttendeeHandle);
610
611         return E_SUCCESS;
612 }
613
614 IList*
615 _CalEventImpl::GetAllAttendeesN(void) const
616 {
617         ClearLastResult();
618
619         std::unique_ptr<ArrayList, AllElementsDeleter> pList(new (std::nothrow) ArrayList());
620         SysTryReturn(NID_SCL, pList != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
621         result r = pList->Construct();
622         SysTryReturn(NID_SCL, !IsFailed(r), null, r, "[%s] Propagating.", GetErrorMessage(r));
623
624         unsigned int attendeeCount = 0;
625         calendar_record_get_child_record_count(__eventRecord.GetHandle(), _calendar_event.calendar_attendee, &attendeeCount);
626
627         for (unsigned int i = 0; i < attendeeCount; i++)
628         {
629                 calendar_record_h tmpAttendeeHandle = null;
630                 char* pTmpEmail = null;
631                 char* pTmpName = null;
632                 char* pTmpPhoneNumber = null;
633                 int tmpStatus = 0;
634                 int tmpRole = 0;
635                 int tmpPersonId = -1;
636                 AttendeeStatus attendeeStatus = ATTENDEE_STATUS_NONE;
637                 AttendeeRole attendeeRole = ATTENDEE_ROLE_ATTENDEE;
638
639                 calendar_record_get_child_record_at_p(__eventRecord.GetHandle(), _calendar_event.calendar_attendee, i, &tmpAttendeeHandle);
640                 calendar_record_get_str_p(tmpAttendeeHandle, _calendar_attendee.email, &pTmpEmail);
641                 calendar_record_get_str_p(tmpAttendeeHandle, _calendar_attendee.name, &pTmpName);
642                 calendar_record_get_str_p(tmpAttendeeHandle, _calendar_attendee.number, &pTmpPhoneNumber);
643                 calendar_record_get_int(tmpAttendeeHandle, _calendar_attendee.status, &tmpStatus);
644                 calendar_record_get_int(tmpAttendeeHandle, _calendar_attendee.role, &tmpRole);
645                 calendar_record_get_int(tmpAttendeeHandle, _calendar_attendee.person_id, &tmpPersonId);
646
647                 switch (tmpStatus)
648                 {
649                 case CALENDAR_ATTENDEE_STATUS_PENDING:
650                         attendeeStatus = ATTENDEE_STATUS_NOT_RESPONDED;
651                         break;
652                 case CALENDAR_ATTENDEE_STATUS_ACCEPTED:
653                         attendeeStatus = ATTENDEE_STATUS_ACCEPTED;
654                         break;
655                 case CALENDAR_ATTENDEE_STATUS_DECLINED:
656                         attendeeStatus = ATTENDEE_STATUS_DECLINED;
657                         break;
658                 case CALENDAR_ATTENDEE_STATUS_TENTATIVE:
659                         attendeeStatus = ATTENDEE_STATUS_TENTATIVE;
660                         break;
661                 case CALENDAR_ATTENDEE_STATUS_DELEGATED:
662                         attendeeStatus = ATTENDEE_STATUS_NONE;
663                         break;
664                 case CALENDAR_ATTENDEE_STATUS_COMPLETED:
665                         attendeeStatus = ATTENDEE_STATUS_NONE;
666                         break;
667                 case CALENDAR_ATTENDEE_STATUS_IN_PROCESS:
668                         attendeeStatus = ATTENDEE_STATUS_NOT_RESPONDED;
669                         break;
670                 default:
671                         SysLog(NID_SCL, "The attendee status value is invalid. attendee status = %d", tmpStatus);
672                         attendeeStatus = ATTENDEE_STATUS_NONE;
673                         break;
674                 }
675
676                 switch (tmpRole)
677                 {
678                 case CALENDAR_ATTENDEE_ROLE_REQ_PARTICIPANT:
679                         attendeeRole = ATTENDEE_ROLE_REQUIRED_ATTENDEE;
680                         break;
681                 case CALENDAR_ATTENDEE_ROLE_OPT_PARTICIPANT:
682                         attendeeRole = ATTENDEE_ROLE_ATTENDEE;
683                         break;
684                 case CALENDAR_ATTENDEE_ROLE_NON_PARTICIPANT:
685                         attendeeRole = ATTENDEE_ROLE_ATTENDEE;
686                         break;
687                 case CALENDAR_ATTENDEE_ROLE_CHAIR:
688                         attendeeRole = ATTENDEE_ROLE_ORGANIZER;
689                         break;
690                 default:
691                         SysLog(NID_SCL, "The attendee role value is invalid. attendee role = %d", tmpRole);
692                         attendeeRole = ATTENDEE_ROLE_ATTENDEE;
693                         break;
694                 }
695
696                 Attendee* pTmpAttendee = new (std::nothrow) Attendee(pTmpEmail);
697                 SysTryReturn(NID_SCL, pTmpAttendee != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
698
699                 if (pTmpName != null && strlen(pTmpName) > 0)
700                 {
701                         pTmpAttendee->SetName(pTmpName);
702                 }
703
704                 if (pTmpPhoneNumber != null && strlen(pTmpPhoneNumber) > 0)
705                 {
706                         pTmpAttendee->SetPhoneNumber(pTmpPhoneNumber);
707                 }
708
709                 pTmpAttendee->SetStatus(attendeeStatus);
710                 pTmpAttendee->SetRole(attendeeRole);
711                 pTmpAttendee->SetPersonId(tmpPersonId);
712
713                 pList->Add(*pTmpAttendee);
714         }
715
716         return pList.release();
717 }
718
719 Tizen::Locales::TimeZone
720 _CalEventImpl::GetTimeZone(void) const
721 {
722         char* pTimeZoneId = null;
723         TimeZone timeZone;
724
725         calendar_record_get_str_p(__eventRecord.GetHandle(), _calendar_event.start_tzid, &pTimeZoneId);
726         if (pTimeZoneId != null && strlen(pTimeZoneId) > 0)
727         {
728                 TimeZone::GetTimeZone(pTimeZoneId, timeZone);
729         }
730
731         return timeZone;
732 }
733
734 result
735 _CalEventImpl::SetTimeZone(const Tizen::Locales::TimeZone& timeZone)
736 {
737         int errorCode = CALENDAR_ERROR_NONE;
738
739         std::unique_ptr<char[]> pConvertedTimeZoneId(_StringConverter::CopyToCharArrayN(timeZone.GetId()));
740         SysTryReturnResult(NID_SCL, pConvertedTimeZoneId != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
741
742         errorCode = calendar_record_set_str(__eventRecord.GetHandle(), _calendar_event.start_tzid, pConvertedTimeZoneId.get());
743         SysTryReturnResult(NID_SCL, errorCode == CALENDAR_ERROR_NONE, E_OUT_OF_MEMORY, "Memory allocation failed.");
744         errorCode = calendar_record_set_str(__eventRecord.GetHandle(), _calendar_event.end_tzid, pConvertedTimeZoneId.get());
745         SysTryReturnResult(NID_SCL, errorCode == CALENDAR_ERROR_NONE, E_OUT_OF_MEMORY, "Memory allocation failed.");
746
747         return E_SUCCESS;
748 }
749
750 RecurrenceId
751 _CalEventImpl::GetRecurrenceId(void) const
752 {
753         ClearLastResult();
754         SysTryReturn(NID_SCL, __isInstance, DateTime(), E_INVALID_STATE,
755                                 "[E_INVALID_STATE] The instance does not have a recurrence or is not a CalEvent instance which doesn't have a RecurrenceId.");
756
757         return GetStartTime();
758 }
759
760 String
761 _CalEventImpl::GetSubject(void) const
762 {
763         char* pSubject = null;
764
765         calendar_record_get_str_p(__eventRecord.GetHandle(), _calendar_event.summary, &pSubject);
766
767         return String(pSubject);
768 }
769
770 String
771 _CalEventImpl::GetDescription(void) const
772 {
773         char* pDescription = null;
774
775         calendar_record_get_str_p(__eventRecord.GetHandle(), _calendar_event.description, &pDescription);
776
777         return String(pDescription);
778 }
779 DateTime
780 _CalEventImpl::GetStartTime(void) const
781 {
782         calendar_time_s startCalendarTime;
783         DateTime tmpStartTime;
784
785         calendar_record_get_caltime(__eventRecord.GetHandle(), _calendar_event.start_time, &startCalendarTime);
786
787         if (startCalendarTime.type == CALENDAR_TIME_UTIME)
788         {
789                 tmpStartTime = _CalendarbookUtil::ConvertEpochTimeToDateTime(startCalendarTime.time.utime);
790         }
791         else
792         {
793                 tmpStartTime.SetValue(startCalendarTime.time.date.year, startCalendarTime.time.date.month, startCalendarTime.time.date.mday);
794         }
795
796         return tmpStartTime;
797 }
798
799 DateTime
800 _CalEventImpl::GetEndTime(void) const
801 {
802         calendar_time_s endCalendarTime;
803         DateTime tmpEndTime;
804
805         calendar_record_get_caltime(__eventRecord.GetHandle(), _calendar_event.end_time, &endCalendarTime);
806
807         if (endCalendarTime.type == CALENDAR_TIME_UTIME)
808         {
809                 tmpEndTime = _CalendarbookUtil::ConvertEpochTimeToDateTime(endCalendarTime.time.utime);
810         }
811         else if (endCalendarTime.type == CALENDAR_TIME_LOCALTIME)
812         {
813                 tmpEndTime.SetValue(endCalendarTime.time.date.year, endCalendarTime.time.date.month, endCalendarTime.time.date.mday);
814         }
815
816         return tmpEndTime;
817 }
818
819 String
820 _CalEventImpl::GetLocation(void) const
821 {
822         char* pLocation = null;
823
824         calendar_record_get_str_p(__eventRecord.GetHandle(), _calendar_event.location, &pLocation);
825
826         return String(pLocation);
827 }
828
829 EventCategory
830 _CalEventImpl::GetCategory(void) const
831 {
832         char* pCategories = null;
833
834         calendar_record_get_str_p(__eventRecord.GetHandle(), _calendar_event.categories, &pCategories);
835
836         return _CalendarbookUtil::ConvertCSCategoriesToEventCategory(pCategories);
837 }
838
839 RecordSensitivity
840 _CalEventImpl::GetSensitivity(void) const
841 {
842         int srcSensitivity = CALENDAR_SENSITIVITY_PUBLIC;
843         RecordSensitivity sensitivity = SENSITIVITY_PUBLIC;
844
845         calendar_record_get_int(__eventRecord.GetHandle(), _calendar_event.sensitivity, &srcSensitivity);
846
847         switch (srcSensitivity)
848         {
849         case CALENDAR_SENSITIVITY_PUBLIC:
850                 sensitivity = SENSITIVITY_PUBLIC;
851                 break;
852         case CALENDAR_SENSITIVITY_PRIVATE:
853                 sensitivity = SENSITIVITY_PRIVATE;
854                 break;
855         case CALENDAR_SENSITIVITY_CONFIDENTIAL:
856                 sensitivity = SENSITIVITY_CONFIDENTIAL;
857                 break;
858         default :
859                 SysLogException(NID_SCL, E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument is used. sensitivity = %d", srcSensitivity);
860                 sensitivity = SENSITIVITY_PUBLIC;
861         }
862
863         return sensitivity;
864 }
865
866 const Reminder*
867 _CalEventImpl::GetReminder(void) const
868 {
869         if (__reminderListUpdated == false)
870         {
871                 result r = _CalendarbookUtil::ConvertEventAlarmsToReminderList(__eventRecord.GetHandle(), __reminderList);
872                 SysTryReturn(NID_SCL, r == E_SUCCESS, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
873
874                 __reminderListUpdated = true;
875         }
876
877         if (__reminderList.GetCount() > 0)
878         {
879                 return static_cast<const Reminder*>(__reminderList.GetAt(0));
880         }
881
882         return null;
883 }
884
885 const Recurrence*
886 _CalEventImpl::GetRecurrence(void) const
887 {
888         if (__pRecurrence == null)
889         {
890                 __pRecurrence.reset(ConvertEventHandleToRecurrenceN(__eventRecord.GetHandle()));
891         }
892
893         return __pRecurrence.get();
894 }
895
896 Recurrence*
897 _CalEventImpl::ConvertEventHandleToRecurrenceN(calendar_record_h eventHandle) const
898 {
899         int srcFrequency = CALENDAR_RECURRENCE_NONE;
900         calendar_time_s untilCalendarTime;
901         int rangeType = CALENDAR_RANGE_NONE;
902         int count = 0;
903         int interval = 0;
904         char* pByDay = null;
905         char* pByMonthDay = null;
906         char* pByMonth = null;
907         int weekStart = 0;
908         char* pExDates = null;
909
910         result r = E_SUCCESS;
911         int dayOfWeek = 0;
912         int monthOfYear = 0;
913         int dayOfMonth = 0;
914         int weekOfMonth = 0;
915         CalDayOfWeek convertedWeekStart = CAL_SUNDAY;
916
917         std::unique_ptr<Recurrence> pRecurrence(new (std::nothrow) Recurrence());
918
919         calendar_record_get_int(eventHandle, _calendar_event.freq, &srcFrequency);
920
921         if (srcFrequency == CALENDAR_RECURRENCE_NONE)
922         {
923                 return null;
924         }
925
926         calendar_record_get_int(eventHandle, _calendar_event.range_type, &rangeType);
927         calendar_record_get_int(eventHandle, _calendar_event.count, &count);
928         calendar_record_get_int(eventHandle, _calendar_event.interval, &interval);
929         calendar_record_get_caltime(eventHandle, _calendar_event.until_time, &untilCalendarTime);
930         calendar_record_get_int(eventHandle, _calendar_event.wkst, &weekStart);
931
932         calendar_record_get_str_p(eventHandle, _calendar_event.byday, &pByDay);
933         calendar_record_get_str_p(eventHandle, _calendar_event.bymonthday, &pByMonthDay);
934         if (pByMonthDay != null)
935         {
936                 r = Integer::Parse(pByMonthDay, dayOfMonth);
937                 SysTryReturn(NID_SCL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
938         }
939         calendar_record_get_str_p(eventHandle, _calendar_event.bymonth, &pByMonth);
940         if (pByMonth != null)
941         {
942                 r = Integer::Parse(pByMonth, monthOfYear);
943                 SysTryReturn(NID_SCL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
944         }
945
946         switch (srcFrequency)
947         {
948         case CALENDAR_RECURRENCE_DAILY:
949                 pRecurrence->SetFrequency(FREQ_DAILY);
950                 break;
951         case CALENDAR_RECURRENCE_WEEKLY:
952                 pRecurrence->SetFrequency(FREQ_WEEKLY);
953
954                 dayOfWeek = ConvertRRuleByDayStringToDayOfWeek(pByDay);
955                 SysTryReturn(NID_SCL, GetLastResult() == E_SUCCESS, null, E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument is used. byday = %s", pByDay);
956
957                 pRecurrence->SetDayOfWeek(dayOfWeek);
958
959                 break;
960         case CALENDAR_RECURRENCE_MONTHLY:
961                 pRecurrence->SetFrequency(FREQ_MONTHLY);
962
963                 if (dayOfMonth != 0)
964                 {
965                         if (dayOfMonth < 0)
966                         {
967                                 int maxDaysOfMonth = _CalendarbookUtil::GetMaxDaysOfMonth(untilCalendarTime.time.date.year, monthOfYear);
968                                 pRecurrence->SetDayOfMonth(maxDaysOfMonth + dayOfMonth);
969                         }
970                         else
971                         {
972                                 pRecurrence->SetDayOfMonth(dayOfMonth);
973                         }
974                 }
975                 else
976                 {
977                         ConvertRRuleByDayStringToDayOfWeekAndWeekOfMonth(pByDay, weekOfMonth, dayOfWeek);
978                         SysTryReturn(NID_SCL, r == E_SUCCESS, null, E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument is used. byday = %s", pByDay);
979
980                         pRecurrence->SetWeekOfMonth(weekOfMonth);
981                         pRecurrence->SetDayOfWeek(dayOfWeek);
982                 }
983
984                 break;
985         case CALENDAR_RECURRENCE_YEARLY:
986                 pRecurrence->SetFrequency(FREQ_YEARLY);
987
988                 if (dayOfMonth != 0)
989                 {
990                         if (dayOfMonth < 0)
991                         {
992                                 int maxDaysOfMonth = _CalendarbookUtil::GetMaxDaysOfMonth(untilCalendarTime.time.date.year, monthOfYear);
993                                 pRecurrence->SetDayOfMonth(maxDaysOfMonth + dayOfMonth);
994                         }
995                         else
996                         {
997                                 pRecurrence->SetDayOfMonth(dayOfMonth);
998                         }
999                 }
1000                 else
1001                 {
1002                         r = ConvertRRuleByDayStringToDayOfWeekAndWeekOfMonth(pByDay, weekOfMonth, dayOfWeek);
1003                         SysTryReturn(NID_SCL, r == E_SUCCESS, null, E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument is used. byday = %s", pByDay);
1004
1005                         pRecurrence->SetWeekOfMonth(weekOfMonth);
1006                         pRecurrence->SetDayOfWeek(dayOfWeek);
1007                 }
1008                 pRecurrence->SetMonthOfYear(monthOfYear);
1009
1010                 break;
1011         default :
1012                 SysLogException(NID_SCL, E_INVALID_ARG, "Invalid argument is passed. frequency = %d", srcFrequency);
1013                 return null;
1014         }
1015
1016         if (rangeType == CALENDAR_RANGE_NONE)
1017         {
1018                 pRecurrence->SetUntil(&DateTime::GetMaxValue());
1019         }
1020         else if (rangeType == CALENDAR_RANGE_UNTIL)
1021         {
1022                 DateTime until;
1023
1024                 if (untilCalendarTime.type == CALENDAR_TIME_LOCALTIME)
1025                 {
1026                         until.SetValue(untilCalendarTime.time.date.year, untilCalendarTime.time.date.month, untilCalendarTime.time.date.mday);
1027                 }
1028                 else
1029                 {
1030                         until = _CalendarbookUtil::ConvertEpochTimeToDateTime(untilCalendarTime.time.utime);
1031                 }
1032
1033                 pRecurrence->SetUntil(&until);
1034         }
1035         else
1036         {
1037                 pRecurrence->SetCounts(count);
1038         }
1039         pRecurrence->SetInterval(interval);
1040
1041         switch (weekStart)
1042         {
1043         case CALENDAR_SUNDAY:
1044                 convertedWeekStart = CAL_SUNDAY;
1045                 break;
1046         case CALENDAR_MONDAY:
1047                 convertedWeekStart = CAL_MONDAY;
1048                 break;
1049         default:
1050                 SysLogException(NID_SCL, E_INVALID_ARG, "Invalid argument is passed. week start = %d", weekStart);
1051                 return null;
1052         }
1053         pRecurrence->SetWeekStart(convertedWeekStart);
1054
1055         calendar_record_get_str_p(eventHandle, _calendar_event.exdate, &pExDates);
1056         if (pExDates != null && strlen(pExDates) != 0)
1057         {
1058                 r = ConvertRRuleExDateStringToRecurrence(pExDates, *pRecurrence.get());
1059                 SysTryReturn(NID_SCL, r == E_SUCCESS, null, E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument is used. exdate = %s", pExDates);
1060         }
1061
1062         return pRecurrence.release();
1063 }
1064
1065 DateTime
1066 _CalEventImpl::GetLastRevisedTime(void) const
1067 {
1068         long long lastModifiedTime = 0;
1069         DateTime tmpLastRevisedTime;
1070
1071         calendar_record_get_lli(__eventRecord.GetHandle(), _calendar_event.last_modified_time, &lastModifiedTime);
1072
1073         tmpLastRevisedTime = _CalendarbookUtil::ConvertEpochTimeToDateTime(lastModifiedTime);
1074
1075         return tmpLastRevisedTime;
1076 }
1077
1078 result
1079 _CalEventImpl::SetSubject(const String& subject)
1080 {
1081         if (_AppInfo::GetApiVersion() == _API_VERSION_2_0 && _AppInfo::IsOspCompat())
1082         {
1083                 SysTryReturnResult(NID_SCL, subject.GetLength() <= MAX_EVENT_SUBJECT_LENGTH, E_INVALID_ARG
1084                                 , "The length of the value exceeds MAX_EVENT_SUBJECT_LENGTH.");
1085         }
1086
1087         std::unique_ptr<char[]> pConvertedSubject(_StringConverter::CopyToCharArrayN(subject));
1088         SysTryReturnResult(NID_SCL, pConvertedSubject != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
1089
1090         int errorCode = CALENDAR_ERROR_NONE;
1091         errorCode = calendar_record_set_str(__eventRecord.GetHandle(), _calendar_event.summary, pConvertedSubject.get());
1092         SysTryReturnResult(NID_SCL, errorCode == CALENDAR_ERROR_NONE, E_OUT_OF_MEMORY, "Memory allocation failed.");
1093
1094         return E_SUCCESS;
1095 }
1096
1097 result
1098 _CalEventImpl::SetDescription(const String& description)
1099 {
1100         if (_AppInfo::GetApiVersion() == _API_VERSION_2_0 && _AppInfo::IsOspCompat())
1101         {
1102                 SysTryReturnResult(NID_SCL, description.GetLength() <= MAX_EVENT_DESCRIPTION_LENGTH, E_INVALID_ARG
1103                                 , "The length of the value exceeds MAX_EVENT_DESCRIPTION_LENGTH.");
1104         }
1105
1106         std::unique_ptr<char[]> pConvertedDescription(_StringConverter::CopyToCharArrayN(description));
1107         SysTryReturnResult(NID_SCL, pConvertedDescription != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
1108
1109         int errorCode = CALENDAR_ERROR_NONE;
1110         errorCode = calendar_record_set_str(__eventRecord.GetHandle(), _calendar_event.description, pConvertedDescription.get());
1111         SysTryReturnResult(NID_SCL, errorCode == CALENDAR_ERROR_NONE, E_OUT_OF_MEMORY, "Memory allocation failed.");
1112
1113         return E_SUCCESS;
1114 }
1115
1116 result
1117 _CalEventImpl::SetLocation(const String& location)
1118 {
1119         if (_AppInfo::GetApiVersion() == _API_VERSION_2_0 && _AppInfo::IsOspCompat())
1120         {
1121                 SysTryReturnResult(NID_SCL, location.GetLength() <= MAX_EVENT_LOCATION_LENGTH, E_INVALID_ARG
1122                                 , "The length of the value exceeds MAX_EVENT_LOCATION_LENGTH.");
1123         }
1124
1125         std::unique_ptr<char[]> pConvertedLocation(_StringConverter::CopyToCharArrayN(location));
1126         SysTryReturnResult(NID_SCL, pConvertedLocation != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
1127
1128         int errorCode = CALENDAR_ERROR_NONE;
1129         errorCode = calendar_record_set_str(__eventRecord.GetHandle(), _calendar_event.location, pConvertedLocation.get());
1130         SysTryReturnResult(NID_SCL, errorCode == CALENDAR_ERROR_NONE, E_OUT_OF_MEMORY, "Memory allocation failed.");
1131
1132         return E_SUCCESS;
1133 }
1134
1135 result
1136 _CalEventImpl::SetStartAndEndTime(const DateTime& start, const DateTime& end)
1137 {
1138         int recurrenceFrequency = 0;
1139
1140         calendar_record_get_int(__eventRecord.GetHandle(), _calendar_event.freq, &recurrenceFrequency);
1141
1142         SysTryReturnResult(NID_SCL, recurrenceFrequency == CALENDAR_RECURRENCE_NONE, E_INVALID_CONDITION
1143                         , "The recurrence date is already set. Cannot modify the start and end date/time.");
1144         SysTryReturnResult(NID_SCL, _CalendarbookUtil::CheckValidDateTime(start), E_INVALID_ARG, "Invalid argument is used. start = %S", start.ToString().GetPointer());
1145         SysTryReturnResult(NID_SCL, _CalendarbookUtil::CheckValidDateTime(end), E_INVALID_ARG, "Invalid argument is used. end = %S", end.ToString().GetPointer());
1146         SysTryReturnResult(NID_SCL, start <= end, E_INVALID_ARG, "Invalid argument is used. The end date is earlier than the start date.");
1147
1148         return SetStartAndEndTimeCommon(start, end);
1149 }
1150
1151 result
1152 _CalEventImpl::SetStartAndEndTimeCommon(const DateTime& start, const DateTime& end)
1153 {
1154         calendar_time_s startCalendarTime;
1155         calendar_time_s endCalendarTime;
1156
1157         calendar_record_get_caltime(__eventRecord.GetHandle(), _calendar_event.start_time, &startCalendarTime);
1158
1159         if (startCalendarTime.type == CALENDAR_TIME_LOCALTIME)
1160         {
1161                 startCalendarTime.time.date.year = start.GetYear();
1162                 startCalendarTime.time.date.month = start.GetMonth();
1163                 startCalendarTime.time.date.mday = start.GetDay();
1164
1165                 endCalendarTime.type = CALENDAR_TIME_LOCALTIME;
1166                 endCalendarTime.time.date.year = end.GetYear();
1167                 endCalendarTime.time.date.month = end.GetMonth();
1168                 endCalendarTime.time.date.mday = end.GetDay();
1169         }
1170         else
1171         {
1172                 startCalendarTime.time.utime = _CalendarbookUtil::ConvertDateTimeToEpochTime(start);
1173
1174                 endCalendarTime.type = CALENDAR_TIME_UTIME;
1175                 endCalendarTime.time.utime = _CalendarbookUtil::ConvertDateTimeToEpochTime(end);
1176         }
1177
1178         calendar_record_set_caltime(__eventRecord.GetHandle(), _calendar_event.start_time, startCalendarTime);
1179         calendar_record_set_caltime(__eventRecord.GetHandle(), _calendar_event.end_time, endCalendarTime);
1180
1181         return E_SUCCESS;
1182 }
1183
1184 void
1185 _CalEventImpl::SetCategory(EventCategory category)
1186 {
1187         int errorCode = CALENDAR_ERROR_NONE;
1188         std::unique_ptr<char[]> pConvertedCategory;
1189
1190         if (category == EVENT_CATEGORY_ANNIVERSARY)
1191         {
1192                 SetAllDayEvent(true);
1193
1194                 pConvertedCategory.reset(_StringConverter::CopyToCharArrayN(_EVENT_CATEGORY_ANNIVERSARY_STRING));
1195                 SysTryReturnVoidResult(NID_SCL, pConvertedCategory != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
1196         }
1197         else
1198         {
1199                 pConvertedCategory.reset(_StringConverter::CopyToCharArrayN(_EVENT_CATEGORY_APPOINTMENT_STRING));
1200                 SysTryReturnVoidResult(NID_SCL, pConvertedCategory != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
1201         }
1202
1203         errorCode = calendar_record_set_str(__eventRecord.GetHandle(), _calendar_event.categories, pConvertedCategory.get());
1204         SysTryReturnVoidResult(NID_SCL, errorCode == CALENDAR_ERROR_NONE, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
1205 }
1206
1207 void
1208 _CalEventImpl::SetSensitivity(RecordSensitivity sensitivity)
1209 {
1210         calendar_record_set_int(__eventRecord.GetHandle(), _calendar_event.sensitivity, _CalendarbookUtil::ConvertSensitivityToCSSensitivity(sensitivity));
1211 }
1212
1213 result
1214 _CalEventImpl::SetCoordinates(double latitude, double longitude)
1215 {
1216         SysTryReturnResult(NID_SCL, latitude >= _MIN_LATITUDE && latitude <= _MAX_LATITUDE, E_INVALID_ARG, "Invalid argument is used. The latitude is out of range.");
1217         SysTryReturnResult(NID_SCL, longitude >= _MIN_LONGITUDE && longitude <= _MAX_LONGITUDE, E_INVALID_ARG, "Invalid argument is used. The longitude is out of range.");
1218
1219         calendar_record_set_double(__eventRecord.GetHandle(), _calendar_event.latitude, latitude);
1220         calendar_record_set_double(__eventRecord.GetHandle(), _calendar_event.longitude, longitude);
1221
1222         return E_SUCCESS;
1223 }
1224
1225 void
1226 _CalEventImpl::GetCoordinates(double& latitude, double& longitude) const
1227 {
1228         calendar_record_get_double(__eventRecord.GetHandle(), _calendar_event.latitude, &latitude);
1229         calendar_record_get_double(__eventRecord.GetHandle(), _calendar_event.longitude, &longitude);
1230 }
1231
1232 result
1233 _CalEventImpl::SetReminder(const Reminder* pReminder)
1234 {
1235         int errorCode = CALENDAR_ERROR_NONE;
1236
1237         unsigned int reminderCount = 0;
1238         calendar_record_h tmpAlarmHandle = null;
1239
1240         calendar_record_get_child_record_count(__eventRecord.GetHandle(), _calendar_event.calendar_alarm, &reminderCount);
1241
1242         if (pReminder != null)
1243         {
1244                 int convertedTimeUnit = 0;
1245                 switch (pReminder->GetTimeUnit())
1246                 {
1247                 case REMINDER_TIME_UNIT_MINUTE:
1248                         convertedTimeUnit = CALENDAR_ALARM_TIME_UNIT_MINUTE;
1249                         break;
1250                 case REMINDER_TIME_UNIT_HOUR:
1251                         convertedTimeUnit = CALENDAR_ALARM_TIME_UNIT_HOUR;
1252                         break;
1253                 case REMINDER_TIME_UNIT_DAY:
1254                         convertedTimeUnit = CALENDAR_ALARM_TIME_UNIT_DAY;
1255                         break;
1256                 case REMINDER_TIME_UNIT_WEEK:
1257                         convertedTimeUnit = CALENDAR_ALARM_TIME_UNIT_WEEK;
1258                         break;
1259                 default:
1260                         break;
1261                 }
1262
1263                 calendar_record_h tmpAlarmHandle = null;
1264
1265                 if (reminderCount > 0)
1266                 {
1267                         calendar_record_get_child_record_at_p(__eventRecord.GetHandle(), _calendar_event.calendar_alarm, 0, &tmpAlarmHandle);
1268                         calendar_record_set_int(tmpAlarmHandle, _calendar_alarm.tick_unit, convertedTimeUnit);
1269                         calendar_record_set_int(tmpAlarmHandle, _calendar_alarm.tick, pReminder->GetTimeOffset());
1270
1271                         std::unique_ptr<char[]> pTmpAlarmTone(_StringConverter::CopyToCharArrayN(pReminder->GetSoundFile()));
1272                         SysTryReturnResult(NID_SCL, pTmpAlarmTone != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
1273
1274                         errorCode = calendar_record_set_str(tmpAlarmHandle, _calendar_alarm.tone, pTmpAlarmTone.get());
1275                         SysTryReturnResult(NID_SCL, errorCode == CALENDAR_ERROR_NONE, E_OUT_OF_MEMORY, "Memory allocation failed.");
1276                 }
1277                 else
1278                 {
1279                         std::unique_ptr<char[]> pTmpAlarmTone(_StringConverter::CopyToCharArrayN(pReminder->GetSoundFile()));
1280                         SysTryReturnResult(NID_SCL, pTmpAlarmTone != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
1281
1282                         errorCode = calendar_record_create(_calendar_alarm._uri, &tmpAlarmHandle);
1283                         SysTryReturnResult(NID_SCL, errorCode == CALENDAR_ERROR_NONE, E_OUT_OF_MEMORY, "Memory allocation failed.");
1284
1285                         calendar_record_set_int(tmpAlarmHandle, _calendar_alarm.tick_unit, convertedTimeUnit);
1286                         calendar_record_set_int(tmpAlarmHandle, _calendar_alarm.tick, pReminder->GetTimeOffset());
1287                         errorCode = calendar_record_set_str(tmpAlarmHandle, _calendar_alarm.tone, pTmpAlarmTone.get());
1288                         SysTryReturnResult(NID_SCL, errorCode == CALENDAR_ERROR_NONE, E_OUT_OF_MEMORY, "Memory allocation failed.");
1289
1290                         errorCode = calendar_record_add_child_record(__eventRecord.GetHandle(), _calendar_event.calendar_alarm, tmpAlarmHandle);
1291                         SysTryReturnResult(NID_SCL, errorCode == CALENDAR_ERROR_NONE, E_OUT_OF_MEMORY, "Memory allocation failed.");
1292                 }
1293         }
1294         else
1295         {
1296                 if (reminderCount > 0)
1297                 {
1298                         calendar_record_get_child_record_at_p(__eventRecord.GetHandle(), _calendar_event.calendar_alarm, 0, &tmpAlarmHandle);
1299                         calendar_record_remove_child_record(__eventRecord.GetHandle(), _calendar_event.calendar_alarm, tmpAlarmHandle);
1300                 }
1301         }
1302
1303         __reminderList.RemoveAll(true);
1304         __reminderListUpdated = false;
1305
1306         return E_SUCCESS;
1307 }
1308
1309 result
1310 _CalEventImpl::SetRecurrence(const Recurrence* pRecurrence)
1311 {
1312         result r = E_SUCCESS;
1313         int errorCode = CALENDAR_ERROR_NONE;
1314
1315         if (pRecurrence != null)
1316         {
1317                 r = VerifyRecurrence(*pRecurrence);
1318                 SysTryReturn(NID_SCL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
1319
1320                 r = ResetStartAndEndTimeByRecurrence(*pRecurrence);
1321                 SysTryReturn(NID_SCL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
1322
1323                 r = ConvertRecurrenceToEventHandle(*pRecurrence, __eventRecord.GetHandle());
1324                 SysTryReturn(NID_SCL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
1325
1326                 std::unique_ptr<char[]> pExDates(_StringConverter::CopyToCharArrayN(ConvertRecurrenceToRRuleExDateString(*pRecurrence, IsAllDayEvent())));
1327                 errorCode = calendar_record_set_str(__eventRecord.GetHandle(), _calendar_event.exdate, pExDates.get());
1328                 SysTryReturnResult(NID_SCL, errorCode == CALENDAR_ERROR_NONE, E_OUT_OF_MEMORY, "Memory allocation failed.");
1329
1330                 __pRecurrence.reset(new (std::nothrow) Recurrence(*pRecurrence));
1331                 SysTryReturnResult(NID_SCL, __pRecurrence != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
1332         }
1333         else
1334         {
1335                 calendar_record_set_int(__eventRecord.GetHandle(), _calendar_event.freq, CALENDAR_RECURRENCE_NONE);
1336
1337                 __pRecurrence.reset(null);
1338         }
1339
1340         return E_SUCCESS;
1341 }
1342
1343 result
1344 _CalEventImpl::AddReminder(const Reminder& reminder)
1345 {
1346         int errorCode = CALENDAR_ERROR_NONE;
1347         calendar_record_h tmpAlarmHandle = null;
1348
1349         std::unique_ptr<char[]> pTmpAlarmTone(_StringConverter::CopyToCharArrayN(reminder.GetSoundFile()));
1350         SysTryReturnResult(NID_SCL, pTmpAlarmTone != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
1351
1352         errorCode = calendar_record_create(_calendar_alarm._uri, &tmpAlarmHandle);
1353         SysTryReturnResult(NID_SCL, errorCode == CALENDAR_ERROR_NONE, E_OUT_OF_MEMORY, "Memory allocation failed.");
1354
1355         int convertedTimeUnit = 0;
1356
1357         ReminderTimeUnit timeUnit = reminder.GetTimeUnit();
1358         switch (timeUnit)
1359         {
1360         case REMINDER_TIME_UNIT_MINUTE:
1361                 convertedTimeUnit = CALENDAR_ALARM_TIME_UNIT_MINUTE;
1362                 break;
1363         case REMINDER_TIME_UNIT_HOUR:
1364                 convertedTimeUnit = CALENDAR_ALARM_TIME_UNIT_HOUR;
1365                 break;
1366         case REMINDER_TIME_UNIT_DAY:
1367                 convertedTimeUnit = CALENDAR_ALARM_TIME_UNIT_DAY;
1368                 break;
1369         case REMINDER_TIME_UNIT_WEEK:
1370                 convertedTimeUnit = CALENDAR_ALARM_TIME_UNIT_WEEK;
1371                 break;
1372         case REMINDER_TIME_UNIT_NONE:
1373                 convertedTimeUnit = CALENDAR_ALARM_TIME_UNIT_SPECIFIC;
1374                 break;
1375         default:
1376                 break;
1377         }
1378
1379         calendar_record_set_int(tmpAlarmHandle, _calendar_alarm.tick_unit, convertedTimeUnit);
1380         calendar_record_set_int(tmpAlarmHandle, _calendar_alarm.tick, reminder.GetTimeOffset());
1381         errorCode = calendar_record_set_str(tmpAlarmHandle, _calendar_alarm.tone, pTmpAlarmTone.get());
1382         SysTryReturnResult(NID_SCL, errorCode == CALENDAR_ERROR_NONE, E_OUT_OF_MEMORY, "Memory allocation failed.");
1383
1384         if (convertedTimeUnit == CALENDAR_ALARM_TIME_UNIT_SPECIFIC)
1385         {
1386                 calendar_record_set_lli(tmpAlarmHandle, _calendar_alarm.time, _CalendarbookUtil::ConvertDateTimeToEpochTime(reminder.GetAbsoluteTime()));
1387         }
1388
1389         errorCode = calendar_record_add_child_record(__eventRecord.GetHandle(), _calendar_event.calendar_alarm, tmpAlarmHandle);
1390         SysTryReturnResult(NID_SCL, errorCode == CALENDAR_ERROR_NONE, E_OUT_OF_MEMORY, "Memory allocation failed.");
1391
1392         __reminderList.RemoveAll(true);
1393         __reminderListUpdated = false;
1394
1395         return E_SUCCESS;
1396 }
1397
1398 result
1399 _CalEventImpl::RemoveReminderAt(int index)
1400 {
1401         int errorCode = CALENDAR_ERROR_NONE;
1402         calendar_record_h tmpAlarmHandle = null;
1403
1404         errorCode = calendar_record_get_child_record_at_p(__eventRecord.GetHandle(), _calendar_event.calendar_alarm, index, &tmpAlarmHandle);
1405         SysTryReturnResult(NID_SCL, tmpAlarmHandle != null, E_OUT_OF_RANGE, "The index is out of range. index = %d", index);
1406
1407         calendar_record_remove_child_record(__eventRecord.GetHandle(), _calendar_event.calendar_alarm, tmpAlarmHandle);
1408
1409         __reminderList.RemoveAll(true);
1410         __reminderListUpdated = false;
1411
1412         return E_SUCCESS;
1413 }
1414
1415 const IList&
1416 _CalEventImpl::GetAllReminders(void) const
1417 {
1418         ClearLastResult();
1419
1420         if (__reminderListUpdated == false)
1421         {
1422                 result r = _CalendarbookUtil::ConvertEventAlarmsToReminderList(__eventRecord.GetHandle(), __reminderList);
1423                 SysTryReturn(NID_SCL, r == E_SUCCESS, __reminderList, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
1424
1425                 __reminderListUpdated = true;
1426         }
1427
1428         return __reminderList;
1429 }
1430
1431 result
1432 _CalEventImpl::ConvertRecurrenceToEventHandle(const Recurrence& recurrence, calendar_record_h eventHandle) const
1433 {
1434         result r = E_SUCCESS;
1435
1436         int errorCode = CALENDAR_ERROR_NONE;
1437         int weekStart = CALENDAR_SUNDAY;
1438         std::unique_ptr<char[]> pByDay;
1439         std::unique_ptr<char[]> pByMonth;
1440         std::unique_ptr<char[]> pByMonthDay;
1441
1442         int dayOfWeek = 0;
1443         String dayOfWeekString;
1444         String exDateString;
1445
1446         switch (recurrence.GetWeekStart())
1447         {
1448         case CAL_SUNDAY:
1449                 weekStart = CALENDAR_SUNDAY;
1450                 break;
1451         case CAL_MONDAY:
1452                 weekStart = CALENDAR_MONDAY;
1453                 break;
1454         default:
1455                 SysLogException(NID_SCL, E_INVALID_ARG, "Invalid argument is passed. week start = %d", recurrence.GetWeekStart());
1456                 return E_INVALID_ARG;
1457         }
1458         errorCode = calendar_record_set_int(eventHandle, _calendar_event.wkst, weekStart);
1459         SysTryReturnResult(NID_SCL, errorCode == CALENDAR_ERROR_NONE, E_INVALID_ARG, "Invalid argument is passed. week start = %d", weekStart);
1460
1461         if (recurrence.GetUntil() != null)
1462         {
1463                 if (*recurrence.GetUntil() == DateTime::GetMaxValue())
1464                 {
1465                         calendar_record_set_int(eventHandle, _calendar_event.range_type, CALENDAR_RANGE_NONE);
1466                 }
1467                 else
1468                 {
1469                         calendar_time_s startCalendarTime;
1470                         calendar_time_s untilCalendarTime;
1471
1472                         calendar_record_get_caltime(eventHandle, _calendar_event.start_time, &startCalendarTime);
1473                         if (startCalendarTime.type == CALENDAR_TIME_LOCALTIME)
1474                         {
1475                                 untilCalendarTime.type = CALENDAR_TIME_LOCALTIME;
1476                                 untilCalendarTime.time.date.year = recurrence.GetUntil()->GetYear();
1477                                 untilCalendarTime.time.date.month = recurrence.GetUntil()->GetMonth();
1478                                 untilCalendarTime.time.date.mday = recurrence.GetUntil()->GetDay();
1479                         }
1480                         else
1481                         {
1482                                 untilCalendarTime.type = CALENDAR_TIME_UTIME;
1483                                 untilCalendarTime.time.utime = _CalendarbookUtil::ConvertDateTimeToEpochTime(*recurrence.GetUntil());
1484                         }
1485
1486                         calendar_record_set_int(eventHandle, _calendar_event.range_type, CALENDAR_RANGE_UNTIL);
1487                         calendar_record_set_caltime(eventHandle, _calendar_event.until_time, untilCalendarTime);
1488                 }
1489         }
1490         else
1491         {
1492                 calendar_record_set_int(eventHandle, _calendar_event.range_type, CALENDAR_RANGE_COUNT);
1493                 calendar_record_set_int(eventHandle, _calendar_event.count, recurrence.GetCounts());
1494         }
1495
1496         calendar_record_set_int(eventHandle, _calendar_event.interval, recurrence.GetInterval());
1497
1498         switch (recurrence.GetFrequency())
1499         {
1500         case FREQ_DAILY:
1501                 calendar_record_set_int(eventHandle, _calendar_event.freq, CALENDAR_RECURRENCE_DAILY);
1502                 break;
1503         case FREQ_WEEKLY:
1504                 calendar_record_set_int(eventHandle, _calendar_event.freq, CALENDAR_RECURRENCE_WEEKLY);
1505
1506                 dayOfWeek = recurrence.GetDayOfWeek();
1507                 r = ConvertDayOfWeekToRRuleByDayString(dayOfWeek, 0, dayOfWeekString);
1508                 SysTryReturnResult(NID_SCL, r == E_SUCCESS, E_INVALID_ARG, "Invalid argument is passed. day of week = %d", dayOfWeek);
1509
1510                 pByDay.reset(_StringConverter::CopyToCharArrayN(dayOfWeekString));
1511
1512                 break;
1513         case FREQ_MONTHLY:
1514                 calendar_record_set_int(eventHandle, _calendar_event.freq, CALENDAR_RECURRENCE_MONTHLY);
1515
1516                 if (recurrence.GetDayOfMonth() != 0)
1517                 {
1518                         pByMonthDay.reset(_StringConverter::CopyToCharArrayN(Integer::ToString(recurrence.GetDayOfMonth())));
1519                 }
1520                 else
1521                 {
1522                         dayOfWeek = recurrence.GetDayOfWeek();
1523                         r = ConvertDayOfWeekToRRuleByDayString(dayOfWeek, recurrence.GetWeekOfMonth(), dayOfWeekString);
1524                         SysTryReturnResult(NID_SCL, r == E_SUCCESS, E_INVALID_ARG, "Invalid argument is passed. day of week = %d", dayOfWeek);
1525
1526                         pByDay.reset(_StringConverter::CopyToCharArrayN(dayOfWeekString));
1527                 }
1528
1529                 break;
1530         case FREQ_YEARLY:
1531                 calendar_record_set_int(eventHandle, _calendar_event.freq, CALENDAR_RECURRENCE_YEARLY);
1532
1533                 pByMonth.reset(_StringConverter::CopyToCharArrayN(Integer::ToString(recurrence.GetMonthOfYear())));
1534
1535                 if (recurrence.GetDayOfMonth() != 0)
1536                 {
1537                         pByMonthDay.reset(_StringConverter::CopyToCharArrayN(Integer::ToString(recurrence.GetDayOfMonth())));
1538                 }
1539                 else
1540                 {
1541                         dayOfWeek = recurrence.GetDayOfWeek();
1542                         r = ConvertDayOfWeekToRRuleByDayString(dayOfWeek, recurrence.GetWeekOfMonth(), dayOfWeekString);
1543                         SysTryReturnResult(NID_SCL, r == E_SUCCESS, E_INVALID_ARG, "Invalid argument is passed. day of week = %d", dayOfWeek);
1544
1545                         pByDay.reset(_StringConverter::CopyToCharArrayN(dayOfWeekString));
1546                 }
1547
1548                 break;
1549         default:
1550                 SysLogException(NID_SCL, E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument is used. frequency = %d", recurrence.GetFrequency());
1551                 return E_INVALID_ARG;
1552         }
1553
1554         errorCode = calendar_record_set_str(eventHandle, _calendar_event.byday, pByDay.get());
1555         SysTryReturnResult(NID_SCL, errorCode == CALENDAR_ERROR_NONE, E_OUT_OF_MEMORY, "Memory allocation failed.");
1556         errorCode = calendar_record_set_str(eventHandle, _calendar_event.bymonth, pByMonth.get());
1557         SysTryReturnResult(NID_SCL, errorCode == CALENDAR_ERROR_NONE, E_OUT_OF_MEMORY, "Memory allocation failed.");
1558         errorCode = calendar_record_set_str(eventHandle, _calendar_event.bymonthday, pByMonthDay.get());
1559         SysTryReturnResult(NID_SCL, errorCode == CALENDAR_ERROR_NONE, E_OUT_OF_MEMORY, "Memory allocation failed.");
1560
1561         return E_SUCCESS;
1562 }
1563
1564 result
1565 _CalEventImpl::ConvertDayOfWeekToRRuleByDayString(int dayOfWeek, int weekOfMonth, String& byDayString) const
1566 {
1567         int tmpDayOfWeek = CAL_SUNDAY;
1568
1569         byDayString.Clear();
1570         for (int i = 0; i < _NUMBER_OF_DAYS_OF_WEEK; i++)
1571         {
1572                 if (dayOfWeek & tmpDayOfWeek)
1573                 {
1574                         if (weekOfMonth != 0)
1575                         {
1576                                 byDayString.Append(weekOfMonth);
1577                         }
1578
1579                         switch (tmpDayOfWeek)
1580                         {
1581                         case CAL_SUNDAY:
1582                                 byDayString.Append(_RECURRENCE_KEYWORD_SUNDAY);
1583                                 break;
1584                         case CAL_MONDAY:
1585                                 byDayString.Append(_RECURRENCE_KEYWORD_MONDAY);
1586                                 break;
1587                         case CAL_TUESDAY:
1588                                 byDayString.Append(_RECURRENCE_KEYWORD_TUESDAY);
1589                                 break;
1590                         case CAL_WEDNESDAY:
1591                                 byDayString.Append(_RECURRENCE_KEYWORD_WEDNESDAY);
1592                                 break;
1593                         case CAL_THURSDAY:
1594                                 byDayString.Append(_RECURRENCE_KEYWORD_THURSDAY);
1595                                 break;
1596                         case CAL_FRIDAY:
1597                                 byDayString.Append(_RECURRENCE_KEYWORD_FRIDAY);
1598                                 break;
1599                         case CAL_SATURDAY:
1600                                 byDayString.Append(_RECURRENCE_KEYWORD_SATURDAY);
1601                                 break;
1602                         }
1603                         byDayString.Append(_RECURRENCE_DELIMITER);
1604                 }
1605
1606                 tmpDayOfWeek <<= 1;
1607         }
1608
1609         byDayString.Remove(byDayString.GetLength() - 1, _RECURRENCE_DELIMITER_LENGTH);
1610
1611         return E_SUCCESS;
1612 }
1613
1614 RecordId
1615 _CalEventImpl::GetCalendarId(void) const
1616 {
1617         int srcCalendarbookId = 0;
1618
1619         calendar_record_get_int(__eventRecord.GetHandle(), _calendar_event.calendar_book_id, &srcCalendarbookId);
1620
1621         return srcCalendarbookId;
1622 }
1623
1624 RecordId
1625 _CalEventImpl::GetBaseEventId(void) const
1626 {
1627         int srcBaseEventId = INVALID_RECORD_ID;
1628
1629         calendar_record_get_int(__eventRecord.GetHandle(), _calendar_event.original_event_id, &srcBaseEventId);
1630
1631         return srcBaseEventId;
1632 }
1633
1634 void
1635 _CalEventImpl::SetOriginalCalEventId(RecordId originalEventId)
1636 {
1637         __originalEventId = originalEventId;
1638         __isInstance = true;
1639 }
1640
1641 int
1642 _CalEventImpl::GetAttendeeIndex(const char* pAttendeeEmail)
1643 {
1644         int index = _INVALID_ATTENDEE_INDEX;
1645         unsigned int attendeeCount = 0;
1646
1647         calendar_record_get_child_record_count(__eventRecord.GetHandle(), _calendar_event.calendar_attendee, &attendeeCount);
1648
1649         calendar_record_h tmpAttendeeHandle = null;
1650         char* pTmpAttendeeEmail = null;
1651         for (unsigned int i = 0; i < attendeeCount; i++)
1652         {
1653                 calendar_record_get_child_record_at_p(__eventRecord.GetHandle(), _calendar_event.calendar_attendee, i, &tmpAttendeeHandle);
1654                 calendar_record_get_str_p(tmpAttendeeHandle, _calendar_attendee.email, &pTmpAttendeeEmail);
1655
1656                 if (strcmp(pAttendeeEmail, pTmpAttendeeEmail) == 0)
1657                 {
1658                         index = i;
1659                         break;
1660                 }
1661         }
1662
1663         return index;
1664 }
1665
1666 result
1667 _CalEventImpl::VerifyRecurrence(const Recurrence& recurrence)
1668 {
1669         const DateTime* pUntil = recurrence.GetUntil();
1670         RecurFrequency frequency = recurrence.GetFrequency();
1671         int durationLimit = 0;
1672         int interval = recurrence.GetInterval();
1673
1674         DateTime startTime = GetStartTime();
1675         DateTime endTime = GetEndTime();
1676         EventCategory category = GetCategory();
1677
1678         if (pUntil != null)
1679         {
1680                 SysTryReturnResult(NID_SCL, startTime <= *pUntil, E_INVALID_CONDITION, "The until date of recurrence is earlier than start date.");
1681         }
1682
1683         if (_AppInfo::GetApiVersion() == _API_VERSION_2_0 && _AppInfo::IsOspCompat())
1684         {
1685                 if (category == EVENT_CATEGORY_ANNIVERSARY)
1686                 {
1687                         SysTryReturnResult(NID_SCL, frequency == FREQ_YEARLY, E_TYPE_MISMATCH
1688                                         , "The recurrence pattern is not a yearly pattern in case of the event being an Anniversary.");
1689                 }
1690         }
1691
1692         if (frequency == FREQ_DAILY)
1693         {
1694                 durationLimit = _TERM_LIMIT_DAILY * interval;
1695         }
1696         else if (frequency == FREQ_WEEKLY)
1697         {
1698                 SysTryReturnResult(NID_SCL, recurrence.GetDayOfWeek() != 0, E_INVALID_ARG, "Invalid argument is used. The day of week is not set.");
1699                 durationLimit = _TERM_LIMIT_WEEKLY * interval;
1700         }
1701         else if (frequency == FREQ_MONTHLY)
1702         {
1703                 SysTryReturnResult(NID_SCL, recurrence.GetDayOfMonth() != 0 || (recurrence.GetDayOfWeek() != 0 && recurrence.GetWeekOfMonth() != 0)
1704                                 , E_INVALID_ARG, "Invalid argument is used. The day of month or day of week/week of month is not set.");
1705                 durationLimit = _TERM_LIMIT_MONTHLY * interval;
1706         }
1707         else if (frequency == FREQ_YEARLY)
1708         {
1709                 int dayOfMonth = recurrence.GetDayOfMonth();
1710                 int monthOfYear = recurrence.GetMonthOfYear();
1711                 SysTryReturnResult(NID_SCL, monthOfYear != 0, E_INVALID_ARG, "Invalid argument is used. The month of year is not set.");
1712                 SysTryReturnResult(NID_SCL, dayOfMonth != 0 || (recurrence.GetDayOfWeek() != 0 && recurrence.GetWeekOfMonth() != 0)
1713                                 , E_INVALID_ARG, "Invalid argument is used. The day of month or day of week/week of month is not set.");
1714
1715                 SysTryReturnResult(NID_SCL, monthOfYear != 2 || dayOfMonth < 30
1716                                 , E_INVALID_ARG, "Invalid argument is used. If the frequency is yearly, the max days of the February is less than 30.");
1717                 if (dayOfMonth > 30)
1718                 {
1719                         SysTryReturnResult(NID_SCL, monthOfYear != 4 && monthOfYear != 6 && monthOfYear != 9 && monthOfYear != 11
1720                                         , E_INVALID_ARG, "Invalid argument is used. If the frequency is yearly, the max days of the April, June, September and November is less than 31.");
1721                 }
1722
1723                 durationLimit = _TERM_LIMIT_YEARLY * interval;
1724         }
1725
1726         TimeSpan duration = endTime.GetTime() - startTime.GetTime();
1727         SysTryReturnResult(NID_SCL, duration.GetDays() <= durationLimit, E_INVALID_CONDITION
1728                         , "The duration of the event is greater than (interval x frequency) days. duration days = %d", duration.GetDays());
1729
1730         return E_SUCCESS;
1731 }
1732
1733 result
1734 _CalEventImpl::ResetStartAndEndTimeByRecurrence(const Recurrence& recurrence)
1735 {
1736         result r = E_SUCCESS;
1737         DateTime startTime;
1738         DateTime endTime;
1739
1740         bool isAllDay = IsAllDayEvent();
1741         Locales::TimeZone timeZone;
1742
1743         if (!isAllDay)
1744         {
1745                 timeZone = GetTimeZone();
1746                 startTime = timeZone.UtcTimeToWallTime(GetStartTime());
1747                 endTime = timeZone.UtcTimeToWallTime(GetEndTime());
1748         }
1749         else
1750         {
1751                 startTime = GetStartTime();
1752                 endTime = GetEndTime();
1753         }
1754
1755         DateTime calculatedStartTime(startTime);
1756         DateTime calculatedEndTime(endTime);
1757         RecurFrequency frequency = recurrence.GetFrequency();
1758         int interval = recurrence.GetInterval();
1759         int dayOfMonth = recurrence.GetDayOfMonth();
1760         int dayOfWeek = recurrence.GetDayOfWeek();
1761         int weekOfMonth = recurrence.GetWeekOfMonth();
1762         int monthOfYear = recurrence.GetMonthOfYear();
1763         CalDayOfWeek weekStart = recurrence.GetWeekStart();
1764         CalDayOfWeek weekEnd = CAL_SATURDAY;
1765         DateTime until;
1766         TimeSpan duration = endTime.GetTime() - startTime.GetTime();
1767
1768         if (weekStart == CAL_MONDAY)
1769         {
1770                 weekEnd = CAL_SUNDAY;
1771         }
1772
1773         if (recurrence.GetUntil() != null)
1774         {
1775                 until = *(recurrence.GetUntil());
1776                 if (!isAllDay)
1777                 {
1778                         until = timeZone.UtcTimeToWallTime(until);
1779                 }
1780         }
1781         else
1782         {
1783                 until = _CalendarbookImpl::GetMaxDateTime();
1784         }
1785
1786         CalDayOfWeek dayOfStartTime = GetDayOfWeek(startTime, timeZone);
1787
1788         if (frequency == FREQ_WEEKLY)
1789         {
1790                 int count = 0;
1791
1792                 for (int i = 0; i < _NUMBER_OF_DAYS_OF_WEEK; i++)
1793                 {
1794                         if ((dayOfStartTime & dayOfWeek) != 0)
1795                         {
1796                                 break;
1797                         }
1798
1799                         if ((dayOfStartTime & weekEnd) != 0)
1800                         {
1801                                 count += (interval - 1) * _NUMBER_OF_DAYS_OF_WEEK;
1802                         }
1803
1804                         dayOfStartTime = GetNextDayOfWeek(dayOfStartTime);
1805                         count++;
1806                 }
1807
1808                 r = calculatedStartTime.AddDays(count);
1809                 SysTryReturnResult(NID_SCL, !IsFailed(r), r, "[%s][Propagating]", GetErrorMessage(r));
1810                 r = calculatedEndTime.AddDays(count);
1811                 SysTryReturnResult(NID_SCL, !IsFailed(r), r, "[%s][Propagating]", GetErrorMessage(r));
1812
1813         }
1814         else if (frequency == FREQ_MONTHLY)
1815         {
1816                 if (dayOfMonth != 0)
1817                 {
1818                         bool isDone = false;
1819                         while (calculatedStartTime <= until)
1820                         {
1821                                 if (calculatedStartTime.SetValue(calculatedStartTime.GetYear(), calculatedStartTime.GetMonth(), dayOfMonth, calculatedStartTime.GetHour(), calculatedStartTime.GetMinute(), calculatedStartTime.GetSecond()) == E_SUCCESS)
1822                                 {
1823                                         if (calculatedStartTime >= startTime)
1824                                         {
1825                                                 isDone = true;
1826                                                 break;
1827                                         }
1828                                 }
1829                                 calculatedStartTime.AddMonths(interval);
1830                         }
1831                         SysTryReturnResult(NID_SCL, isDone, E_INVALID_ARG, "Invalid argument is used. There is no instance of the recurrence.");
1832                         calculatedEndTime = calculatedStartTime;
1833                         calculatedEndTime.Add(duration);
1834                 }
1835                 else
1836                 {
1837                         bool isDone = false;
1838                         int dayCount = 0;
1839                         CalDayOfWeek tmpDayOfWeek = GetFirstDay(weekStart, dayOfWeek, dayCount);
1840                         while (calculatedStartTime <= until)
1841                         {
1842                                 for (int i = 0; i < dayCount; i++)
1843                                 {
1844                                         calculatedStartTime = GetDate(calculatedStartTime.GetYear(), calculatedStartTime.GetMonth(), weekOfMonth, tmpDayOfWeek, calculatedStartTime, timeZone);
1845                                         if (calculatedStartTime >= startTime)
1846                                         {
1847                                                 isDone = true;
1848                                                 break;
1849                                         }
1850                                         tmpDayOfWeek = GetNextDay(dayOfWeek, tmpDayOfWeek);
1851                                 }
1852                                 if (isDone)
1853                                 {
1854                                         break;
1855                                 }
1856                                 calculatedStartTime.AddMonths(interval);
1857                         }
1858
1859                         SysTryReturnResult(NID_SCL, isDone, E_INVALID_ARG, "Invalid argument is used. There is no instance of the recurrence.");
1860                         calculatedEndTime = calculatedStartTime;
1861                         calculatedEndTime.Add(duration);
1862                 }
1863         }
1864         else if (frequency == FREQ_YEARLY)
1865         {
1866                 if (dayOfMonth != 0)
1867                 {
1868                         bool isDone = false;
1869                         while (calculatedStartTime <= until)
1870                         {
1871                                 if (calculatedStartTime.SetValue(calculatedStartTime.GetYear(), monthOfYear, dayOfMonth, calculatedStartTime.GetHour(), calculatedStartTime.GetMinute(), calculatedStartTime.GetSecond()) == E_SUCCESS)
1872                                 {
1873                                         if (calculatedStartTime >= startTime)
1874                                         {
1875                                                 isDone = true;
1876                                                 break;
1877                                         }
1878                                 }
1879                                 calculatedStartTime.AddYears(interval);
1880                         }
1881                         SysTryReturnResult(NID_SCL, isDone, E_INVALID_ARG, "Invalid argument is used. There is no instance of the recurrence.");
1882                         calculatedEndTime = calculatedStartTime;
1883                         calculatedEndTime.Add(duration);
1884                 }
1885                 else
1886                 {
1887                         bool isDone = false;
1888                         int dayCount = 0;
1889                         CalDayOfWeek tmpDayOfWeek = GetFirstDay(weekStart, dayOfWeek, dayCount);
1890                         while (calculatedStartTime <= until)
1891                         {
1892                                 for (int i = 0; i < dayCount; i++)
1893                                 {
1894                                         calculatedStartTime = GetDate(calculatedStartTime.GetYear(), monthOfYear, weekOfMonth, tmpDayOfWeek, calculatedStartTime, timeZone);
1895                                         if (calculatedStartTime >= startTime)
1896                                         {
1897                                                 isDone = true;
1898                                                 break;
1899                                         }
1900                                         tmpDayOfWeek = GetNextDay(dayOfWeek, tmpDayOfWeek);
1901                                 }
1902                                 if (isDone)
1903                                 {
1904                                         break;
1905                                 }
1906                                 calculatedStartTime.AddYears(interval);
1907                         }
1908
1909                         SysTryReturnResult(NID_SCL, isDone, E_INVALID_ARG, "Invalid argument is used. There is no instance of the recurrence.");
1910                         calculatedEndTime = calculatedStartTime;
1911                         calculatedEndTime.Add(duration);
1912                 }
1913         }
1914
1915         if (!isAllDay)
1916         {
1917                 calculatedStartTime = timeZone.WallTimeToUtcTime(calculatedStartTime);
1918                 calculatedEndTime = timeZone.WallTimeToUtcTime(calculatedEndTime);
1919         }
1920
1921         SysTryReturnResult(NID_SCL, calculatedStartTime <= until, E_INVALID_ARG, "Invalid argument is used. There is no instance of the recurrence.");
1922         SysTryReturnResult(NID_SCL, calculatedEndTime <= _CalendarbookImpl::GetMaxDateTime(), E_INVALID_ARG, "Invalid argument is used. There is no instance of the recurrence.");
1923
1924         SysLog(NID_SCL, "Reset start time : %S", calculatedStartTime.ToString().GetPointer());
1925         SetStartAndEndTimeCommon(calculatedStartTime, calculatedEndTime);
1926
1927         return E_SUCCESS;
1928 }
1929
1930 int
1931 _CalEventImpl::ConvertRRuleByDayStringToDayOfWeek(const String& byDay) const
1932 {
1933         result r = E_SUCCESS;
1934         int dayOfWeek = 0;
1935         ClearLastResult();
1936
1937         SysTryReturn(NID_SCL, !byDay.IsEmpty(), 0, E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument is used. The byDay is empty.");
1938
1939         String delim(_RECURRENCE_DELIMITER);
1940         String token;
1941
1942         StringTokenizer strTok(byDay, delim);
1943         while (strTok.HasMoreTokens())
1944         {
1945                 r = strTok.GetNextToken(token);
1946                 SysTryReturn(NID_SCL, r == E_SUCCESS, 0, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
1947
1948                 if (token == String(_RECURRENCE_KEYWORD_SUNDAY))
1949                 {
1950                         dayOfWeek |= CAL_SUNDAY;
1951                 }
1952                 else    if (token == String(_RECURRENCE_KEYWORD_MONDAY))
1953                 {
1954                         dayOfWeek |= CAL_MONDAY;
1955                 }
1956                 else    if (token == String(_RECURRENCE_KEYWORD_TUESDAY))
1957                 {
1958                         dayOfWeek |= CAL_TUESDAY;
1959                 }
1960                 else    if (token == String(_RECURRENCE_KEYWORD_WEDNESDAY))
1961                 {
1962                         dayOfWeek |= CAL_WEDNESDAY;
1963                 }
1964                 else    if (token == String(_RECURRENCE_KEYWORD_THURSDAY))
1965                 {
1966                         dayOfWeek |= CAL_THURSDAY;
1967                 }
1968                 else    if (token == String(_RECURRENCE_KEYWORD_FRIDAY))
1969                 {
1970                         dayOfWeek |= CAL_FRIDAY;
1971                 }
1972                 else    if (token == String(_RECURRENCE_KEYWORD_SATURDAY))
1973                 {
1974                         dayOfWeek |= CAL_SATURDAY;
1975                 }
1976                 else
1977                 {
1978                         SysLogException(NID_SCL, E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument is used. byday = %S", byDay.GetPointer());
1979                         return 0;
1980                 }
1981         }
1982
1983         return dayOfWeek;
1984 }
1985
1986 result
1987 _CalEventImpl::ConvertRRuleByDayStringToDayOfWeekAndWeekOfMonth(const String& byDay, int& weekOfMonth, int& dayOfWeek) const
1988 {
1989         result r = E_SUCCESS;
1990         String delim(_RECURRENCE_DELIMITER);
1991         String token;
1992         wchar_t tmpChar = 0;
1993         int tmpWeekOfMonth = 0;
1994         int weekStringStartIndex = 0;
1995         String tmpString;
1996
1997         weekOfMonth = 0;
1998         dayOfWeek = 0;
1999
2000         SysTryReturnResult(NID_SCL, !byDay.IsEmpty(), E_INVALID_ARG, "Invalid argument is passed. The byDay is empty.");
2001
2002         StringTokenizer strTok(byDay, delim);
2003
2004         while (strTok.HasMoreTokens())
2005         {
2006                 r = strTok.GetNextToken(token);
2007                 SysTryReturnResult(NID_SCL, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
2008
2009                 r = token.GetCharAt(_RECURRENCE_BY_DAY_FIRST_INDEX, tmpChar);
2010                 if (tmpChar == _RECURRENCE_BY_DAY_CHAR_MINUS)
2011                 {
2012                         SysTryReturnResult(NID_SCL, weekOfMonth == 0 || weekOfMonth == _MAX_WEEK_OF_MONTH
2013                                         , E_INVALID_ARG, "Invalid argument is passed. byday = %S", byDay.GetPointer());
2014
2015                         if (weekOfMonth == 0)
2016                         {
2017                                 tmpChar = 0;
2018                                 r = token.GetCharAt(_RECURRENCE_BY_DAY_SECOND_INDEX, tmpChar);
2019                                 SysTryReturnResult(NID_SCL, tmpChar == _RECURRENCE_BY_DAY_CHAR_ONE
2020                                                 , E_INVALID_ARG, "Invalid argument is passed. byday = %S", byDay.GetPointer());
2021
2022                                 weekOfMonth = _MAX_WEEK_OF_MONTH;
2023                         }
2024                         weekStringStartIndex = _RECURRENCE_BY_DAY_SECOND_INDEX + 1;
2025                 }
2026                 else if (tmpChar == _RECURRENCE_BY_DAY_CHAR_PLUS)
2027                 {
2028                         if (weekOfMonth == 0)
2029                         {
2030                                 tmpChar = 0;
2031                                 r = token.GetCharAt(_RECURRENCE_BY_DAY_SECOND_INDEX, tmpChar);
2032                                 tmpWeekOfMonth = Character::ToDigit(tmpChar, Character::RADIX_DECIMAL);
2033                                 SysTryReturnResult(NID_SCL, tmpWeekOfMonth > 0 && tmpWeekOfMonth <= _MAX_WEEK_OF_MONTH
2034                                                 , E_INVALID_ARG, "Invalid argument is passed. byday = %S", byDay.GetPointer());
2035
2036                                 weekOfMonth = tmpWeekOfMonth;
2037                         }
2038                         else
2039                         {
2040                                 SysTryReturnResult(NID_SCL, weekOfMonth == tmpWeekOfMonth
2041                                                 , E_INVALID_ARG, "Invalid argument is passed. byday = %S", byDay.GetPointer());
2042                         }
2043
2044                         weekStringStartIndex = _RECURRENCE_BY_DAY_SECOND_INDEX + 1;
2045                 }
2046                 else
2047                 {
2048                         if (weekOfMonth == 0)
2049                         {
2050                                 tmpWeekOfMonth = Character::ToDigit(tmpChar, Character::RADIX_DECIMAL);
2051                                 SysTryReturnResult(NID_SCL, tmpWeekOfMonth > 0 && tmpWeekOfMonth <= _MAX_WEEK_OF_MONTH
2052                                                 , E_INVALID_ARG, "Invalid argument is passed. byday = %S", byDay.GetPointer());
2053
2054                                 weekOfMonth = tmpWeekOfMonth;
2055                         }
2056                         else
2057                         {
2058                                 SysTryReturnResult(NID_SCL, weekOfMonth == tmpWeekOfMonth
2059                                                 , E_INVALID_ARG, "Invalid argument is passed. byday = %S", byDay.GetPointer());
2060                         }
2061
2062                         weekStringStartIndex = _RECURRENCE_BY_DAY_FIRST_INDEX + 1;
2063                 }
2064
2065                 token.SubString(weekStringStartIndex, tmpString);
2066
2067                 if (tmpString == String(_RECURRENCE_KEYWORD_SUNDAY))
2068                 {
2069                         dayOfWeek |= CAL_SUNDAY;
2070                 }
2071                 else    if (tmpString == String(_RECURRENCE_KEYWORD_MONDAY))
2072                 {
2073                         dayOfWeek |= CAL_MONDAY;
2074                 }
2075                 else    if (tmpString == String(_RECURRENCE_KEYWORD_TUESDAY))
2076                 {
2077                         dayOfWeek |= CAL_TUESDAY;
2078                 }
2079                 else    if (tmpString == String(_RECURRENCE_KEYWORD_WEDNESDAY))
2080                 {
2081                         dayOfWeek |= CAL_WEDNESDAY;
2082                 }
2083                 else    if (tmpString == String(_RECURRENCE_KEYWORD_THURSDAY))
2084                 {
2085                         dayOfWeek |= CAL_THURSDAY;
2086                 }
2087                 else    if (tmpString == String(_RECURRENCE_KEYWORD_FRIDAY))
2088                 {
2089                         dayOfWeek |= CAL_FRIDAY;
2090                 }
2091                 else    if (tmpString == String(_RECURRENCE_KEYWORD_SATURDAY))
2092                 {
2093                         dayOfWeek |= CAL_SATURDAY;
2094                 }
2095                 else
2096                 {
2097                         SysLogException(NID_SCL, E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument is used. byday = %S", byDay.GetPointer());
2098                 }
2099         }
2100
2101         return E_SUCCESS;
2102 }
2103
2104 result
2105 _CalEventImpl::ConvertRRuleExDateStringToRecurrence(const String& exdate, Recurrence& recurrence) const
2106 {
2107         result r = E_SUCCESS;
2108
2109         String delim(_RECURRENCE_DELIMITER);
2110         String token;
2111         DateTime tmpDateTime;
2112         TimeZone tmpTimeZone;
2113         TimeZone utcTimeZone = TimeZone::GetGmtTimeZone();
2114         bool isDate = false;
2115
2116         SysTryReturnResult(NID_SCL, !exdate.IsEmpty(), E_INVALID_ARG, "Invalid argument is passed. The exdate is empty.");
2117
2118         StringTokenizer strTok(exdate, delim);
2119         while (strTok.HasMoreTokens())
2120         {
2121                 r = strTok.GetNextToken(token);
2122                 SysTryReturnResult(NID_SCL, r == E_SUCCESS, E_OUT_OF_MEMORY, "Memory allocation failed.");
2123
2124                 r = _CalendarbookUtil::ConvertRRuleDateTimeStringToDateTime(token, tmpDateTime, tmpTimeZone, isDate);
2125                 SysTryReturnResult(NID_SCL, r == E_SUCCESS, E_INVALID_ARG, "Invalid argument is passed. exdate = %S", exdate.GetPointer());
2126
2127                 if (!isDate && tmpTimeZone != utcTimeZone)
2128                 {
2129                         tmpDateTime = tmpTimeZone.WallTimeToUtcTime(tmpDateTime);
2130                 }
2131
2132                 r = recurrence.AddExceptionDate(tmpDateTime);
2133                 SysTryReturnResult(NID_SCL, r == E_SUCCESS, E_INVALID_ARG, "Invalid argument is passed. exdate = %S", exdate.GetPointer());
2134         }
2135
2136         return E_SUCCESS;
2137 }
2138
2139 String
2140 _CalEventImpl::ConvertRecurrenceToRRuleExDateString(const Recurrence& recurrence, bool isDate) const
2141 {
2142         bool isNotFirst = false;
2143         String exdateString;
2144
2145         std::unique_ptr<IList, AllElementsDeleter> pExDateList(recurrence.GetExceptionDatesN());
2146
2147         IEnumerator* pEnum = pExDateList->GetEnumeratorN();
2148         while (pEnum->MoveNext() == E_SUCCESS)
2149         {
2150                 DateTime* pDateTime = static_cast<DateTime*>(pEnum->GetCurrent());
2151
2152                 if (isNotFirst)
2153                 {
2154                         exdateString.Append(_RECURRENCE_DELIMITER);
2155                 }
2156
2157                 exdateString.Append(_CalendarbookUtil::ConvertDateTimeToRRuleDateTimeString(*pDateTime, isDate));
2158
2159                 isNotFirst = true;
2160         }
2161         delete pEnum;
2162
2163         return exdateString;
2164 }
2165
2166 CalDayOfWeek
2167 _CalEventImpl::GetNextDayOfWeek(CalDayOfWeek currentDay)
2168 {
2169         int tmpDay = currentDay;
2170
2171         tmpDay <<= 1;
2172         if (tmpDay > CAL_SATURDAY)
2173         {
2174                 tmpDay = CAL_SUNDAY;
2175         }
2176
2177         return static_cast<CalDayOfWeek>(tmpDay);
2178 }
2179
2180 DateTime
2181 _CalEventImpl::GetDate(int year, int month, int weekOfMonth, CalDayOfWeek dayOfWeek, const DateTime& time, const Locales::TimeZone& timeZone)
2182 {
2183         Tizen::Locales::DayOfWeek dayOfWeekByGregorianCalendar = Tizen::Locales::DAY_OF_WEEK_UNDEFINED;
2184
2185         switch (dayOfWeek)
2186         {
2187         case CAL_SUNDAY:
2188                 dayOfWeekByGregorianCalendar = Tizen::Locales::SUNDAY;
2189                 break;
2190         case CAL_MONDAY:
2191                 dayOfWeekByGregorianCalendar = Tizen::Locales::MONDAY;
2192                 break;
2193         case CAL_TUESDAY:
2194                 dayOfWeekByGregorianCalendar = Tizen::Locales::TUESDAY;
2195                 break;
2196         case CAL_WEDNESDAY:
2197                 dayOfWeekByGregorianCalendar = Tizen::Locales::WEDNESDAY;
2198                 break;
2199         case CAL_THURSDAY:
2200                 dayOfWeekByGregorianCalendar = Tizen::Locales::THURSDAY;
2201                 break;
2202         case CAL_FRIDAY:
2203                 dayOfWeekByGregorianCalendar = Tizen::Locales::FRIDAY;
2204                 break;
2205         case CAL_SATURDAY:
2206                 dayOfWeekByGregorianCalendar = Tizen::Locales::SATURDAY;
2207                 break;
2208         default:
2209                 break;
2210         }
2211
2212         Tizen::Locales::Calendar* pGregorianCalendar = Tizen::Locales::Calendar::CreateInstanceN(timeZone, Tizen::Locales::CALENDAR_GREGORIAN);
2213
2214         pGregorianCalendar->SetTimeField(Tizen::Locales::TIME_FIELD_YEAR, year);
2215         pGregorianCalendar->SetTimeField(Tizen::Locales::TIME_FIELD_MONTH, month);
2216         pGregorianCalendar->SetTimeField(Tizen::Locales::TIME_FIELD_DAY_OF_MONTH, 1);
2217
2218         Tizen::Locales::DayOfWeek tmpDayOfWeek = static_cast<Tizen::Locales::DayOfWeek>(pGregorianCalendar->GetTimeField(TIME_FIELD_DAY_OF_WEEK));
2219         int maxDaysOfMonth = pGregorianCalendar->GetActualMaxTimeField(TIME_FIELD_DAY_OF_MONTH);
2220         int tmpDayOfMonth = ((_NUMBER_OF_DAYS_OF_WEEK + dayOfWeekByGregorianCalendar) - tmpDayOfWeek) % _NUMBER_OF_DAYS_OF_WEEK + 1;
2221
2222         tmpDayOfMonth += ((weekOfMonth - 1) * _NUMBER_OF_DAYS_OF_WEEK);
2223         if (tmpDayOfMonth > maxDaysOfMonth)
2224         {
2225                 tmpDayOfMonth -= _NUMBER_OF_DAYS_OF_WEEK;
2226         }
2227
2228         DateTime resultTime;
2229         resultTime.SetValue(year, month, tmpDayOfMonth, time.GetHour(), time.GetMinute(), time.GetSecond());
2230
2231         delete pGregorianCalendar;
2232
2233         return resultTime;
2234 }
2235
2236 CalDayOfWeek
2237 _CalEventImpl::GetDayOfWeek(const DateTime& date, const Locales::TimeZone& timeZone)
2238 {
2239         CalDayOfWeek dayOfWeek = CAL_SUNDAY;
2240
2241         std::unique_ptr<Tizen::Locales::Calendar> pGregorianCalendar(Tizen::Locales::Calendar::CreateInstanceN(timeZone, Tizen::Locales::CALENDAR_GREGORIAN));
2242
2243         pGregorianCalendar->SetTime(date);
2244         int dayOfWeekByGregorianCalendar = pGregorianCalendar->GetTimeField(Tizen::Locales::TIME_FIELD_DAY_OF_WEEK);
2245
2246         switch (dayOfWeekByGregorianCalendar)
2247         {
2248         case Tizen::Locales::SUNDAY:
2249                 dayOfWeek = CAL_SUNDAY;
2250                 break;
2251         case Tizen::Locales::MONDAY:
2252                 dayOfWeek = CAL_MONDAY;
2253                 break;
2254         case Tizen::Locales::TUESDAY:
2255                 dayOfWeek = CAL_TUESDAY;
2256                 break;
2257         case Tizen::Locales::WEDNESDAY:
2258                 dayOfWeek = CAL_WEDNESDAY;
2259                 break;
2260         case Tizen::Locales::THURSDAY:
2261                 dayOfWeek = CAL_THURSDAY;
2262                 break;
2263         case Tizen::Locales::FRIDAY:
2264                 dayOfWeek = CAL_FRIDAY;
2265                 break;
2266         case Tizen::Locales::SATURDAY:
2267                 dayOfWeek = CAL_SATURDAY;
2268                 break;
2269         default:
2270                 break;
2271         }
2272
2273         return dayOfWeek;
2274 }
2275
2276 CalDayOfWeek
2277 _CalEventImpl::GetFirstDay(CalDayOfWeek weekStart, int dayOfWeek, int& count)
2278 {
2279         int firstDay = 0;
2280         int tmpDay = weekStart;
2281
2282         count = 0;
2283         for (int i = 0; i < _NUMBER_OF_DAYS_OF_WEEK; i++)
2284         {
2285                 if ((tmpDay & dayOfWeek) != 0)
2286                 {
2287                         if (firstDay == 0)
2288                         {
2289                                 firstDay = tmpDay;
2290                         }
2291
2292                         count++;
2293                 }
2294
2295                 tmpDay = GetNextDayOfWeek(static_cast<CalDayOfWeek>(tmpDay));
2296         }
2297
2298         return static_cast<CalDayOfWeek>(firstDay);
2299 }
2300
2301 CalDayOfWeek
2302 _CalEventImpl::GetNextDay(int dayOfWeek, CalDayOfWeek currentDay)
2303 {
2304         int tmpDay = currentDay;
2305
2306         for (int i = 0; i < _NUMBER_OF_DAYS_OF_WEEK; i++)
2307         {
2308                 tmpDay = GetNextDayOfWeek(static_cast<CalDayOfWeek>(tmpDay));
2309
2310                 if ((tmpDay & dayOfWeek) != 0)
2311                 {
2312                         break;
2313                 }
2314         }
2315
2316         return static_cast<CalDayOfWeek>(tmpDay);
2317 }
2318
2319 void
2320 _CalEventImpl::SetRecordHandle(calendar_record_h eventHandle)
2321 {
2322         __eventRecord.ResetHandle(eventHandle);
2323 }
2324
2325 calendar_record_h
2326 _CalEventImpl::GetRecordHandle(void) const
2327 {
2328         return __eventRecord.GetHandle();
2329 }
2330
2331 CalEvent*
2332 _CalEventImpl::CreateDefaultInstanceN(void)
2333 {
2334         return new (std::nothrow) CalEvent();
2335 }
2336
2337 _CalEventImpl*
2338 _CalEventImpl::GetInstance(CalEvent& event)
2339 {
2340         return event.__pCalEventImpl;
2341 }
2342
2343 const _CalEventImpl*
2344 _CalEventImpl::GetInstance(const CalEvent& event)
2345 {
2346         return event.__pCalEventImpl;
2347 }
2348
2349 }} //Tizen::Social