agendainterface/agendautil/src/agendautil_p.cpp
author hgs
Tue, 05 Oct 2010 13:57:00 +0530
changeset 81 ce92091cbd61
parent 70 a5ed90760192
child 83 5aadd1120515
permissions -rw-r--r--
201039

/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description: Definition file for AgendaUtilPrivate class.
*
*/

// System includes
#include <hbextendedlocale.h>
#include <calsession.h>
#include <calinstance.h>
#include <CalenImporter>
#include <CalenInterimUtils2>
#include <calentry.h>
#include <calrrule.h>
#include <e32math.h>
#include <caluser.h>
#include <caldataexchange.h>
#include <caldataformat.h>
#include <f32file.h>
#include <s32file.h>
#include <asshddefs.h>

// User includes
#include <agendaentry.h>
#include "agendautil_p.h"
#include "agendaentry_p.h"
#include "CleanupResetAndDestroy.h"

// Constants
//recognition string for ical
_LIT8(KVersionICal,		"VERSION:2.0");
//recognition string for vcal
_LIT8(KVersionVCal,		"VERSION:1.0");
const TInt KReadDataAmount = 256;
const TInt KNoOfDaysInWeek = 7;
static const int startDateArray[2] = { 1900, 1};
static const int endDateArray[2] = { 2100, 1};

AgendaUtilPrivate::AgendaUtilPrivate(AgendaUtil* parent)
:q(parent)
{
	mEntryViewCreated = false;
	mInstanceViewCreated = false;
	mIsDeleting = false;
	mIsEntryViewBeingDeleted = false;
	mIsInstanceViewBeingDeleted = false;
	prepareSession();
}

bool AgendaUtilPrivate::prepareSession()
{
	if (iCalSession && mEntryViewCreated && mInstanceViewCreated)
		{
		// Everything is ready, nothing to be done
		return true;
		}

	// Create the cal session if not already there.
	if (!iCalSession)
		{
		TRAP(iError, iCalSession = CCalSession::NewL(););
		if (!iCalSession)
			{
			return false;
			}

		const TDesC& file = iCalSession->DefaultFileNameL();
		TRAPD(iError, iCalSession->OpenL(file));
		if (iError == KErrNotFound)
			{
			iCalSession->CreateCalFileL(file);
			iCalSession->OpenL(file);
			}
		else if (iError != KErrNone)
			{
			return false;
			}

		// Subscribe for notification on changes in the opened session (file).
		TCalTime startDate;
		TCalTime endDate;
		TDateTime startTime = TDateTime(
				startDateArray[0], static_cast<TMonth>(startDateArray[1]),
				0, 0, 0, 0, 0);
		TDateTime endTime = TDateTime(
				endDateArray[0], static_cast<TMonth>(endDateArray[1]),
				0, 0, 0, 0, 0);

		startDate.SetTimeUtcL(startTime);
		endDate.SetTimeUtcL(endTime);
		CalCommon::TCalTimeRange searchTimeRange(startDate, endDate);

		CCalChangeNotificationFilter* filter = 0;
		filter = CCalChangeNotificationFilter::NewL(
				MCalChangeCallBack2::EChangeEntryAll, true, searchTimeRange);

		iCalSession->StartChangeNotification(*this, *filter);

		// Cleanup.
		delete filter;
		}

	// First construct the CCalInstanceView if not already available.
	// The CCalEntryView is constructed in CompletedL. Instance view
	// is created before entry view since entry view is required only
	// when editing/saving any entry. So we will construct it later
	if (!iCalInstanceView) {
	    TRAP (iError, iCalInstanceView = CCalInstanceView::NewL(*iCalSession,
	                                                           *this);)
	}
	
	// All the requests have been made
	return true;
}

AgendaUtilPrivate::~AgendaUtilPrivate()
{
    if (iCalEntryView && !mIsEntryViewBeingDeleted) {
        mIsEntryViewBeingDeleted = true;
        delete iCalEntryView;
        iCalEntryView = NULL;
    }
    
    if (iCalInstanceView && !mIsInstanceViewBeingDeleted) {
        mIsInstanceViewBeingDeleted = true;
        delete iCalInstanceView;
        iCalInstanceView = NULL;
    }
	
	if (iCalSession) {
		iCalSession->StopChangeNotification();
	}
	delete iCalSession;
}

void AgendaUtilPrivate::Completed(TInt aError)
{
	iError = aError;

	if (mIsDeleting) {
		// If deletion was in progress, then it is completed now
		// emit the signal to the clients.
		mIsDeleting = false;
		emit q->entriesDeleted(iError);
	}

	if (KErrNone != iError) {
		// Something has gone wrong, return
		if (iCalEntryView && !mIsEntryViewBeingDeleted) {
            mIsEntryViewBeingDeleted = true;
            delete iCalEntryView;
            iCalEntryView = NULL;
            mIsEntryViewBeingDeleted = false;
		}
		if (iCalInstanceView && !mIsInstanceViewBeingDeleted) {
            mIsInstanceViewBeingDeleted = true;
            delete iCalInstanceView;
            iCalInstanceView = NULL;
            mIsInstanceViewBeingDeleted = false;
		}
		return;
	}

	if (iCalInstanceView && !mInstanceViewCreated) {
	    // Instance view is now created.
	    mInstanceViewCreated = true;
	    emit q->instanceViewCreationCompleted(iError);
	    // Start with the construction of entry view
		if (!iCalEntryView) {
		    TRAP (iError,
		          iCalEntryView = CCalEntryView::NewL(*iCalSession, *this);
		    );
		}
	} else if(iCalEntryView && !mEntryViewCreated) {
	    // Entry view is now constructed
		mEntryViewCreated = true;
		emit q->entryViewCreationCompleted(iError);
	}
}

void AgendaUtilPrivate::CalChangeNotification(
		RArray<TCalChangeEntry>& aChangeItems)
{
	QList<ulong> ids;
	for (int i = 0; i < aChangeItems.Count(); i++) {
		ids.append(aChangeItems[i].iEntryId);
	}

	emit q->entriesChanged(ids);
}

/*!
	To store the new entry or update the entry in the Calendar db.

	\param entry The entry to be added/updated.
	\param range The recurrence range of entry.
	\param instanceOriginalDateTime The start time of the original instance..
	\return ulong The local uid of the entry added/updated in the db.
*/
ulong AgendaUtilPrivate::store(
		AgendaEntry &entry, AgendaUtil::RecurrenceRange range,
		QDateTime &instanceOriginalDateTime)
{
	// Will be filled with the lUID of the new entry created.
	TCalLocalUid localUid = 0;

	// First check if the session to the calendar database is prepared or not.
	if (!mInstanceViewCreated) {
		// Something went wrong
		return localUid;
	}
	CCalEntry *calEntry = 0;
	
	TRAP(
			iError,
			// Get the global uid.
			CCalenInterimUtils2* calenInterimUtils2 = CCalenInterimUtils2::NewL();
			bool isChild = !(entry.recurrenceId().isNull());
			
			//Flag to decide whether entry is added or updated
			bool entryAdded = false;
			
			// if the entry id is zero means need to create a new entry
			if ((AgendaUtil::ThisAndAll == range) && (0 == entry.id())) {
		
				entryAdded = true;
				
				HBufC8* globalUid = calenInterimUtils2->GlobalUidL();
				CleanupStack::PushL(globalUid);
				calEntry
						= CCalEntry::NewL(
										  static_cast<CCalEntry::TType> (entry.type()),
										  globalUid,
										  static_cast<CCalEntry::TMethod> (entry.method()),
										  0);
		
				CleanupStack::Pop(globalUid);
			} else if (((AgendaUtil::ThisOnly == range) && isChild)
					|| ((AgendaUtil::ThisAndAll == range) && (entry.id() > 0))) {
				
				// Updating the entry/Exceptional entry
				calEntry = iCalEntryView->FetchL(entry.id());
				
				CleanupStack::PushL(calEntry);
				// Repeat rule 
				TCalRRule rrule;
				TBool isRepeating = calEntry->GetRRuleL( rrule );
		
				// If the repeat rule is cleared then Clear the Repeat rule from CCalEntry
				if ((AgendaUtil::ThisAndAll == range) 
						&& isRepeating && !(entry.isRepeating())) {
					calEntry->ClearRepeatingPropertiesL();
				}
				CleanupStack::Pop(calEntry);	
			} else {
				// Creating a exceptional entry
				if ((AgendaUtil::ThisOnly == range) && !isChild) {
					// Get the entry corresponding to the id.
					CCalEntry *parentEntry = iCalEntryView->FetchL(entry.id());
					CleanupStack::PushL(parentEntry);
					// We are creating an exception, hence get the global Uid
					HBufC8* guid = parentEntry->UidL().AllocLC();
					
					
					
					// create new (child) entry
					// Use original instance time for recurrenceID as this entry hasn't got one.
					TCalTime originalCalTime;
					TDateTime originalDateTime(instanceOriginalDateTime.date().year(),
								TMonth(instanceOriginalDateTime.date().month() - 1),
								instanceOriginalDateTime.date().day() -1,
								0,
								0,
								0,
								0);
					
					TTime originalDateTimeTTime(originalDateTime);
					// Use floating time for non-timed entries so that
					// the time will be same regardless of the timezone
					if(entry.isTimedEntry()) {
					    originalCalTime.SetTimeLocalL(originalDateTimeTTime);					    					    
					}else {
					    originalCalTime.SetTimeLocalFloatingL(originalDateTimeTTime);
					}
					// create the new child now
					calEntry = CCalEntry::NewL(parentEntry->EntryTypeL(), 
											   guid,
											   parentEntry->MethodL(),
											   parentEntry->SequenceNumberL(),
											   originalCalTime,
											   CalCommon::EThisOnly);
		
					// reset local UID and clear the repeat rule for exceptional entry
					calEntry->SetLocalUidL(TCalLocalUid(0));
					calEntry->ClearRepeatingPropertiesL();
					
					CleanupStack::Pop(guid);
					CleanupStack::PopAndDestroy(parentEntry);
					
					// clear repeat rule properties
					AgendaRepeatRule repeatrule;
					entry.setRepeatRule(repeatrule);
				}
		
			}
			
			// Converting agenda entry to CCalEntry to store it to database
			createCCalEntryFromAgendaEntry(entry, *calEntry);
			
			calenInterimUtils2->StoreL(*iCalEntryView, *calEntry, true);
			localUid = calEntry->LocalUidL();
			
			// Emit signal upon successful creation of entry.
			if (0 < localUid) {
				// if creating new entry then emit signal entryAdded else entryUpdated
				if (entryAdded) {
				emit q->entryAdded(localUid);
				} else {
					q->entryUpdated(localUid);
				}
			}
			
			delete calenInterimUtils2;
			delete calEntry;
	)
	return localUid;

}

/*!
	Clones the `entry' passed in the argument and saves it as type `type'.

	\param entry Entry which should be used for cloning.
	\param type The new type of the entry.
	\return ulong The local UID of the new entry.

	\sa deleteEntry()
 */
