/***************************************************************************
                          calendarthread.cpp  -  description
                             -------------------
    begin                : Sat Feb 14 2003
    copyright            : (C) 2003 by Simone Gotti
    email                : simone.gotti@email.it
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
 
#include <kdebug.h>
#include <klocale.h>

#include <qregexp.h>
#include <qfile.h>
#include <qdir.h>

#include <libkcal/calendarlocal.h>
#include <libkcal/vcalformat.h>

#include <libkdepim/kpimprefs.h>

#include <idhelper.h>

#include "calendarthread.h"
#include "changelog.h"
#include "device.h"


using namespace KSync;
using namespace KCal;


/**
   Constructor.
*/
CalendarThread::CalendarThread( const IrMCSyncHelper::Device::Model phoneModel, QObject* reciver )
		: IrMCSyncThreadBase("calendar", "cal", "vcs", phoneModel, reciver )
{
	mSyncee = new CalendarSyncee(new KCal::CalendarLocal(KPimPrefs::timezone()));
	mSyncee->setTitle( i18n( "IrMCSync" ) );
  mSyncee->setMerger( mDeviceHelper->merger( IrMCSyncHelper::Device::Calendar ) );
}

/**
   Destructor.
*/
CalendarThread::~CalendarThread()
{
	delete mSyncee;
}

KSync::Syncee* CalendarThread::rawDataToSyncee(QByteArray data, QStringList& XIRMCLUIDs)
{
	kdDebug() << "rawDataToSyncee()" << endl;
	CalendarLocal *tmpCalendar = new CalendarLocal(KPimPrefs::timezone());	
	//tmpCalendar->setLocalTime();
	KSync::CalendarSyncee* syncee = new KSync::CalendarSyncee(tmpCalendar);
	// Get the X-IRMC-LUID
	QStringList fullCalendarStrings;

	QTextStream changelogStream(data, IO_ReadOnly);
	QString tmp;
	while ((tmp = changelogStream.readLine()) != QString::null)
		fullCalendarStrings.append(tmp);

	QRegExp rxp("^X-IRMC-LUID:");
	QStringList matchingStrings = fullCalendarStrings.grep(rxp);
	QStringList::Iterator matchingStringsIt;
	for ( matchingStringsIt = matchingStrings.begin(); matchingStringsIt != matchingStrings.end(); ++matchingStringsIt )
		XIRMCLUIDs.append((*matchingStringsIt).section(rxp, 1));

	// Convert the QByteArray in the Vcal format
	QString tempFileName = databaseDir + "/" + "temp-vcal";
	QFile file(tempFileName);
	file.open( IO_WriteOnly );
	file.writeBlock (data);
	file.close();

	KCal::CalendarLocal *tempCalendar = new KCal::CalendarLocal(KPimPrefs::timezone());
	// vcal->fromString DOESN'T WORK (it crashes!!!)!!!
	// We have to create a temporary file and convert the vcal from it...
	//vcal->fromString( tempCalendar, dataString );
	//tempCalendar->setLocalTime();
	tempCalendar->load( tempFileName );
	
	/*Get All the events from the received calendar: They are only 1 !!! */
	Incidence::List incidencesList = tempCalendar->incidences();
	Incidence::List::Iterator it;
	kdDebug() << "There are " << incidencesList.size() << " events" << endl;


	QString LUID, Uid, dstFileName;
	QStringList::Iterator XIRMCLUIDsIt = XIRMCLUIDs.begin();
	for ( it = incidencesList.begin(); it != incidencesList.end(); ++it ) {
		// Get the associated LUID
		if(XIRMCLUIDsIt == XIRMCLUIDs.end()) {
			kdDebug() << "Error: More Events then LUIDs!!!" << endl;
		}
		//Save the entry in the serialnumber/database dir.
		QString LUID, Uid, dstFileName;
		LUID = (*XIRMCLUIDsIt);
		
		// We check if there's a local file with the same LUID,
		// this is needed as the creation time of the received entry 
		// is setted to NOW (due to the calendar conversion we do, saving the data
		// to a file and the reading it) while we need to set to it's real creation time.
		Uid = uidHelper->kdeId(appName, LUID);
		dstFileName = GenerateFullPathFileName(LUID);
		if(QFile::exists(dstFileName)) {
			// If the file exists We have to extract the createdvalue() as it's changed by the tempCalendar->load( tempFileName )
			kdDebug() << "Reading Creation Time. " << endl;
			KCal::CalendarLocal *tmpCalendar = new KCal::CalendarLocal(KPimPrefs::timezone());
			//tmpCalendar->setLocalTime();
			tmpCalendar->load( databaseDir + "/" + dstFileName);
			Incidence::List list = tmpCalendar->incidences();
			Incidence::List::Iterator incidenceIt;

			if((incidenceIt = list.begin()) != list.end()) {
				//Get the created() value;
				QDateTime created = (*incidenceIt)->created();
				(*incidenceIt)->setCreated(created);

				kdDebug() << "Creation Time= " << created << endl;
			}
			
			// We have to set the Uid to the local Uid and NOT the device LUID!!!
			(*it)->setUid(Uid);
		} else {
			// If there's no an existing entry we can choose like local Uid 
			// the same value of the "IrMCSyncKonnector-" + LUID
			Uid = "IrMCSyncKonnector-" + LUID;
			(*it)->setUid(Uid);
			uidHelper->addId(appName, LUID, Uid);
			uidHelper->save();
		}

		KSync::CalendarSyncEntry* entry = new KSync::CalendarSyncEntry(*it , mSyncee);
		syncee->addEntry(entry);
		
		XIRMCLUIDsIt++;
	}

	return syncee;
}

