/***************************************************************************
                          clientmanager.cpp  -  description
                             -------------------
    begin                : Sat Feb 14 2003
    copyright            : (C) 2003 by Simone Gotti
	
	from the threaded konnector of Mathias Froehlich <Mathias.Froehlich@web.de>
	
    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 <qobject.h>
#include <qapplication.h>
#include <qthread.h>
#include <kdebug.h>

#include "obexclient.h"
#include "calendarthread.h"
#include "addressbookthread.h"
#include "clientmanager.h"

using namespace KSync;

/**
   Constructor with the usual parent handling.
*/
ClientManager::ClientManager(SyncType type, const IrMCSyncHelper::Device::Model phoneModel, QObject* parent, const char* name )
		: QObject( parent, name )
{
	if(type == CalendarSync) {
		kdDebug() << "Creating a CalendarThread. " << endl;
		mWorker = new CalendarThread( phoneModel, this );
	} else if(type == AddressBookSync) {
		kdDebug() << "Creating a AddressBookThread. " << endl;
		mWorker = new AddressBookThread( phoneModel, this );
	}

	//mWorker->mLock.lock();
	//start();
}

/**
   Destructor, make sure that the thread terminated.
*/
ClientManager::~ClientManager()
{
	// Terminate the worker thread if required.
/*	if ( !finished() ) {
		// Tell the thread to terminate ...
		terminateThread();
		// ... and give it 5 seconds to terminate.
		if ( !wait( 5000 ) ) {
			// If it has not worked, try the hard way ...
			terminate();
			wait();
		}
	}*/
}

/**
   Worker function of QThread.
   It runs the requests and posts events.
*/
void ClientManager::run()
{
	// Call the real working routine.
	//mWorker->run();
}

void ClientManager::setObexClient(Client* obexClient)
{
	// Call the real working routine.
	mWorker->setObexClient(obexClient);
}

/**
   Returns if the worker is idel at the monment.
   Since we have only one manager this lock free access does not introduce
   a race condition.
*/
bool ClientManager::isIdle()
{
	return !mWorker->mLock.locked();
}

/**
   Starts reading the device and computing the synccees.
   Returns if a backup could be started. If the function returns with true
   the job is terminated by by either a @ref signalError( const KSync::Error& )
   or a @ref signalFinished( const KSync::Progress& ).
*/
bool ClientManager::readSyncees()
{
	//mWorker->mLock.lock();
	kdDebug() << "ClientManager::readSyncees(): OK!!! " << endl;
	mWorker->mCommand = ClientThread::ReadSyncees;
	mWorker->run();
	//mWorker->mLock.unlock();
	//mWorker->mWait.wakeOne();
	return true;
}

/**
   Starts writing the syncees to the device.
   Returns if a backup could be started. If the function returns with true
   the job is terminated by by either a @ref signalError( const KSync::Error& )
   or a @ref signalFinished( const KSync::Progress& ).
*/
bool ClientManager::writeSyncees()
{
	//mWorker->mLock.lock();
	kdDebug() << "ClientManager::writeSyncees(): OK!!! " << endl;
	mWorker->mCommand = ClientThread::WriteSyncees;
	mWorker->run();
	//mWorker->mLock.unlock();
	//mWorker->mWait.wakeOne();
	return true;
}

/**
   Terminates ...
*/
bool ClientManager::terminateThread()
{
	//mWorker->mCancel = true;
	//mWorker->mLock.lock();
	mWorker->mCommand = ClientThread::TerminateThread;
	mWorker->run();
	//mWorker->mLock.unlock();
	//mWorker->mWait.wakeOne();
	return true;
}

/**
   Sets a flag in the client thread. We hope, that the worker thread
   regularly reads that flag ...
*/
void ClientManager::cancelJob()
{
	mWorker->mCancel = true;
}

/**
   Called by QObject to report that an event has arrived.
*/
void ClientManager::customEvent( QCustomEvent* ce )
{
	if ( ce->type() == QEvent::Type( ClientThread::TerminatedEvent ) ) {
		// Make sure that we are really done ...
		wait();
		// ...
		emit signalTerminated();
		mWorker->mLock.unlock();
	} else if ( ce->type() == QEvent::Type( ClientThread::SynceeReadedEvent ) ) {
		KSync::Syncee* s = static_cast<KSync::Syncee *>( ce->data() );
		if ( s )
			emit signalSynceeReaded( s );
	} else if ( ce->type() == QEvent::Type( ClientThread::SynceeWritedEvent ) ) {
		emit signalSynceeWrited();
	}
}

#include "clientmanager.moc"