ulong AgendaUtilPrivate::cloneEntry(
		const AgendaEntry &entry, AgendaEntry::Type type)
{
	// First prepare the session with agenda server.
	if (!mInstanceViewCreated) {
		// Something went wrong.
		return 0;
	}

	if (entry.isNull()
			|| type == AgendaEntry::TypeUnknown) {
		return 0;
	}

	// Will be filled with the lUID of the new entry created.
	TCalLocalUid localUid = 0;
	int success = 0;
	CCalEntry *originalEntry = 0;
	HBufC8* globalUid = 0;

	// Get the stored entry first.
	TRAP(
			iError,

			originalEntry = iCalEntryView->FetchL(entry.id());
	)

	if (!originalEntry) {
		return 0;
	}

	// Now save the GUID of the saved entry.
	TRAP(
			iError,
			globalUid = originalEntry->UidL().AllocL();
	)

	delete originalEntry;

	// Now start cloning and create a new entry.
	if (AgendaEntry::TypeNote == type) {
		TRAP(
				iError,

				RPointerArray<CCalEntry> entryArray;
				CleanupClosePushL(entryArray);

				// Construct a CCalEntry object and start filling the details.
				CCalEntry* newEntry = 0;
				newEntry = CCalEntry::NewL(
						static_cast<CCalEntry::TType>(type),
						globalUid,
						static_cast<CCalEntry::TMethod>(entry.method()),
						0);

				// Add description.
				TPtrC description(reinterpret_cast<const TUint16*>(
						entry.description().utf16()));
				newEntry->SetDescriptionL(description);

				// Set the favourite property.
				newEntry->SetFavouriteL(entry.favourite());

				// Finally set the entry to the database using the entry view.
				entryArray.AppendL(newEntry);
				iCalEntryView->StoreL(entryArray, success);
				localUid = newEntry->LocalUidL();

				// Cleanup.
				CleanupStack::PopAndDestroy(&entryArray);
		)
	} else {
		TRAP(
				iError,

				RPointerArray<CCalEntry> entryArray;
				CleanupClosePushL(entryArray);

				// Construct a CCalEntry object and start filling the details.
				CCalEntry* newEntry = 0;
				newEntry = CCalEntry::NewL(
						static_cast<CCalEntry::TType>(type),
						globalUid,
						static_cast<CCalEntry::TMethod>(entry.method()),
						0);

				// Add the summary.
				if (!entry.summary().isNull()) {
					TPtrC summary(reinterpret_cast<const TUint16*>(
							entry.summary().utf16()));
					newEntry->SetSummaryL(summary);
				}

				// Set the entry Start/End Date and time.
				QDate date = entry.startTime().date();
				QTime time = entry.startTime().time();

				TDateTime startDateTime(
						date.year(), static_cast<TMonth>(date.month() - 1),
						date.day() - 1, time.hour(), time.minute(), 0, 0);
				TTime entryStartTime(startDateTime);
				TCalTime calStartTime;

				date = entry.endTime().date();
				time = entry.endTime().time();

				TDateTime endDateTime(
						date.year(), static_cast<TMonth>(date.month() - 1),
						date.day() - 1, time.hour(), time.minute(), 0, 0);
				TTime entryEndTime(endDateTime);
				TCalTime calEndTime;
				
				bool isNonFloating = false;
                // Use floating time for non-timed entries so that
                // the time will be same regardless of the timezone
				if(type == AgendaEntry::TypeAppoinment|| type == AgendaEntry::TypeReminder) {
				    calStartTime.SetTimeLocalL(entryStartTime); 
				    calEndTime.SetTimeLocalL(entryEndTime);
				    isNonFloating = true;
				}else {
				    calStartTime.SetTimeLocalFloatingL(entryStartTime);
				    calEndTime.SetTimeLocalFloatingL(entryEndTime); 
				    isNonFloating = false;
				}
				newEntry->SetStartAndEndTimeL(calStartTime, calEndTime);

				// Add attendees to the entry.
				addAttendeesToEntry(entry.d->m_attendees, *newEntry);

				// Add categories to the entry.
				addCategoriesToEntry(entry.d->m_categories, *newEntry);

				// Add description to the entry.
				TPtrC description(reinterpret_cast<const TUint16*>(
						entry.description().utf16()));
				newEntry->SetDescriptionL(description);

				// Set the favourite property.
				newEntry->SetFavouriteL(entry.favourite());

				// Add Alarm to the entry.
				AgendaAlarm alarm = entry.alarm();
				if (!alarm.isNull()) {
					setAlarmToEntry(alarm, *newEntry);
				}

				// Set the priority.
				int priority = entry.priority();
				if (entry.priority() != -1) {
					newEntry->SetPriorityL(priority);
				}

				// Set the location.
				if (!entry.location().isNull()) {
					TPtrC location(reinterpret_cast<const TUint16*>(
							entry.location().utf16()));
					newEntry->SetLocationL(location);
				}

				// Set the repeat type if applicable.
				if (AgendaRepeatRule::InvalidRule
						!= entry.repeatRule().type()) {
					AgendaRepeatRule agendaRepeatRule = entry.repeatRule();
					TCalRRule repeatRule = 
							createTCalRRuleFromAgendaRRule(agendaRepeatRule, isNonFloating);
					newEntry->SetRRuleL(repeatRule);
				}

				// Save the status of the entry.
				newEntry->SetStatusL((CCalEntry::TStatus) entry.status());
				newEntry->SetLastModifiedDateL();
				
				// Save the geo value if any
				AgendaGeoValue entryGeoValue = entry.geoValue();
				if (!entryGeoValue.isNull()) {
					CCalGeoValue* geoValue = CCalGeoValue::NewL();
					double latitude;
					double longitude;
					entryGeoValue.getLatLong(latitude, longitude);
					
					// set the values to symbian geo value
					geoValue->SetLatLongL(latitude, longitude);
					
					// set it to CCalentry
					newEntry->SetGeoValueL(*geoValue);
					delete geoValue;
				}
								
				// Finally set the entry to the database using the entry view.
				entryArray.AppendL(newEntry);
				iCalEntryView->StoreL(entryArray, success);
				localUid = newEntry->LocalUidL();

				// Cleanup.
				CleanupStack::PopAndDestroy(&entryArray);
		)
	}
	// Emit signal upon successful creation of entry.
	if (0 < localUid && 1 == success) {
		emit q->entryAdded(localUid);
	}
	return localUid;
}

/*!
	Deletes a given entry with `id'.

	\param id The id of the entry to be deleted.
	\return bool true if deletion successful, false otherwise.
 */
bool AgendaUtilPrivate::deleteEntry(ulong id)
{
	// First prepare the session with agenda server.
	if (!mInstanceViewCreated) {
		// Something went wrong.
		return false;
	}
	int success = 0;

	// Now delete the entry with agenda server.
	TRAP(
			iError,
			RArray<TCalLocalUid> localIds;
			CleanupClosePushL(localIds);

			localIds.AppendL(id);
			iCalEntryView->DeleteL(localIds, success);
			CleanupStack::PopAndDestroy(&localIds);
	)

	// Emit the signal to notify the deletion of entry.
	if (0 < success) {
		emit q->entryDeleted(id);
	}
	return (success != 0);
}

/*!
	Deletes a repeated entry given the recurrance range.

	\param entry
	\param range
	\return bool true if deletion successful, false otherwise.
 */
void AgendaUtilPrivate::deleteRepeatedEntry(
		AgendaEntry& entry,
		AgendaUtil::RecurrenceRange range)
{

	// First prepare the session with agenda server.
	if (!mInstanceViewCreated) {
		// Something went wrong.
		return;
	}

	TRAP(iError,

			if (range != AgendaUtil::ThisAndAll) {
				// Find the correct instance to be deleted from entry.
				CCalInstance* instance = findPossibleInstance(entry);
				if (instance) {
				    iCalInstanceView->DeleteL(instance,
				                              (CalCommon::TRecurrenceRange)range);
				}
			} else {
				// Unfortunately we can't pass the existing child instance
				// through to the InstanceView DeleteL function because even if
				// we pass in EThisAndAll, it only ever deletes the exception.
				// We'll have to fetch the parent then delete it via
				// the entry view.
				CCalEntry* calEntry = iCalEntryView->FetchL(entry.id());
				CleanupStack::PushL(calEntry);

				// Fetch the entries based on the global uid of the entry, as
				// the exceptional entries share the global uid with the parent
				// entry.
				RPointerArray<CCalEntry> entries;
				CleanupResetAndDestroyPushL(entries);
				iCalEntryView->FetchL(calEntry->UidL(), entries);
				if (entries.Count()) {
				    iCalEntryView->DeleteL(*entries[0]);
				}

				CleanupStack::PopAndDestroy(&entries);
				CleanupStack::PopAndDestroy();
			}
	)
	
	// Emit the signal to notify the deletion of entry.
	emit q->entryDeleted(entry.id());
}

/*!
	Fetches an AgendaEntry, given the id.

	\param id The (ulong) local uid the entry to be fetched.
	\return AgendaEntry The fetched entry.
 */
AgendaEntry AgendaUtilPrivate::fetchById(ulong id)
{
	AgendaEntry entry;

	// First check if the session with the calendar exists.
	if (!mInstanceViewCreated) {
		// Return empty AgendaEntry.
		return entry;
	}

	TRAP(
			iError,

			CCalEntry* calEntry = iCalEntryView->FetchL(id);

			// We fetch only if we have got a valid calendar entry.
			if (calEntry) {
				CleanupStack::PushL(calEntry);

				// We have a valid CCalEntry. We get the AgendaEntry
				// corresponding to that.
				entry = createAgendaEntryFromCalEntry(*calEntry);

				// Cleanup.
				CleanupStack::PopAndDestroy(calEntry);
			}
	)
	return entry;
}

/*!
	Returns a list of entry ids which match the given filter.

	\param filter The filter to be applied to get the entry ids.
	\return QList a list of entry ids.
 */
QList<ulong> AgendaUtilPrivate::entryIds(AgendaUtil::FilterFlags filter)
{
	QList<ulong> listOfIds;

	// First check if the session with agenda server exists.
	if (!mInstanceViewCreated) {
		// Return empty list.
		return listOfIds;
	}

	TRAP(
			iError,

			RPointerArray<CCalInstance> instanceList;
            CleanupResetAndDestroyPushL(instanceList);
			CalCommon::TCalViewFilter filters = filter;
			TCalTime startDateForInstanceSearch;
			TCalTime endDateForInstanceSearch;

			TDateTime startTime = TDateTime(
					startDateArray[0], static_cast<TMonth>(startDateArray[1]),
					0, 0, 0, 0, 0);

			TDateTime endTime = TDateTime(
					endDateArray[0], static_cast<TMonth>(endDateArray[1]),
					0, 0, 0, 0, 0);

			startDateForInstanceSearch.SetTimeLocalL(startTime);
			endDateForInstanceSearch.SetTimeLocalL(endTime);
			CalCommon::TCalTimeRange searchTimeRange(
					startDateForInstanceSearch, endDateForInstanceSearch);

			iCalInstanceView->FindInstanceL(
					instanceList, filters, searchTimeRange);

			TDateTime date;

			for (int iter = 0; iter < instanceList.Count(); iter++) {
				listOfIds.append(instanceList[iter]->Entry().LocalUidL());
			}

			// Cleanup.
			CleanupStack::PopAndDestroy(&instanceList);
	)

	return listOfIds;
}

/*!
	Retruns a list of entries matching a given filter.

	\param Filter to be applied to get the matching entries.
	\return QList a list of AgendaEntries matching the given filter.
 */
QList<AgendaEntry> AgendaUtilPrivate::fetchAllEntries(
		AgendaUtil::FilterFlags filter)
{
	QList<AgendaEntry> entryList;

	// First check if the session with agenda server exists.
	if (!mInstanceViewCreated) {
		// Return empty list.
		return entryList;
	}

	TRAP(
			iError,

			RPointerArray<CCalInstance> instanceList;
            CleanupResetAndDestroyPushL(instanceList);
			CalCommon::TCalViewFilter filters = filter;
			TCalTime startDateForInstanceSearch;
			TCalTime endDateForInstanceSearch;

			TDateTime startTime = TDateTime(
					startDateArray[0], static_cast<TMonth>(startDateArray[1]),
					0, 0, 0, 0, 0);

			TDateTime endTime = TDateTime(
					endDateArray[0], static_cast<TMonth>(endDateArray[1]),
					0, 0, 0, 0, 0);

			startDateForInstanceSearch.SetTimeLocalL(startTime);
			endDateForInstanceSearch.SetTimeLocalL(endTime);
			CalCommon::TCalTimeRange searchTimeRange(
					startDateForInstanceSearch,
					endDateForInstanceSearch);

			iCalInstanceView->FindInstanceL(
					instanceList, filters, searchTimeRange);

			TDateTime date;

			for (int iter = 0; iter < instanceList.Count(); iter++) {
				entryList.append(
						createAgendaEntryFromCalEntry(
								instanceList[iter]->Entry(),
								instanceList[iter]));
			}

			// Cleanup.
			CleanupStack::PopAndDestroy(&instanceList);
	)

	return entryList;
}

QList<AgendaEntry> AgendaUtilPrivate::fetchEntriesInRange(
		QDateTime rangeStart, QDateTime rangeEnd,
		AgendaUtil::FilterFlags filter)
{
    QList<AgendaEntry> entryList;
    if(!mInstanceViewCreated)
        {
            // return empty list
            return entryList;
        }

    TRAP(iError,

        RPointerArray<CCalInstance> instanceList;
        CleanupResetAndDestroyPushL(instanceList);
        CalCommon::TCalViewFilter filters = filter;
        TCalTime startDateForInstanceSearch;
        TCalTime endDateForInstanceSearch;

        TDateTime startTime(rangeStart.date().year(),
                TMonth(rangeStart.date().month() - 1),
                rangeStart.date().day() - 1,
                rangeStart.time().hour(),
                rangeStart.time().minute(),
                rangeStart.time().second(),
                rangeStart.time().msec());

        TDateTime endTime(rangeEnd.date().year(),
                TMonth(rangeEnd.date().month() - 1),
                rangeEnd.date().day() - 1,
                rangeEnd.time().hour(),
                rangeEnd.time().minute(),
                rangeEnd.time().second(),
                rangeEnd.time().msec());

        startDateForInstanceSearch.SetTimeLocalL(startTime);
        endDateForInstanceSearch.SetTimeLocalL(endTime);
        CalCommon::TCalTimeRange searchTimeRange(
                startDateForInstanceSearch,
                endDateForInstanceSearch);

        iCalInstanceView->FindInstanceL(instanceList, filters, searchTimeRange);

        for(TInt i = 0; i<instanceList.Count(); i++)
        {
            entryList.append(createAgendaEntryFromCalEntry(instanceList[i]->Entry(), instanceList[i]));
        }
        CleanupStack::PopAndDestroy(&instanceList);
    )

    return entryList;
}

