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