QByteArray CalendarThread::syncEntryToRawData(KSync::SyncEntry* entry, QString& Uid)
{
	kdDebug() << "CalendarThread::syncEntryToRawData() " << endl;

  KCal::Incidence *incidence = ((KSync::CalendarSyncEntry*)entry)->incidence();
	Uid = incidence->uid();

	KCal::CalendarLocal *tempCalendar = new KCal::CalendarLocal(KPimPrefs::timezone());

	tempCalendar->addIncidence( incidence );
	
	QString tempFileName = databaseDir + "/" + "temp-vcal-2";
	tempCalendar->save(tempFileName, new VCalFormat);

	QByteArray data;
	QFile file(tempFileName);
	file.open(IO_ReadOnly);
	data = file.readAll();
	file.close();

	return data;
}

KSync::Syncee* CalendarThread::localGetEntry(const QString& path)
{
	kdDebug() << "CalendarThread::localGetEntry() " << endl;

	KSync::CalendarSyncee* syncee = new KSync::CalendarSyncee(new KCal::CalendarLocal(KPimPrefs::timezone()));
	KCal::CalendarLocal *tmpCalendar = new KCal::CalendarLocal(KPimPrefs::timezone());
	tmpCalendar->load(path);
	Incidence::List incidencesList = tmpCalendar->incidences();
	Incidence::List::Iterator it;

	if((it = incidencesList.begin()) != incidencesList.end()) {
		KSync::CalendarSyncEntry* entry = new KSync::CalendarSyncEntry(*it, mSyncee);
		kdDebug() << "dtStartTimeStr: " << entry->incidence()->dtStartTimeStr() << endl;
		syncee->addEntry(entry);
	}
	return syncee;
}

void CalendarThread::localPutEntry(KSync::SyncEntry* entry, const QString& path)
{
	KCal::CalendarLocal *tempCalendar = new KCal::CalendarLocal(KPimPrefs::timezone());
	KSync::CalendarSyncee* syncee = new KSync::CalendarSyncee(tempCalendar);
	syncee->addEntry(entry);
		
	kdDebug() << "Saving: " << path << endl;
	tempCalendar->save(path, new VCalFormat);
}


#include "calendarthread.moc"