void AgendaUtilPrivate::markDatesWithEvents(QDateTime rangeStart, 
	QDateTime rangeEnd,AgendaUtil::FilterFlags filter, QList<QDate>& dates)
{
	RPointerArray<CCalInstance> instanceList;
	
	if(!mInstanceViewCreated) {
	    // return empty list
	    return;
	}
	
	CleanupResetAndDestroyPushL(instanceList);
	CalCommon::TCalViewFilter filters = filter;
	TCalTime startDateForInstanceSearch;
	TCalTime endDateForInstanceSearch;

	TDateTime startTime(rangeStart.date().year(),
			TMonth(rangeStart.date().month() - 1),
			rangeStart.date().day() - 1,
			rangeStart.time().hour(),
			rangeStart.time().minute(),
			rangeStart.time().second(),
			rangeStart.time().msec());

	TDateTime endTime(rangeEnd.date().year(),
			TMonth(rangeEnd.date().month() - 1),
			rangeEnd.date().day() - 1,
			rangeEnd.time().hour(),
			rangeEnd.time().minute(),
			rangeEnd.time().second(),
			rangeEnd.time().msec());

	startDateForInstanceSearch.SetTimeLocalL(startTime);
	endDateForInstanceSearch.SetTimeLocalL(endTime);
	CalCommon::TCalTimeRange searchTimeRange(
			startDateForInstanceSearch,
			endDateForInstanceSearch);

	iCalInstanceView->FindInstanceL(instanceList, filters, searchTimeRange);

	// Parse thru the list and mark the dates which have events
	for (int i = 0; i < instanceList.Count(); i++) {
		CCalEntry::TType type = instanceList[i]->Entry().EntryTypeL();
		// Get the start time and end time of the events
		TCalTime startCalTime = instanceList[i]->StartTimeL();
		TCalTime endCalTime = instanceList[i]->EndTimeL();
		TDateTime startDateTime = startCalTime.TimeLocalL().DateTime();
		TDateTime endDateTime = endCalTime.TimeLocalL().DateTime();
		QDate startDate(startDateTime.Year(), startDateTime.Month()+1,
						startDateTime.Day() + 1);
        QDate endDate(endDateTime.Year(), endDateTime.Month()+1,
                        endDateTime.Day() + 1);
		if (type == CCalEntry::EEvent || type == CCalEntry::EAppt ||
				type == CCalEntry::EReminder) {
			if(endsAtStartOfDay(instanceList[i], endCalTime.TimeLocalL())) {
				TDateTime endDateTime = endCalTime.TimeLocalL().DateTime();
				// prevent problems with items ending tomorrow at 00:00
				endDateTime.SetMinute(endDateTime.Minute() - 1);
				TTime time(endDateTime);
				// If it is ending before the start of the grid 
				if (time <= startDateForInstanceSearch.TimeLocalL()) {
					continue;
				}
			}
        // Mark the required dates frm start date to end date
        int numOfDays = 0;
        //check if the start date of the entry is before the start day of the grid
        if(startDate < rangeStart.date()){
            if(endDate<=rangeEnd.date()){
                //if the end date of entry is lying in the grid ,
                //then mark the entry from start day of the grid to the end date of the entry
                numOfDays = rangeStart.date().daysTo(endDate);
            }
            else{
                //if end date of the entry is greater then the last date of grid, 
                //then mark all the date of the grid with the entry 
               numOfDays = rangeStart.daysTo(rangeEnd);
            }
            // Check if the event is all-day
            if (instanceList[i]->Entry().EntryTypeL() == CCalEntry::EEvent) {
                // no need to consider the date on which it ends
                // reduce days count by 1
                numOfDays--;
                }
            //start the entries from the first day of the grid
            for (int j = 0; j <= numOfDays; j++) {
                QDate date = rangeStart.date().addDays(j);
                if (date <= rangeEnd.date()) {
                    dates.append(date);
                } else {
                    break;
                }
            }
        }
        //if the start date of the entry is lying inside the grid
        else{
            if(endDate<=rangeEnd.date()){
                //if the end date of entry is lying in the grid ,
                //then mark the entry from start date of the entry to the end date of the entry
                numOfDays = startDate.daysTo(endDate);
            }
            else{
                //if end date of the entry is greater then the last date of grid, 
                //then mark all the date from start date of the entry to the end date of the grid 
                numOfDays = startDate.daysTo(rangeEnd.date()); 
            }
            // Check if the event is all-day
            if (instanceList[i]->Entry().EntryTypeL() == CCalEntry::EEvent) {
                // no need to consider the date on which it ends
                // reduce days count by 1
                numOfDays--;
                }
            for (int j = 0; j <= numOfDays; j++) {
                QDate date = startDate.addDays(j);
                if (date <= rangeEnd.date()) {
                    dates.append(date);
                } else {
                    break;
                }
            }   
        }
    } else if (type == CCalEntry::EAnniv) {
        if (startDate <= rangeEnd.date()) {
            dates.append(startDate);
        }
    } else if (type == CCalEntry::ETodo) {
            // if start time is less that today, then mark it for today
            if (startDate < QDate::currentDate()) {
                dates.append(QDate::currentDate());
            } else {
                dates.append(startDate);
            }
        }
    }
    CleanupStack::PopAndDestroy(&instanceList);
}

QList<AgendaEntry> AgendaUtilPrivate::createEntryIdListForDay( QDateTime day,
                            AgendaUtil::FilterFlags filter )
{
    QList<AgendaEntry> entryList;
    if(!mInstanceViewCreated) {
        // return empty list
        return entryList;
    }
    TCalTime dummy;
    CalCommon::TCalTimeRange dayRange( dummy, dummy );
    TRAP(iError,
        getDayRange(day, day, dayRange);
        RPointerArray<CCalInstance> instanceList;
        CleanupResetAndDestroyPushL(instanceList);
        CalCommon::TCalViewFilter filters = filter;
        // Check if the filter has todos also to be included
        if(filter & CalCommon::EIncludeIncompletedTodos)
            {
            // Show the incompleted todos till date only for the current date 
            if(QDate::currentDate() == day.date())
                {
                // Remove the todos from the filter and fetch it separately
                CalCommon::TCalViewFilter changedfilter = 
                                   filter ^ CalCommon::EIncludeIncompletedTodos;
                iCalInstanceView->FindInstanceL(
                                         instanceList, changedfilter, dayRange);
                // Get the range from minimum datetime till the today
                getDayRange(minTime(), day, dayRange);
                iCalInstanceView->FindInstanceL(
                        instanceList ,CalCommon::EIncludeIncompletedTodos | 
                        // only fetch the first instance for repeating to-dos!
                        CalCommon::EIncludeRptsNextInstanceOnly, 
                        dayRange);
                }
            else if(QDate::currentDate() < day.date())
                {
            	// Fetch all the instances including todos
            	// only if the day range is in future dates
                iCalInstanceView->FindInstanceL(
                                               instanceList, filters, dayRange);
                }
            else if(QDate::currentDate() > day.date())
				{
				// Remove todos from the filter
				CalCommon::TCalViewFilter changedfilter = 
								   filter ^ CalCommon::EIncludeIncompletedTodos;
            	// Fetch all the instances excluding todos
            	// only if the day range is in past dates
				iCalInstanceView->FindInstanceL(
										 instanceList, changedfilter, dayRange);
				}
            }
        else
            {
            iCalInstanceView->FindInstanceL(instanceList, filters, dayRange);
            }
        
        // In this list, check if any events are there that end at the start of the day
        // we should not show it again on next day
        TCalTime calTime;
        TDateTime dateTime(
                day.date().year(),
                static_cast<TMonth>(day.date().month() - 1),
                day.date().day() - 1, day.time().hour(),
                day.time().minute(), 0, 0);
        TTime time(dateTime);
        for (int i(0); i < instanceList.Count(); i++) {
            if ((endsAtStartOfDay(instanceList[i], time))) {
                // Previous day event has been found, we are not supposed to
                // show it on current day, hence remove it from the instance list
                CCalInstance *instance = instanceList[i];
                instanceList.Remove(i);
                delete instance;
                i--;
            }
        }
        
        // Sort the list
        sortInstanceList(instanceList);
        for(TInt i = 0; i<instanceList.Count(); i++)
            {
                entryList.append(createAgendaEntryFromCalEntry(
                                    instanceList[i]->Entry(), instanceList[i]));
            }
        CleanupStack::PopAndDestroy( &instanceList );
        )

    return entryList;
}

int AgendaUtilPrivate::importvCalendar(const QString& fileName, 
										AgendaEntry& entry)
{
	int success = -1 ;

	// First prepare the session with agenda server.
	if (!mInstanceViewCreated) {
		return success;
	}

	CCalenImporter* calImporter = CCalenImporter::NewL(*iCalSession);
	CleanupStack::PushL(calImporter);
	calImporter->SetImportMode(ECalenImportModeExtended);

	RFs fs;
	User::LeaveIfError(fs.Connect());
	CleanupClosePushL(fs);
	TPtrC path(reinterpret_cast<const TUint16*> (fileName.utf16()));
	RFileReadStream stream;
	User::LeaveIfError(stream.Open(fs, path, EFileRead));
	CleanupClosePushL(stream);

	TBuf8<KReadDataAmount> vcalData;
	stream.ReadL(vcalData, KReadDataAmount);

	//return the read stream back to the beginning for import
	stream.Source()->SeekL(MStreamBuf::ERead, EStreamBeginning, 0);

	TInt errImport(KErrNone);
	RPointerArray<CCalEntry> calEntryArray;
	CleanupClosePushL(calEntryArray);
	if (vcalData.FindF(KVersionVCal) == KErrNotFound) {
		//using the ICAl import API
		TRAP( errImport, calImporter->ImportICalendarL( stream, calEntryArray ) );
	} else if (vcalData.FindF(KVersionICal) == KErrNotFound) {
		//using the VCAL import API
		TRAP( errImport, calImporter->ImportVCalendarL( stream, calEntryArray ) );
	}
	success = errImport;
	if (errImport != KErrNone || calEntryArray.Count() == 0) {
		// the data was corrupt
		User::Leave(errImport);
	}

	//sets the local UID to 0 in imported entry
	calEntryArray[0]->SetLocalUidL(TCalLocalUid(0));
	AgendaEntry agendaEntry = createAgendaEntryFromCalEntry(*calEntryArray[0]);
	if (!agendaEntry.isNull()) {
		entry = agendaEntry;
	}

	CleanupStack::PopAndDestroy(4, calImporter);
	return success;
}

bool AgendaUtilPrivate::exportAsvCalendar(
		const QString& fileName, ulong calendarEntryId)
{
	// First prepare session with agenda server.
	if (!mInstanceViewCreated) {
		return false;
	}
	TRAP(
			iError,

			TPtrC path(reinterpret_cast<const TUint16*>(fileName.utf16()));
			RFs fs;
			User::LeaveIfError(fs.Connect());
			CleanupClosePushL(fs);
			fs.MkDirAll(path);
			RFileWriteStream rs;
			User::LeaveIfError(rs.Replace(fs, path, EFileWrite));

			CCalEntry* entry = iCalEntryView->FetchL(calendarEntryId);
			CleanupStack::PushL(entry);

			RPointerArray<CCalEntry> calEntryArray;
			CleanupClosePushL(calEntryArray);
			CCalDataExchange* calDataExchange =
					CCalDataExchange::NewL(*iCalSession);
			CleanupStack::PushL(calDataExchange);
			calDataExchange->ExportL(KUidVCalendar, rs, calEntryArray);

			CleanupStack::PopAndDestroy(4, &fs);
	)

	return (iError == KErrNone);
}

/*!
	Returns error code.
 */
AgendaUtil::Error AgendaUtilPrivate::error() const
{
	switch (iError) {
		case KErrNone:
			return AgendaUtil::NoError;
		case KErrNoMemory:
			return AgendaUtil::OutOfMemoryError;
		case KErrInUse:
			return AgendaUtil::AlreadyInUse;
		default:
			return AgendaUtil::UnknownError;
	}
}

void AgendaUtilPrivate::setCompleted(
		AgendaEntry& entry, bool complete, QDateTime& dateTime)
{
	int success = 0;

	TRAP(
			iError,

			// Convert the dateTime to TCalTime.
			TCalTime calTime;
			TDateTime time(
					dateTime.date().year(), TMonth(dateTime.date().month() - 1),
					dateTime.date().day() - 1, dateTime.time().hour(),
					dateTime.time().minute(), dateTime.time().second(),
					dateTime.time().msec());

			calTime.SetTimeLocalL(time);

			// Fetch the calentry
			CCalEntry* calEntry = iCalEntryView->FetchL(entry.id());
			calEntry->SetCompletedL(complete, calTime);

			// Update the entry in the Database
			RPointerArray<CCalEntry> array;
			CleanupResetAndDestroyPushL(array);
			array.AppendL(calEntry);
			iCalEntryView->UpdateL(array, success);

			// Cleanup.
			CleanupStack::PopAndDestroy( &array );
	)

	if (0 < success) {
		emit q->entryUpdated(entry.id());
	}
}

