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