/*!
	Deletes entries between a given range.

	\param start The start datetime of the range.
	\param end The end datetime of the range.
	\param filter The filter to include types of entries.
 */
void AgendaUtilPrivate::deleteEntries(
		QDateTime& start, QDateTime& end, AgendaUtil::FilterFlags filter)
{
	TRAP(
			iError,

			TDateTime startDateTime(
					start.date().year(), TMonth(start.date().month() - 1),
					start.date().day() - 1, start.time().hour(),
					start.time().minute(), start.time().second(),
					start.time().msec());

			TDateTime endDateTime(
					end.date().year(), TMonth(end.date().month() - 1),
					end.date().day() - 1, end.time().hour(),
					end.time().minute(), end.time().second(),
					end.time().msec());

			TCalTime startCalTime;
			TCalTime endCalTime;
			startCalTime.SetTimeLocalL(startDateTime);
			endCalTime.SetTimeLocalL(endDateTime);

			CalCommon::TCalTimeRange calTimeRange(startCalTime, endCalTime);

			// Set the flag indicating that delete is in progress.
			mIsDeleting = true;
			iCalEntryView->DeleteL(
					calTimeRange,
					(CalCommon::TCalViewFilterFlags) filter, *this);
	)
}

/*!
	Returns the parent entry of the given entry.

	\param entry The entry for which parent entry is required.
	\return AgendaEntry The parent entry.
 */
AgendaEntry AgendaUtilPrivate::parentEntry(AgendaEntry& entry)
{
	AgendaEntry parentEntry;
	// First check if the session with the calendar exists.
	if (!mInstanceViewCreated) {
		// Return empty AgendaEntry.
		return entry;
	}

	TRAP(
			iError,

			// Get the CalEntry equivalent of the entry.
			CCalEntry* calEntry = iCalEntryView->FetchL(entry.id());

			if (calEntry) {
				CleanupStack::PushL(calEntry);
				// Get all the entries with same global Uid.
				RPointerArray<CCalEntry> entries;
				CleanupResetAndDestroyPushL(entries);
				iCalEntryView->FetchL(calEntry->UidL(), entries);
				parentEntry = createAgendaEntryFromCalEntry(*entries[0]);
				CleanupStack::PopAndDestroy(&entries);
				CleanupStack::PopAndDestroy(calEntry);
			}
	)

	// Return the parent entry.
	return parentEntry;
}

/*!
	Returns the start and end times of previous occurence of a particular
	instance

	\param entry The instance with which previous instance details are obtained
	\return None
 */
void AgendaUtilPrivate::getPreviousInstanceTimes(AgendaEntry& entry, 
												QDateTime& startTime, 
												QDateTime& endTime)
{
	RPointerArray<CCalEntry> entries;
	CleanupResetAndDestroyPushL(entries);
	TCalTime previousStartTime;
	TCalTime previousEndTime;
	TTime zero(TInt64(0));
	// Fetch the parent entry 
	// Get the CalEntry equivalent of the entry.
	CCalEntry* calEntry = iCalEntryView->FetchL(entry.id());
	
	// Update the start and end dates as per the instance
	TCalTime instanceStartCalTime;
	TCalTime instanceEndCalTime;
	TDateTime instStartDateTime(entry.startTime().date().year(),
		static_cast<TMonth>(entry.startTime().date().month() - 1),
		entry.startTime().date().day() - 1, entry.startTime().time().hour(),
		entry.startTime().time().minute(), entry.startTime().time().second(), 0);
	
	TDateTime instEndDateTime(entry.endTime().date().year(),
		static_cast<TMonth>(entry.endTime().date().month() - 1),
		entry.endTime().date().day() - 1, entry.endTime().time().hour(),
		entry.endTime().time().minute(), entry.endTime().time().second(), 0);
	
	TTime instStartTime(instStartDateTime);
	TTime instEndTime(instEndDateTime);
	// For nontimed entries set the floating time
	if(entry.isTimedEntry()) {
		instanceStartCalTime.SetTimeLocalL(instStartTime);
		instanceEndCalTime.SetTimeLocalL(instEndTime);					    					    
	}else {
		instanceStartCalTime.SetTimeLocalFloatingL(instStartTime);
		instanceEndCalTime.SetTimeLocalFloatingL(instEndTime);
	}
	
	calEntry->SetStartAndEndTimeL(instanceStartCalTime,instanceEndCalTime);
	
	// Get the parent entry of this instance
	if (calEntry) {
		iCalEntryView->FetchL(calEntry->UidL(), entries);
	}
	
	TCalTime currentInstanceDate = calEntry->RecurrenceIdL();
	if (currentInstanceDate.TimeUtcL() == Time::NullTTime()) {
		// We must be creating a new exception. Calculate the recurrence id.
		TTime startTime =  entries[0]->StartTimeL().TimeLocalL();
		TTimeIntervalMinutes timeOfDay = 0;
		TTime beginningOfDay = zero + startTime.DaysFrom( zero );
		startTime.MinutesFrom(beginningOfDay,timeOfDay);
		beginningOfDay = zero + calEntry->StartTimeL().TimeLocalL().DaysFrom(zero);
		currentInstanceDate.SetTimeLocalL( beginningOfDay + timeOfDay );
	}
	TDateTime check = currentInstanceDate.TimeLocalL().DateTime();
	TCalRRule rrule;
	if (entries[0]->GetRRuleL(rrule)) {
		int repeatIndex = getRepeatIndex(*entries[0]);
		TBool keepLooking = ETrue;
		RArray<TCalTime> exdates;
		CleanupClosePushL( exdates );
		entries[0]->GetExceptionDatesL(exdates);
		
		// Needed for case ERepeatOther
		TCalRRule::TType type( rrule.Type() );
		TInt repeatInterval( rrule.Interval() );
		TCalTime start, end;
		TTime previousInstanceTime = Time::NullTTime(); 
		
		while (keepLooking) {
			// Subtract the repeat interval of the parent.
			switch (repeatIndex) {
				case repeatDaily:
					currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()-TTimeIntervalDays(1) );
					break;
				case repeatWeekly:
				case repeatWorkdays:
					currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()-TTimeIntervalDays(7) );
					break;
				case repeatBiWeekly:
					currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()-TTimeIntervalDays(14) );
					break;
				case repeatMonthly:
					currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()-TTimeIntervalMonths(1) );
					break;
				case repeatYearly:
					currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()-TTimeIntervalYears(1) );
					break;
				case repeatOther:
					/* This case includes repeating events like: 3 days every week, 3rd weekday of everymonth
					   that does not fall in any cases above but still have repeating rule*/
					   
					// Check if the current entry being edited is child entry
					// If yes, then put back the child entry time to currentInstanceDate  
					if (calEntry->RecurrenceIdL().TimeUtcL() != Time::NullTTime()) {
						 currentInstanceDate.SetTimeLocalL(calEntry->StartTimeL().TimeLocalL());
					}
			 
					 switch (type) {
						case TCalRRule::EDaily:
							start.SetTimeLocalL( currentInstanceDate.TimeLocalL()-TTimeIntervalDays(1 * repeatInterval));
							break;
						case TCalRRule::EWeekly:
							start.SetTimeLocalL( currentInstanceDate.TimeLocalL()-TTimeIntervalDays(7 * repeatInterval));
							break;
						case TCalRRule::EMonthly: 
							// Add 7 days of buffer to cover the cases were gap b/w two instances of the event 
							// can go beuong 30 days. Ex: Every third wednesday of every month 
							start.SetTimeLocalL( currentInstanceDate.TimeLocalL()-TTimeIntervalMonths(repeatInterval)-TTimeIntervalDays(7 * repeatInterval));
							break;
						case TCalRRule::EYearly:  
							// Add 7 days of buffer to cover the cases were gap b/w two instances of the event 
							// can go beuong 365 days. Ex: Every third wednesday of September of every year
							start.SetTimeLocalL( currentInstanceDate.TimeLocalL()-TTimeIntervalYears(repeatInterval)-TTimeIntervalDays(7 * repeatInterval));
							break;
					 }
					 
					 end.SetTimeLocalL(zero + currentInstanceDate.TimeLocalL().DaysFrom( zero ));
					 previousInstanceTime = getPreviousInstanceForRepeatOther(*entries[0], CalCommon::TCalTimeRange( start, end));
					 currentInstanceDate.SetTimeLocalL( previousInstanceTime);
					 break;
				default:
				case notRepeated:
					keepLooking = EFalse;
					break;
			}
			// Is currentInstanceDate before parent dt start?
			if (currentInstanceDate.TimeLocalL() < 
					entries[0]->StartTimeL().TimeLocalL()) {
				TBool exceptionEntryBeforeParentStartPresent = EFalse;
				for (TInt i=0; i<exdates.Count(); ++i) {
					if( exdates[i].TimeLocalL() < currentInstanceDate.TimeLocalL() ) {
						exceptionEntryBeforeParentStartPresent = ETrue;
					}
				}
				if (!exceptionEntryBeforeParentStartPresent) {
					currentInstanceDate.SetTimeLocalL(Time::NullTTime());
					previousStartTime = currentInstanceDate;
				}
				// There are no instances before the exception
				keepLooking = EFalse;
			} else {
				// TODO: Put the rest of this function into a separate function, as it's identical
				// to GetNextInstanceTimeL().

				// Is there an exdate on currentInstanceDate?
				TBool isExdateOnDay = EFalse;
				for (TInt i=0; i<exdates.Count(); ++i) {
					if( exdates[i].TimeLocalL() == currentInstanceDate.TimeLocalL() )
						{
						isExdateOnDay = ETrue;
						// There is an exdate - is there a child associated with the exdate?
						for(TInt j=1; j<entries.Count(); ++j)
							{
							if( entries[j]->RecurrenceIdL().TimeLocalL() == currentInstanceDate.TimeLocalL() )
								{
								// This child is the previous instance.
								previousStartTime = entries[j]->StartTimeL();
								previousEndTime = entries[j]->EndTimeL();
								keepLooking = EFalse;
								}
							}
						break;
						}
				}
				if (!isExdateOnDay) {
					// The instance exists and hasn't been deleted or made into an exception.
					// Use information from the parent to set the start/end times.
					previousStartTime = currentInstanceDate;

					TTimeIntervalMinutes duration;
					TTime start = entries[0]->StartTimeL().TimeLocalL();
					TTime end = entries[0]->EndTimeL().TimeLocalL(); 
					end.MinutesFrom( start, duration );
					previousEndTime.SetTimeLocalL( currentInstanceDate.TimeLocalL() + duration );
					keepLooking = EFalse;
				}
			}
		}
		CleanupStack::PopAndDestroy(&exdates);
	}
	
	if(previousStartTime.TimeUtcL() != Time::NullTTime()) {
		// Convert TCalTimes to QDateTimes
		TDateTime prevStart = previousStartTime.TimeLocalL().DateTime();
		TDateTime prevEnd = previousEndTime.TimeLocalL().DateTime();
		startTime.setDate(QDate(prevStart.Year(), prevStart.Month()+1,
		                        prevStart.Day() + 1));
		startTime.setTime(QTime(prevStart.Hour(), prevStart.Minute(), 0, 0));
		endTime.setDate(QDate(prevEnd.Year(), prevEnd.Month()+1,
		                      prevEnd.Day() + 1));
		endTime.setTime(QTime(prevEnd.Hour(), prevEnd.Minute(), 0, 0));
	} else {
		QDateTime nullDateTime;
		startTime = nullDateTime;
		endTime = nullDateTime;
	}
	delete calEntry;
	CleanupStack::PopAndDestroy(&entries);
}

/*!
	Returns the start and end times of next occurence of a particular
	instance

	\param entry The instance with which next instance details are obtained
	\return None
 */
void AgendaUtilPrivate::getNextInstanceTimes(AgendaEntry& entry, 
                                          QDateTime& startTime, 
                                          QDateTime& endTime)
{
	RPointerArray<CCalEntry> entries;
	CleanupResetAndDestroyPushL(entries);
	TCalTime nextStartTime;
	TCalTime nextEndTime;
	TTime zero(TInt64(0));
	// Fetch the parent entry 
	// Get the CalEntry equivalent of the entry.
	CCalEntry* calEntry = iCalEntryView->FetchL(entry.id());
	
	// Update the start and end dates as per the instance
	TCalTime instanceStartCalTime;
	TCalTime instanceEndCalTime;
	TDateTime instStartDateTime(entry.startTime().date().year(),
		static_cast<TMonth>(entry.startTime().date().month() - 1),
		entry.startTime().date().day() - 1, entry.startTime().time().hour(),
		entry.startTime().time().minute(), entry.startTime().time().second(), 0);
	
	TDateTime instEndDateTime(entry.endTime().date().year(),
		static_cast<TMonth>(entry.endTime().date().month() - 1),
		entry.endTime().date().day() - 1, entry.endTime().time().hour(),
		entry.endTime().time().minute(), entry.endTime().time().second(), 0);
	
	TTime instStartTime(instStartDateTime);
	TTime instEndTime(instEndDateTime);
	// For nontimed entries set the floating time
	if (entry.isTimedEntry()) {
		instanceStartCalTime.SetTimeLocalL(instStartTime);
		instanceEndCalTime.SetTimeLocalL(instEndTime);
	}else {
		instanceStartCalTime.SetTimeLocalFloatingL(instStartTime);
		instanceEndCalTime.SetTimeLocalFloatingL(instEndTime);
	}
	calEntry->SetStartAndEndTimeL(instanceStartCalTime,instanceEndCalTime);
	
	// Get the parent entry of this instance
	if (calEntry) {
		iCalEntryView->FetchL(calEntry->UidL(), entries);
	}
	
	TCalTime currentInstanceDate = calEntry->RecurrenceIdL();
	if (currentInstanceDate.TimeUtcL() == Time::NullTTime()) {
		// We must be creating a new exception. Calculate the recurrence id.
		TTime startTime =  entries[0]->StartTimeL().TimeLocalL();
		TTimeIntervalMinutes timeOfDay = 0;
		TTime beginningOfDay = zero + startTime.DaysFrom( zero );
		startTime.MinutesFrom(beginningOfDay,timeOfDay);
		beginningOfDay = zero + calEntry->StartTimeL().TimeLocalL().DaysFrom(zero);
		currentInstanceDate.SetTimeLocalL( beginningOfDay + timeOfDay );
	}
	
	TCalRRule rrule;
	if (entries[0]->GetRRuleL(rrule)) {
		int repeatIndex = getRepeatIndex(*entries[0]);
		TBool keepLooking = ETrue;
		RArray<TCalTime> exdates;
		CleanupClosePushL( exdates );
		entries[0]->GetExceptionDatesL(exdates);
		
		// Needed for case ERepeatOther
		TCalRRule::TType type( rrule.Type() );
		TInt repeatInterval( rrule.Interval() );
		TCalTime start, end;
		TTime previousInstanceTime = Time::NullTTime(); 
		
		while (keepLooking) {
			// Subtract the repeat interval of the parent.
			switch (repeatIndex) {
				case repeatDaily:
					currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()+TTimeIntervalDays(1) );
					break;
				case repeatWeekly:
				case repeatWorkdays:
					currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()+TTimeIntervalDays(7) );
					break;
				case repeatBiWeekly:
					currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()+TTimeIntervalDays(14) );
					break;
				case repeatMonthly:
					currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()+TTimeIntervalMonths(1) );
					break;
				case repeatYearly:
					currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()+TTimeIntervalYears(1) );
					break;
				case repeatOther:
					/* This case includes repeating events like: 3 days every week, 3rd weekday of everymonth
					   that does not fall in any cases above but still have repeating rule*/
					   
					// Check if the current entry being edited is child entry
					// If yes, then put back the child entry time to currentInstanceDate  
					if (calEntry->RecurrenceIdL().TimeUtcL() != Time::NullTTime()) {
						 currentInstanceDate.SetTimeLocalL(calEntry->StartTimeL().TimeLocalL());
					}
			 
					 switch (type) {
						case TCalRRule::EDaily:
							start.SetTimeLocalL( currentInstanceDate.TimeLocalL()+TTimeIntervalDays(1 * repeatInterval));
							break;
						case TCalRRule::EWeekly:
							start.SetTimeLocalL( currentInstanceDate.TimeLocalL()+TTimeIntervalDays(7 * repeatInterval));
							break;
						case TCalRRule::EMonthly: 
							// Add 7 days of buffer to cover the cases were gap b/w two instances of the event 
							// can go beuong 30 days. Ex: Every third wednesday of every month 
							start.SetTimeLocalL( currentInstanceDate.TimeLocalL()+TTimeIntervalMonths(repeatInterval)-TTimeIntervalDays(7 * repeatInterval));
							break;
						case TCalRRule::EYearly:  
							// Add 7 days of buffer to cover the cases were gap b/w two instances of the event 
							// can go beuong 365 days. Ex: Every third wednesday of September of every year
							start.SetTimeLocalL( currentInstanceDate.TimeLocalL()+TTimeIntervalYears(repeatInterval)-TTimeIntervalDays(7 * repeatInterval));
							break;
					 }
					 
					 end.SetTimeLocalL(zero + currentInstanceDate.TimeLocalL().DaysFrom( zero ));
					 previousInstanceTime = getNextInstanceForRepeatOther(*entries[0], CalCommon::TCalTimeRange( start, end));
					 currentInstanceDate.SetTimeLocalL( previousInstanceTime);
					 break;
				default:
				case notRepeated:
					keepLooking = EFalse;
					break;
			}
			// Is currentInstanceDate after repeat until date?
			if (currentInstanceDate.TimeLocalL() >  
					rrule.Until().TimeLocalL()) {
				TBool exceptionEntryAfterRepeatUntilPresent = EFalse;
				for (TInt i=0; i<exdates.Count(); ++i) {
					if(exdates[i].TimeLocalL() > rrule.Until().TimeLocalL()) {
						exceptionEntryAfterRepeatUntilPresent = ETrue;
					}
				}
				if (!exceptionEntryAfterRepeatUntilPresent) {
					currentInstanceDate.SetTimeLocalL(Time::NullTTime());
					nextStartTime = currentInstanceDate;
				}
				// There are no instances before the exception
				keepLooking = EFalse;
			} else {
				// TODO: Put the rest of this function into a separate function, as it's identical
				// to GetNextInstanceTimeL().

				// Is there an exdate on currentInstanceDate?
				TBool isExdateOnDay = EFalse;
				for (TInt i=0; i<exdates.Count(); ++i) {
					if( exdates[i].TimeLocalL() == currentInstanceDate.TimeLocalL() )
						{
						isExdateOnDay = ETrue;
						// There is an exdate - is there a child associated with the exdate?
						for(TInt j=1; j<entries.Count(); ++j)
							{
							if( entries[j]->RecurrenceIdL().TimeLocalL() == currentInstanceDate.TimeLocalL() )
								{
								// This child is the previous instance.
								nextStartTime = entries[j]->StartTimeL();
								nextEndTime = entries[j]->EndTimeL();
								keepLooking = EFalse;
								}
							}
						break;
						}
				}
				if (!isExdateOnDay) {
					// The instance exists and hasn't been deleted or made into an exception.
					// Use information from the parent to set the start/end times.
					nextStartTime = currentInstanceDate;

					TTimeIntervalMinutes duration;
					TTime start = entries[0]->StartTimeL().TimeLocalL();
					TTime end = entries[0]->EndTimeL().TimeLocalL(); 
					end.MinutesFrom( start, duration );
					nextEndTime.SetTimeLocalL( currentInstanceDate.TimeLocalL() + duration );
					keepLooking = EFalse;
				}
			}
		CleanupStack::PopAndDestroy( &exdates );
		}
	}
	
	if (nextStartTime.TimeUtcL() != Time::NullTTime()) {
		// Convert TCalTimes to QDateTimes
		TDateTime nextStart = nextStartTime.TimeLocalL().DateTime();
		TDateTime nextEnd = nextEndTime.TimeLocalL().DateTime();
		startTime.setDate(QDate(nextStart.Year(), nextStart.Month()+1,
		                        nextStart.Day() + 1));
		startTime.setTime(QTime(nextStart.Hour(), nextStart.Minute(), 0, 0));
		endTime.setDate(QDate(nextEnd.Year(), nextEnd.Month()+1,
		                      nextEnd.Day() + 1));
		endTime.setTime(QTime(nextEnd.Hour(), nextEnd.Minute(), 0, 0));	
	} else {
		QDateTime nullDateTime;
		startTime = nullDateTime;
		endTime = nullDateTime;
	}
	delete calEntry;
	
	CleanupStack::PopAndDestroy(&entries);
}

/*!
	 Returns true if there are no entries in the database else returns false
	 
	 \return bool 
 */
bool AgendaUtilPrivate::areNoEntriesInCalendar()
{
	// First prepare the session with the agenda server.
	if (!mInstanceViewCreated) {
        // database is not ready, so, return that there are no entries
		return true;
	}
	
	bool isEmpty;
	// Query for the entries for entire range
	RPointerArray<CCalInstance> instanceList;
	CleanupResetAndDestroyPushL(instanceList);
	
	// Create the filter
	CalCommon::TCalViewFilter filters = AgendaUtil::IncludeAnniversaries
										| AgendaUtil::IncludeAppointments
										| AgendaUtil::IncludeEvents
										| AgendaUtil::IncludeReminders
										| AgendaUtil::IncludeIncompletedTodos;
	
	// Set up the range
	TCalTime startDateForInstanceSearch;
	TCalTime endDateForInstanceSearch;

	TDateTime startTime = TDateTime(
			startDateArray[0], static_cast<TMonth>(startDateArray[1]),
			0, 0, 0, 0, 0);

	TDateTime endTime = TDateTime(
			endDateArray[0], static_cast<TMonth>(endDateArray[1]),
			0, 0, 0, 0, 0);

	startDateForInstanceSearch.SetTimeLocalL(startTime);
	endDateForInstanceSearch.SetTimeLocalL(endTime);
	CalCommon::TCalTimeRange searchTimeRange(
			startDateForInstanceSearch,
			endDateForInstanceSearch);
	
	// Fire a query
	iCalInstanceView->FindInstanceL(
			instanceList, filters, searchTimeRange);
	
	// Check the list count
	if (instanceList.Count()) {
		isEmpty = false;
	} else {
		isEmpty = true;
	}
	
	// Cleanup
	CleanupStack::PopAndDestroy( &instanceList );
	return isEmpty;
}

/*!
	Returns the minimum time supported.

	\return QDateTime holding the minimum supported time.
 */
QDateTime AgendaUtilPrivate::minTime()
{
	TTime minTime = TCalTime::MinTime();

	// Convert it to QT
	QDate date(
			minTime.DateTime().Year(), minTime.DateTime().Month() + 1,
			minTime.DateTime().Day() + 1);
	QTime time(
			minTime.DateTime().Hour(), minTime.DateTime().Minute(),
			minTime.DateTime().Second());

	QDateTime minimumDateTime(date, time);

	return minimumDateTime;
}

/*!
	Returns the maximum time supported.

	\return QDateTime holding the maximum supported time.
 */
QDateTime AgendaUtilPrivate::maxTime()
{
	// Returns maximum time allowed, 31.12.2100 0:00 is max so 30.12.2100 is
	// last actual date to be used.
	TTime maxTime = TCalTime::MaxTime() - TTimeIntervalMinutes( 1 );

	// Convert it to QT
	QDate date(
			maxTime.DateTime().Year(), maxTime.DateTime().Month() + 1,
			maxTime.DateTime().Day() + 1);
	QTime time(
			maxTime.DateTime().Hour(), maxTime.DateTime().Minute(),
			maxTime.DateTime().Second());

	QDateTime maximumDateTime(date, time);

	return maximumDateTime;
}

/*!
    Returns true if entry repeats on workdays else false

    \return true if entry repeats on workdays else false
 */
bool AgendaUtilPrivate::isWorkdaysRepeatingEntry(
											const AgendaRepeatRule& repeatRule)
{
	bool status = true;
	int fixedNum = 1;
	int ruleday = 0;
	HbExtendedLocale locale = HbExtendedLocale::system();

	QString workDaysString = locale.workDays();
	bool ok;
	uint workDays = workDaysString.toUInt(&ok, 2);
	if (!ok) {
		return false;
	}
	QList<AgendaRepeatRule::Day> weekDaysFromRule = repeatRule.byDay();

	QList<AgendaRepeatRule::Day> weekDaysFromLocale;

	// "workDays" is a bit mask of seven bits indicating (by being set) which days are workdays. 
	// The least significant bit corresponds to Monday, the next bit to Tuesday and so on. 
	// "workDays" is converted into weekDaysFromLocale for comparing with "weekDaysFromRule".
	for (TInt i = 0; i < KNoOfDaysInWeek; i++) {
		ruleday = fixedNum << i;
		if (workDays & ruleday) {
			weekDaysFromLocale.append((AgendaRepeatRule::Day) i);
		}
	}

	// Checks whether the device "workdays" are same as the event's repeat days.
	if (weekDaysFromRule.count() == weekDaysFromLocale.count()) {
		for (int i = 0; i < weekDaysFromLocale.count(); i++) {
			if ((int) weekDaysFromLocale[i] != (int) weekDaysFromRule[i]) {
				status = false;
				break;
			}
		}
	} else {
		status = false;
	}

	return status;

}
/*!
	Creates an AgendaEntry object from a given CCalEntry and CCalInstance.

	\param calEntry Reference to a CCalEntry.
	\param instance A CCalInstance.

	\return AgendaEntry.
 */
AgendaEntry AgendaUtilPrivate::createAgendaEntryFromCalEntry(
		CCalEntry& calEntry, CCalInstance* instance)
{
	AgendaEntry entry;

	// Type.
	AgendaEntry::Type entryType =
			static_cast<AgendaEntry::Type>(calEntry.EntryTypeL());
	entry.setType(entryType);

	// Method.
	AgendaEntry::Method method =
			static_cast<AgendaEntry::Method>(calEntry.MethodL());
	entry.setMethod(method);

	// Summary.
	TPtrC calSummary = calEntry.SummaryL();
	entry.setSummary(
			QString::fromUtf16(calSummary.Ptr(), calSummary.Length()));

	// Description.
	TPtrC calDescription = calEntry.DescriptionL();
	entry.setDescription(
			QString::fromUtf16(calDescription.Ptr(), calDescription.Length()));

	// Location.
	TPtrC calLocation = calEntry.LocationL();
	entry.setLocation(
			QString::fromUtf16(calLocation.Ptr(), calLocation.Length()));

	// Priority.
	entry.setPriority(calEntry.PriorityL());

	// Time.
	TDateTime calStartDateTime;
	TDateTime calEndDateTime;
	if (instance) {
		// Set start time and end time frm the instance instead from entry
		// to copy the correct time.
		calStartDateTime = instance->StartTimeL().TimeLocalL().DateTime();
		calEndDateTime = instance->EndTimeL().TimeLocalL().DateTime();
	} else {
		calStartDateTime = calEntry.StartTimeL().TimeLocalL().DateTime();
		calEndDateTime = calEntry.EndTimeL().TimeLocalL().DateTime();
	}
	QDateTime startDateTime(
			QDate(
					calStartDateTime.Year(), calStartDateTime.Month()+1,
					calStartDateTime.Day() + 1),
			QTime(
					calStartDateTime.Hour(), calStartDateTime.Minute(), 0, 0));
	QDateTime endDateTime(
			QDate(
					calEndDateTime.Year(), calEndDateTime.Month()+1,
					calEndDateTime.Day() + 1),
			QTime(
					calEndDateTime.Hour(), calEndDateTime.Minute(), 0, 0));
	entry.setStartAndEndTime(startDateTime, endDateTime);

	// Attendees.
	RPointerArray<CCalAttendee> calAttendees = calEntry.AttendeesL();

	for (int i = 0; i < calAttendees.Count(); i++) {
		AgendaAttendee attendee;
		// Address.
		TPtrC calAddress = calAttendees[i]->Address();
		attendee.setAddress(
				QString::fromUtf16(calAddress.Ptr(), calAddress.Length()));

		// Common name.
		TPtrC calCommonName = calAttendees[i]->CommonName();
		attendee.setCommonName(QString::fromUtf16(
				calCommonName.Ptr(), calCommonName.Length()));

		// Response requested.
		attendee.setResponseRequested(calAttendees[i]->ResponseRequested());

		// Participant role.
		attendee.setRole(static_cast<AgendaAttendee::ParticipantRole>(
				calAttendees[i]->RoleL()));

		// Status.
		attendee.setStatus(
				static_cast<AgendaAttendee::StatusType>(
						calAttendees[i]->StatusL()));
		entry.addAttendee(attendee);
	}

// TODO: Right now we are not adding category to agendaEntry.
// Will be handled later when we have some usecase with category.
/*
	// Categories.
	const RPointerArray<CCalCategory>& calCategories = calEntry.CategoryListL();

	for (int i = 0; i < calCategories.Count(); i++) {
		AgendaCategory category;
		CCalCategory::TCalCategoryType categoryType =
				calCategories[i]->Category();
		if (categoryType == CCalCategory::ECalExtended) {
			TPtrC categoryName = calCategories[i]->ExtendedCategoryName();
			category.setExtendedCategoryName(
					QString::fromUtf16(
							categoryName.Ptr(), categoryName.Length()));
		}
		category.setCategory(
				static_cast<AgendaCategory::CategoryType>(categoryType));
		entry.addCategory(category);
	}
*/
	// Id.
	entry.d->m_id = calEntry.LocalUidL();

	// Alarm.
	CCalAlarm* calAlarm = calEntry.AlarmL();
	if (calAlarm) {
		CleanupStack::PushL(calAlarm);
		AgendaAlarm alarm;
		alarm.setAlarmSoundName(QString::fromUtf16(
				calAlarm->AlarmSoundNameL().Ptr(),
				calAlarm->AlarmSoundNameL().Length()));
		alarm.setTimeOffset(calAlarm->TimeOffset().Int());
		entry.setAlarm(alarm);
		CleanupStack::PopAndDestroy(calAlarm);
	}

	// Repear rule.
	TCalRRule calRRule;
	calEntry.GetRRuleL(calRRule);
	if (calRRule.Type() != TCalRRule::EInvalid) {
		AgendaRepeatRule agendaRepeatRule =
		        createAgendaRRuleFromTCalRRule(calRRule);
		// Set the rule now.
		entry.setRepeatRule(agendaRepeatRule);
	}

	// Get the RDates.
	RArray<TCalTime> rDateList;
	calEntry.GetRDatesL(rDateList);
	QList<QDate> qRDates;
	for (int i = 0; i < rDateList.Count(); i++) {
		TTime rDate = rDateList[i].TimeUtcL();
		QDate qRdate(
				rDate.DateTime().Year(),
				rDate.DateTime().Month() + 1,
				rDate.DateTime().Day() + 1);
		qRDates.append(qRdate);
	}
	// Set the RDates.
	entry.setRDates(qRDates);

	// Recurrence Id.
	TCalTime recCalTime = calEntry.RecurrenceIdL();
	
	// Set the recurrence id only when it is not NULL
	// so that we can identify the child properly
	if (recCalTime.TimeUtcL() != Time::NullTTime()) {
		TTime recTime = recCalTime.TimeUtcL();
		QDateTime qRecTime(
				QDate(
						recTime.DateTime().Year(), recTime.DateTime().Month() + 1,
						recTime.DateTime().Day() + 1),
				QTime(
						recTime.DateTime().Hour(), recTime.DateTime().Minute(),
						recTime.DateTime().Second()));
		entry.setRecurrenceId(qRecTime);
	}
	
	// Set the last modification time for the entry.
	TCalTime lastModCalTime = calEntry.LastModifiedDateL();
	TTime localTime = lastModCalTime.TimeLocalL();
	TDateTime localDateTime = localTime.DateTime();
	QDateTime lastModifiedTime(
			QDate(
					localDateTime.Year(),
					localDateTime.Month() + 1,
					localDateTime.Day() + 1),
			QTime(
					localDateTime.Hour(), localDateTime.Minute(),
					localDateTime.Second(), 0));
	entry.setLastModifiedDateTime(lastModifiedTime);

	// Set the status for the entry.
	entry.setStatus((AgendaEntry::Status) calEntry.StatusL());

	// Get the favourite property.
	entry.setFavourite(calEntry.FavouriteL());

	// Set the to-do completion date and time for the entry
	TCalTime completionTime = calEntry.CompletedTimeL();
	TTime completionTimeInlocal = completionTime.TimeLocalL();
	QDateTime completionDateTime(
				QDate(
						completionTimeInlocal.DateTime().Year(),
						completionTimeInlocal.DateTime().Month() + 1,
						completionTimeInlocal.DateTime().Day() + 1),
				QTime(
						completionTimeInlocal.DateTime().Hour(),
						completionTimeInlocal.DateTime().Minute(),
						completionTimeInlocal.DateTime().Second(), 0));
	entry.setCompletedDateTime(completionDateTime);

	// Set the dtStamp time for agenda entry. Currently dtstamp is used as
	// creation time for the entry type ENote.
	TCalTime dtStampTime = calEntry.DTStampL();
	TTime dtStampTimeInLocal = dtStampTime.TimeLocalL();
	QDateTime dtStampDateTime;
	if (dtStampTimeInLocal != Time::NullTTime()) {
		dtStampDateTime.setDate(
				QDate(
					dtStampTimeInLocal.DateTime().Year(),
					dtStampTimeInLocal.DateTime().Month() + 1,
					dtStampTimeInLocal.DateTime().Day() + 1));

		dtStampDateTime.setTime(
				QTime(
					dtStampTimeInLocal.DateTime().Hour(),
					dtStampTimeInLocal.DateTime().Minute(),
					dtStampTimeInLocal.DateTime().Second()));
	}
	entry.setDTStamp(dtStampDateTime);
	
	// Copy the geo value if it has any
	CCalGeoValue* geoValue = calEntry.GeoValueL();
	if (geoValue) {
		AgendaGeoValue entryGeoValue;
		double latitude;
		double longitude;
		geoValue->GetLatLong(latitude, longitude);
		entryGeoValue.setLatLong(latitude, longitude);
		
		// Set it to entry
		entry.setGeoValue(entryGeoValue);
		delete geoValue;
	}
	
	// Return the entry.
	return entry;
}

/*!
	Copy all the data to CCalEntry from a given AgendaEntry.
	\param agendaEntry Reference to a AgendaEntry.
	\param calEntry Reference to a CCalEntry.
 */
void AgendaUtilPrivate::createCCalEntryFromAgendaEntry(AgendaEntry &agendaEntry, CCalEntry &calEntry)
{
	if (agendaEntry.isNull()) {
			// Invalid entry.
			return;
		}
	
	TRAP(
			iError,
			// Add description to the agendaEntry.
			TPtrC
					description(
								reinterpret_cast<const TUint16*> (agendaEntry.description().utf16()));
			calEntry.SetDescriptionL(description);
			
			if(AgendaEntry::MethodUnknown != agendaEntry.method()) {
								calEntry.SetMethodL(
									static_cast<CCalEntry::TMethod> (agendaEntry.method()));
			}
	
			// Set the favourite property.
			calEntry.SetFavouriteL(agendaEntry.favourite());
			
			
			if (AgendaEntry::TypeNote == agendaEntry.type()) {
				// Set the last modification time.
				TCalTime calTime;
				QDateTime dateTime = agendaEntry.lastModifiedDateTime();
				TDateTime tempDateTime(dateTime.date().year(),
						static_cast<TMonth> (dateTime.date().month() - 1),
						dateTime.date().day() - 1, dateTime.time().hour(),
						dateTime.time().minute(), 0, 0);
				TTime tempTime(tempDateTime);
				calTime.SetTimeLocalL(tempTime);
				calEntry.SetLastModifiedDateL(calTime);
				
				// Set the dtstamp time.It is used to set the creation time.
				TCalTime creationCalTime;
				QDateTime dtStamp = agendaEntry.dtStamp();
				TDateTime
				creationDateTime(dtStamp.date().year(),
						static_cast<TMonth> (dtStamp.date().month() - 1),
						dtStamp.date().day() - 1, dtStamp.time().hour(),
						dtStamp.time().minute(), 0, 0);
				TTime creationTTime(creationDateTime);
				creationCalTime.SetTimeLocalL(creationTTime);
				calEntry.SetDTStampL(creationCalTime);
			} else {
	
			// Add the summary.
			TPtrC
					summary(
							reinterpret_cast<const TUint16*> (agendaEntry.summary().utf16()));
			calEntry.SetSummaryL(summary);
	
			// Set the agendaEntry Start/End Date and time.
			QDate date = agendaEntry.startTime().date();
			QTime time = agendaEntry.startTime().time();
	
			TDateTime startDateTime(date.year(), static_cast<TMonth> (date.month()
					- 1), date.day() - 1, time.hour(), time.minute(), 0, 0);
			TTime entryStartTime(startDateTime);
			TCalTime calStartTime;

			date = agendaEntry.endTime().date();
			time = agendaEntry.endTime().time();
	
			TDateTime endDateTime(date.year(), static_cast<TMonth> (date.month()
					- 1), date.day() - 1, time.hour(), time.minute(), 0, 0);
			TTime entryEndTime(endDateTime);
			TCalTime calEndTime;
			
			// Use floating time for the nontimed entries.
			if(agendaEntry.isTimedEntry()) {
			    calStartTime.SetTimeLocalL(entryStartTime);
			    calEndTime.SetTimeLocalL(entryEndTime);    
			}else {
			    calStartTime.SetTimeLocalFloatingL(entryStartTime);
			    calEndTime.SetTimeLocalFloatingL(entryEndTime);
			}
			calEntry.SetStartAndEndTimeL(calStartTime, calEndTime);
	
			// Add attendees to the agendaEntry.
			addAttendeesToEntry(agendaEntry.d->m_attendees, calEntry);
	
			// Add categories to the agendaEntry.
			addCategoriesToEntry(agendaEntry.d->m_categories, calEntry);
	
			// Add Alarm to the agendaEntry.
			AgendaAlarm alarm = agendaEntry.alarm();
			setAlarmToEntry(alarm, calEntry);
	
			// Set the priority.
			int priority = agendaEntry.priority();
			if (agendaEntry.priority() != -1) {
				calEntry.SetPriorityL(priority);
			}
	
			// Set the location.
			TPtrC
					location(
							 reinterpret_cast<const TUint16*> (agendaEntry.location().utf16()));
			calEntry.SetLocationL(location);
	
			// Set the repeat type if applicable.
			if (AgendaRepeatRule::InvalidRule != agendaEntry.repeatRule().type()) {
				AgendaRepeatRule agendaRepeatRule = agendaEntry.repeatRule();
				TCalRRule repeatRule =
						createTCalRRuleFromAgendaRRule(agendaRepeatRule, agendaEntry.isTimedEntry());
				calEntry.SetRRuleL(repeatRule);
			}
	
			// Save the status of the agendaEntry.
			calEntry.SetStatusL((CCalEntry::TStatus) agendaEntry.status());
	
			// Save the geo value if any
			AgendaGeoValue entryGeoValue = agendaEntry.geoValue();
			if (!entryGeoValue.isNull()) {
				CCalGeoValue* geoValue = CCalGeoValue::NewL();
				double latitude;
				double longitude;
				entryGeoValue.getLatLong(latitude, longitude);
	
				// set the values to symbian geo value
				geoValue->SetLatLongL(latitude, longitude);
	
				// set it to CCalentry
				calEntry.SetGeoValueL(*geoValue);
				delete geoValue;
			} else {
				calEntry.ClearGeoValueL();
			}
		}
	)

}

bool AgendaUtilPrivate::addAttendeesToEntry(
		const QList<AgendaAttendee>& attendees, CCalEntry& entry)
{
	// First prepare the session with the agenda server.
	if (!mInstanceViewCreated) {
		return false;
	}

	TRAP(
			iError,

			for (int i = 0; i < attendees.count(); i++) {
				CCalAttendee* attendee = CCalAttendee::NewL(
						TPtrC(reinterpret_cast<const TUint16*>(
								attendees.at(i).address().utf16())));
				attendee->SetCommonNameL(
						TPtrC(reinterpret_cast<const TUint16*>(
								attendees.at(i).commonName().utf16())));
				attendee->SetResponseRequested(
						attendees.at(i).responseRequested());
				attendee->SetRoleL(static_cast<CCalAttendee::TCalRole>(
						attendees.at(i).role()));
				attendee->SetStatusL(static_cast<CCalAttendee::TCalStatus>(
						attendees.at(i).status()));
				entry.AddAttendeeL(attendee);
			}
	)
	return (iError == KErrNone);
}

bool AgendaUtilPrivate::addCategoriesToEntry(
		const QList<AgendaCategory>& categories, CCalEntry& entry)
{
	// First prepare the session with the agenda server.
	if (!mInstanceViewCreated) {
		return false;
	}
	TRAP(
			iError,

			for (int i = 0; i < categories.count(); i++) {
				AgendaCategory::CategoryType type = categories.at(i).category();
				if (type != AgendaCategory::ExtendedCategory) {
					CCalCategory* category = CCalCategory::NewL(
							static_cast<CCalCategory::TCalCategoryType>(type));
					entry.AddCategoryL(category);
				} else {
					TPtrC categoryName = TPtrC(reinterpret_cast<const TUint16*>(
							categories.at(i).extendedCategoryName().utf16()));
					CCalCategory* category = CCalCategory::NewL(categoryName);
					entry.AddCategoryL(category);
				}
			}
	)
	return (iError == KErrNone);
}

bool AgendaUtilPrivate::setAlarmToEntry(
		const AgendaAlarm& alarm, CCalEntry& entry)
{
	TRAP(
			iError,

			if (alarm.isNull()) {
				entry.SetAlarmL(0);
			} else {
				CCalAlarm* calAlarm = CCalAlarm::NewL();
				CleanupStack::PushL(calAlarm);
				calAlarm->SetTimeOffset(alarm.timeOffset());
				if (!alarm.alarmSoundName().isNull()) {
					TPtrC alarmName(reinterpret_cast<const TUint16*>(
							alarm.alarmSoundName().utf16()));
					calAlarm->SetAlarmSoundNameL(alarmName);
				}
				entry.SetAlarmL(calAlarm);
				CleanupStack::PopAndDestroy(calAlarm);
			}
	)
	return (iError == KErrNone);
}

void AgendaUtilPrivate::sortInstanceList(RPointerArray<CCalInstance>& list)
{
	TLinearOrder<CCalInstance> instanceListOrder(
			AgendaUtilPrivate::entryCompare );
	list.Sort( instanceListOrder );
}

void AgendaUtilPrivate::getDayRange(
		const QDateTime& aStartDay, const QDateTime& aEndDay,
		CalCommon::TCalTimeRange& aRange )
{
	TDateTime start(
			aStartDay.date().year(), TMonth(aStartDay.date().month() - 1),
			aStartDay.date().day() - 1, aStartDay.time().hour(),
			aStartDay.time().minute(), aStartDay.time().second(),
			aStartDay.time().msec());
	TDateTime end(
			aEndDay.date().year(), TMonth(aEndDay.date().month() - 1),
			aEndDay.date().day() - 1, aEndDay.time().hour(),
			aEndDay.time().minute(), aEndDay.time().second(),
			aEndDay.time().msec());

	start.SetHour(0);
	start.SetMinute(0);
	start.SetSecond(0);
	start.SetMicroSecond(0);

	end.SetHour(23);
	end.SetMinute(59);
	end.SetSecond(59);
	end.SetMicroSecond(0);

	// Prevent overflow.
	TCalTime endDate;
	endDate.SetTimeLocalL(LimitToValidTime(TTime(end)));
	TCalTime startDate;
	startDate.SetTimeLocalL(LimitToValidTime(TTime(start)));

	CalCommon::TCalTimeRange dayrange(startDate, endDate);
	aRange = dayrange;
}

TTime AgendaUtilPrivate::LimitToValidTime( const TTime& aTime )
{

	TTime valid = aTime;
	valid = valid > (
			TCalTime::MaxTime() - TTimeIntervalMinutes( 1 ))
			? (TCalTime::MaxTime() - TTimeIntervalMinutes( 1 ))
			: valid;
	valid = valid < (TCalTime::MinTime()) ? (TCalTime::MinTime()) : valid;

	return valid;
}

CCalInstance* AgendaUtilPrivate::findPossibleInstance(AgendaEntry& entry)
{
    if(!mInstanceViewCreated) {
        // return empty list
        return NULL;
    }
	TCalTime dummy;
	CalCommon::TCalTimeRange dayRange(dummy, dummy);
	getDayRange(entry.startTime(), entry.startTime(), dayRange);
	RPointerArray<CCalInstance> instances;
	CleanupResetAndDestroyPushL(instances);
	CalCommon::TCalViewFilter filter = 
				CalCommon::TCalViewFilter(CalCommon::EIncludeAnnivs |
										CalCommon::EIncludeAppts | 
										CalCommon::EIncludeEvents |
										CalCommon::EIncludeReminder |
										CalCommon::EIncludeIncompletedTodos);
	iCalInstanceView->FindInstanceL(instances, filter, dayRange);
	TTime entryStartTime(dayRange.StartTime().TimeLocalL());

	CCalInstance* result = 0;

	// For instances finishing the next day (now possible with unified
	// DateTime editor), we have to do our best to match the instance time
	// exactly - otherwise we could match the LocalUid to the incorrect
	// instance in a series.
	for(int i = 0; i < instances.Count() && !result; ++i)
	{
		if(instances[i]->Entry().LocalUidL() == entry.id())
		{
			// Check the instance time matches.
			if(instances[i]->StartTimeL().TimeLocalL() == entryStartTime)
			{
				result = instances[i];
				instances.Remove(i);
			}
		}
	}

	if(!result)
	{
		// Couldn't match the instance time exactly - just use the instance
		// with the same LocalUid as the one we're looking for.
		for(TInt i=0; i < instances.Count() && !result; ++i)
		{
			if(instances[i]->Entry().LocalUidL() == entry.id())
			{
				result = instances[i];
				instances.Remove(i);
			}
		}
	}

	// Cleanup.
	CleanupStack::PopAndDestroy(&instances);
	return result;
}

int AgendaUtilPrivate::entryCompare(
		const CCalInstance& aInstance1, const CCalInstance& aInstance2)
{
	int ret(Equal);

	const CCalEntry& entry1 = aInstance1.Entry();
	const CCalEntry& entry2 = aInstance2.Entry();
	const CCalEntry::TType type1 = entry1.EntryTypeL();
	const CCalEntry::TType type2 = entry2.EntryTypeL();

	// types are equal (reminders are handled as meetings)
	if(type1 == type2
			|| ((type1 == CCalEntry::EAppt && type2 == CCalEntry::EReminder)
			|| (type2 == CCalEntry::EAppt && type1 == CCalEntry::EReminder)))
	{
		switch(type1)
		{
			case CCalEntry::ETodo:
				ret = compareToDos(entry1, entry2);
				break;

			case CCalEntry::EAnniv:
			case CCalEntry::EEvent:
				ret = compareNonTimedNotes(aInstance1, aInstance2);
				break;

			case CCalEntry::EReminder:
			case CCalEntry::EAppt:
				ret = compareTimedNotes(aInstance1, aInstance2);
				break;

			default:
				ASSERT(EFalse);
		}
	}
	else // Types are different.
	{
		switch(type1)
		{
			case CCalEntry::ETodo:
				// To-dos come always first...
				ret = LessThan;
				break;

			case CCalEntry::EEvent:
			{
				// ...then day notes...
				if(type2 == CCalEntry::ETodo)
				{
					ret = GreaterThan;
				}
				else
				{
					ret = LessThan;
				}
			}
			break;

			case CCalEntry::EAnniv:
			{
				// ...and anniversaries...
				if((type2 == CCalEntry::ETodo) || (type2 == CCalEntry::EEvent))
				{
					ret = GreaterThan;
				}
				else
				{
					ret = LessThan;
				}
			}
			break;

			case CCalEntry::EReminder:
			case CCalEntry::EAppt:
				// ...and finally timed notes.
				ret = GreaterThan;
				break;

			default:
				ASSERT(EFalse);
		}
	}

	return ret;
}

int AgendaUtilPrivate::compareToDos(
		const CCalEntry& aEntry1, const CCalEntry& aEntry2)
{
    int ret( Equal );
    CCalEntry::TStatus status1 = aEntry1.StatusL();
    CCalEntry::TStatus status2 = aEntry2.StatusL();

    if( status1 == CCalEntry::ENullStatus )
        {
        status1 = CCalEntry::ETodoNeedsAction;
        }

    if( status2 == CCalEntry::ENullStatus )
        {
        status2 = CCalEntry::ETodoNeedsAction;
        }

    if( status1 == status2 )
        {
        TTime time1 = aEntry1.EndTimeL().TimeUtcL();
        TTime time2 = aEntry2.EndTimeL().TimeUtcL();

        if( time1 == time2 )
            {
            const TUint pri1( aEntry1.PriorityL() );
            const TUint pri2( aEntry2.PriorityL() );

            if( pri1 == pri2 )
                {
                time1 = aEntry1.LastModifiedDateL().TimeUtcL();
                time2 = aEntry2.LastModifiedDateL().TimeUtcL();

                if( time1 == time2 )
                    {
                    ret = Equal;
                    }
                else if( time1 > time2 )
                    {
                    ret = GreaterThan; // oldest first
                    }
                else
                    {
                    ret = LessThan;
                    }
                }
            else
                {
                if( pri1 > pri2 )
                    {
                    ret = GreaterThan;
                    }
                else
                    {
                    ret = LessThan;
                    }
                }
            }
        else
            {
            if( time1 > time2 )
                {
                ret = GreaterThan;
                }
            else
                {
                ret = LessThan;
                }
            }
        }
    else
        {
        if( status1 == CCalEntry::ETodoCompleted )
            {
            ret = GreaterThan;
            }
        else
            {
            ret = LessThan;
            }
        }

    return ret;
}

int AgendaUtilPrivate::compareNonTimedNotes( const CCalInstance& aInstance1,
                                              const CCalInstance& aInstance2 )
{
    int ret( Equal );
    TTime time1 = aInstance1.Time().TimeUtcL();
    TTime time2 = aInstance2.Time().TimeUtcL();

    if( time1 == time2 )
        {
        time1 = aInstance1.Entry().LastModifiedDateL().TimeUtcL();
        time2 = aInstance2.Entry().LastModifiedDateL().TimeUtcL();

        if( time1 == time2 )
            {
            ret = Equal;
            }
        else if( time1 > time2 )
            {
            ret = GreaterThan; // oldest first
            }
        else
            {
            ret = LessThan;
            }
        }
    else
        {
        if( time1 < time2 )
            {
            ret = LessThan;
            }
        else
            {
            ret = GreaterThan;
            }
        }

    return ret;
}

int AgendaUtilPrivate::compareTimedNotes( const CCalInstance& aInstance1,
                                           const CCalInstance& aInstance2 )
{
    int ret( Equal );
    TTime time1 = aInstance1.Time().TimeUtcL();
    TTime time2 = aInstance2.Time().TimeUtcL();

    if( time1 == time2 )
        {
        TTimeIntervalMinutes duration1;
        TTimeIntervalMinutes duration2;
        aInstance1.EndTimeL().TimeUtcL().MinutesFrom( aInstance1.StartTimeL().TimeUtcL(), duration1 );
        aInstance2.EndTimeL().TimeUtcL().MinutesFrom( aInstance2.StartTimeL().TimeUtcL(), duration2 );

        if( duration1 == duration2 )
            {
            time1 = aInstance1.Entry().LastModifiedDateL().TimeUtcL();
            time2 = aInstance2.Entry().LastModifiedDateL().TimeUtcL();

            if( time1 == time2 )
                {
                ret = Equal;
                }
            else if( time1 > time2 )
                {
                ret = GreaterThan; // oldest first
                }
            else
                {
                ret = LessThan;
                }
            }
        else
            {
            if( duration1 < duration2 )
                {
                ret = LessThan;
                }
            else
                {
                ret = GreaterThan;
                }
            }
        }
    else
        {
        if( time1 < time2 )
            {
            ret = LessThan;
            }
        else
            {
            ret = GreaterThan;
            }
        }

    return ret;
}

RepeatIndex AgendaUtilPrivate::getRepeatIndex(const CCalEntry& aEntry)
{
	RepeatIndex repeatIndex(notRepeated);

	TCalRRule rrule;

	if (aEntry.GetRRuleL(rrule)) {
		TCalRRule::TType type(rrule.Type());
		TInt repeatInterval(rrule.Interval());

		// If repeat type of current note is not supported in Calendar,
		// default repeat value is "Other".
		repeatIndex = repeatOther;

		switch (type) {
			case TCalRRule::EDaily: {
				switch (repeatInterval) {
					case 1:
						repeatIndex = repeatDaily;
						break;
					case 7:
						repeatIndex = repeatWeekly;
						break;
					case 14:
						repeatIndex = repeatBiWeekly;
						break;
					default:
						break;
				}
				break;
			}

			case TCalRRule::EWeekly: {
				AgendaRepeatRule agendaRepeatRule =
				        createAgendaRRuleFromTCalRRule(rrule);
				bool isWorkdaysRepeating =
				        isWorkdaysRepeatingEntry(agendaRepeatRule);

				if (isWorkdaysRepeating) {
					repeatIndex = repeatWorkdays;
				} else {
					RArray<TDay> weekDays(7);
					rrule.GetByDayL(weekDays);
					if (weekDays.Count() == 1) // FIXME: AL - is this necessary?
					{
						switch (repeatInterval) {
							case 1:
								repeatIndex = repeatWeekly;
								break;
							case 2:
								repeatIndex = repeatBiWeekly;
								break;
							default:
								break;
						}
					}

					weekDays.Close();
				}
				break;
			}

			case TCalRRule::EMonthly: {
				RArray<TInt> monthDays(31);
				rrule.GetByMonthDayL(monthDays);

				if (monthDays.Count() == 1) // FIXME: AL - is this necessary?
				{
					switch (repeatInterval) {
						case 1:
							repeatIndex = repeatMonthly;
							break;
							// If interval of repeat is 12 months, 
							// every year is shown in Note Editor, 
							// because it means yearly repeat.
						case 12:
							repeatIndex = repeatYearly;
							break;
						default:
							break;
					}
				}

				monthDays.Close();

				break;
			}
			case TCalRRule::EYearly: {
				if (repeatInterval == 1) {
					repeatIndex = repeatYearly;
				}
				break;
			}

			default: {
				// If repeat type of current note is not supported in Calendar,
				// default repeat value is "Other".
				repeatIndex = repeatOther;
				break;
			}
		}
	}
	return repeatIndex;
}

TTime AgendaUtilPrivate::getPreviousInstanceForRepeatOther(CCalEntry& entry, 
									const CalCommon::TCalTimeRange& timeRange)
{
	RPointerArray<CCalInstance> allInstances;
	CleanupResetAndDestroyPushL(allInstances);
	
	TInt filter;
	// Get the entry type to be filtered
	switch(entry.EntryTypeL())
		{
		case CCalEntry::EAppt:
			filter = CalCommon::EIncludeAppts;
			break;
		case CCalEntry::ETodo:
			filter = CalCommon::EIncludeCompletedTodos | CalCommon::EIncludeIncompletedTodos;
			break;
		case CCalEntry::EEvent:
			filter = CalCommon::EIncludeEvents;
			break;
		case CCalEntry::EReminder:
			filter = CalCommon::EIncludeReminder;
			break;
		case CCalEntry::EAnniv:
			filter = CalCommon::EIncludeAnnivs;
			break;
		default:
			filter = CalCommon::EIncludeAll;
			break;
		};

	iCalInstanceView->FindInstanceL( allInstances, 
									 (CalCommon::TCalViewFilterFlags)filter,
									 timeRange);

	TTime previousTime = Time::NullTTime();
	
	for( TInt i = allInstances.Count() - 1; i >= 0; i-- )
		{
		if( allInstances[i]->Entry().UidL() == entry.UidL() )
			{
			previousTime = allInstances[i]->Time().TimeLocalL();
			break;
			}
		}

	CleanupStack::PopAndDestroy( &allInstances );  
	return previousTime;
}

TTime AgendaUtilPrivate::getNextInstanceForRepeatOther(CCalEntry& aEntry, 
								   const CalCommon::TCalTimeRange& timeRange)
{
	RPointerArray<CCalInstance> allInstances;
	CleanupResetAndDestroyPushL(allInstances);
    
    TInt filter;
    // Get the entry type to be filtered
    switch(aEntry.EntryTypeL())
        {
    	case CCalEntry::EAppt:
    		filter = CalCommon::EIncludeAppts;
    		break;
    	case CCalEntry::ETodo:
    		filter = CalCommon::EIncludeCompletedTodos | CalCommon::EIncludeIncompletedTodos;
    		break;
    	case CCalEntry::EEvent:
    		filter = CalCommon::EIncludeEvents;
    		break;
    	case CCalEntry::EReminder:
    		filter = CalCommon::EIncludeReminder;
    		break;
    	case CCalEntry::EAnniv:
    		filter = CalCommon::EIncludeAnnivs;
    		break;
    	default:
    		filter = CalCommon::EIncludeAll;
    		break;
        };
    
    iCalInstanceView->FindInstanceL( allInstances, 
                                     (CalCommon::TCalViewFilterFlags)filter,
                                     timeRange);
                                     
    TTime nextTime = Time::NullTTime();
    
	TInt i( 0 );
    for( ; i < allInstances.Count(); i++ )
        {
        if( allInstances[i]->Entry().UidL() == aEntry.UidL() )
            {
            nextTime = allInstances[i]->Time().TimeLocalL();
            break;
            }
        }
  
    CleanupStack::PopAndDestroy( &allInstances );  
    return nextTime;
}

TCalTime AgendaUtilPrivate::generateRecurrenceIdFromEntry( CCalEntry& entry, 
														TCalTime instanceDate )
{    
    TDateTime theTime = entry.StartTimeL().TimeUtcL().DateTime();
    TDateTime theDate = instanceDate.TimeUtcL().DateTime();

    theTime.SetYear(theDate.Year());
    theTime.SetMonth(theDate.Month());
    theTime.SetDay(theDate.Day());

    TCalTime toRet;
    toRet.SetTimeUtcL(theTime);
    
    return toRet;
}

bool AgendaUtilPrivate::endsAtStartOfDay( CCalInstance* instance,
                                          const TTime& day )
{
	TTime zero(TInt64(0));
	TTime dayStart = zero + day.DaysFrom( zero );
    const TTime startTime( instance->StartTimeL().TimeLocalL());
    const TTime endTime( instance->EndTimeL().TimeLocalL());

    const bool result( endTime > startTime && endTime == dayStart );

    return result;
}
	
AgendaRepeatRule AgendaUtilPrivate::createAgendaRRuleFromTCalRRule(
															TCalRRule &calRRule)
{
	AgendaRepeatRule agendaRepeatRule;
	RArray<TDay> days;
	calRRule.GetByDayL(days);
	QList<AgendaRepeatRule::Day> qDays;
	for (int i = 0; i < days.Count(); i++) {
		qDays.append(AgendaRepeatRule::Day(days[i]));
	}
	agendaRepeatRule.setByDay(qDays);

	RArray<TMonth> months;
	calRRule.GetByMonthL(months);
	QList<AgendaRepeatRule::Month> qMonths;
	for (int i = 0; i < months.Count(); i++) {
		qMonths.append(AgendaRepeatRule::Month(months[i]));
	}
	agendaRepeatRule.setByMonth(qMonths);

	RArray<TInt> monthDays;
	calRRule.GetByMonthDayL(monthDays);
	QList<int> qMonthDays;
	for (int i = 0; i < monthDays.Count(); i++) {
		qMonthDays.append(monthDays[i] + 1);
	}
	agendaRepeatRule.setByMonthDay(qMonthDays);

	agendaRepeatRule.setType((AgendaRepeatRule::RuleType) (calRRule.Type()));
	agendaRepeatRule.setInterval(calRRule.Interval());
	TCalTime time = calRRule.Until();
	TTime untilTime = time.TimeLocalL();
	QDateTime repeatUntil(QDate(untilTime.DateTime().Year(), 
	                     untilTime.DateTime().Month() + 1, 
	                     untilTime.DateTime().Day() + 1),
	                     QTime(untilTime.DateTime().Hour(),
	                     untilTime.DateTime().Minute()));
	agendaRepeatRule.setUntil(repeatUntil);

	TCalTime dayStart = calRRule.DtStart();
	TDateTime ruleStart = dayStart.TimeLocalL().DateTime();
	QDateTime qRuleStart(QDate(ruleStart.Year(), ruleStart.Month() + 1, 
	          ruleStart.Day() + 1),QTime(ruleStart.Hour(), ruleStart.Minute()));
	agendaRepeatRule.setRepeatRuleStart(qRuleStart);

	TDay wkDay = calRRule.WkSt();
	AgendaRepeatRule::Day qWkDay = (AgendaRepeatRule::Day) wkDay;
	agendaRepeatRule.setWeekStart(qWkDay);
	
	return agendaRepeatRule;

}

TCalRRule AgendaUtilPrivate::createTCalRRuleFromAgendaRRule(
												AgendaRepeatRule &agendaRRule, bool isNonFloating )
{
	TCalRRule
	        repeatRule(
	                   static_cast<TCalRRule::TType> (agendaRRule.type()));
	QDateTime ruleStartDateTime = agendaRRule.repeatRuleStart();
	TDateTime ruleStartCalendarDateTime(ruleStartDateTime.date().year(), 
	                 static_cast<TMonth> (ruleStartDateTime.date().month() - 1), 
	                 ruleStartDateTime.date().day() - 1,
	                 ruleStartDateTime.time().hour(),
	                 ruleStartDateTime.time().minute(),
	                 0, 
	                 0);
	
	QDateTime repeatUntilDate = agendaRRule.until();
	TDateTime repeatTill(repeatUntilDate.date().year(), 
	                   static_cast<TMonth> (repeatUntilDate.date().month() - 1),
	                   repeatUntilDate.date().day() - 1, 
	                   repeatUntilDate.time().hour(), 
	                   repeatUntilDate.time().minute(), 
	                   0, 
	                   0);
	
	TCalTime ruleStartCalTime;
	TCalTime ruleRepeatTillTime;
	if(isNonFloating) {
	    // Use Fixed time for timed entries.
	    ruleStartCalTime.SetTimeLocalL(TTime(ruleStartCalendarDateTime));
	    ruleRepeatTillTime.SetTimeLocalL(TTime(repeatTill));
	}else {
	    // Use Floating time for Non timed entries
	    ruleStartCalTime.SetTimeLocalFloatingL(TTime(ruleStartCalendarDateTime));
	    ruleRepeatTillTime.SetTimeLocalFloatingL(TTime(repeatTill));
	}
	repeatRule.SetDtStart(ruleStartCalTime);
	repeatRule.SetInterval(agendaRRule.interval());
	repeatRule.SetUntil(ruleRepeatTillTime);
	repeatRule.SetWkSt((TDay)agendaRRule.weekStart());

	QList<AgendaRepeatRule::Day> qDays = agendaRRule.byDay();
	RArray<TDay> days;
	for (int i = 0; i < qDays.count(); i++) {
		days.Append(TDay(qDays[i]));
	}
	if (days.Count() > 0) {
		repeatRule.SetByDay(days);
	}

	QList<int> qmonthDay = agendaRRule.byMonthDay();
	RArray<TInt> monthDay;
	for (int i = 0; i < qmonthDay.count(); i++) {
		monthDay.Append(qmonthDay[i] - 1);
	}
	if (monthDay.Count() > 0) {
		repeatRule.SetByMonthDay(monthDay);
	}

	QList<AgendaRepeatRule::Month> qMonth = agendaRRule.byMonth();
	RArray<TMonth> month;
	for (int i = 0; i < qMonth.count(); i++) {
		month.Append(TMonth(qMonth[i]));
	}
	if (month.Count() > 0) {
		repeatRule.SetByMonth(month);
	}
	
	return repeatRule;
}

// End of file  --Don't remove this.