/*
* dropman.cpp -- Implementation of class KDropManager.
* Author:	Sirtaj Singh Kang
* Version:	$Id: dropman.cpp,v 1.2 1999/08/12 19:26:03 bieker Exp $
* Generated:	Fri May  1 19:33:10 EST 1998
*/

#include<assert.h>
#include<stdlib.h>
#include<qstring.h>

#include<kglobal.h>
#include<klocale.h>
#include<qmessagebox.h>
#include<kconfigbase.h>

#include"dropman.h"
#include"unixdrop.h"
#include"qmail.h"
#include"pop.h"
#include"news.h"
#include"imap.h"
#include"edrop.h"

KDropManager::KDropManager()
{
	_types	=	new QStrList;
	_prototypes =	new QDict<KMailDrop>;
	_prototypes->setAutoDelete( true );

	_monitors=	new QList<KMailDrop>;
	_monitors->setAutoDelete( true );

	addPrototype( new KUnixDrop );
	addPrototype( new KQMailDrop );
	addPrototype( new KPop3Drop );
	addPrototype( new KImap4Drop );
	addPrototype( new KNewsDrop );
	addPrototype( new KExternDrop );
}

KDropManager::~KDropManager()
{
	delete _prototypes;
	delete _types;
	delete _monitors;
}

bool KDropManager::readOldConfig( KConfigBase& config, const char *group )
{
	KConfigGroupSaver save( &config, group );

	// split box names up
	QStrList boxes;
	int boxcount = config.readListEntry( BoxConfigKey, boxes, 
			',' );

	if( boxcount <= 0 ) {
		return false;
	}

	// read and create boxes;
	QString type;
	QString grp;
	QString defAudio = config.readEntry( "audio", "");
	QString defCmd = config.readEntry( "command", "");

	int defPoll = KPollableDrop::DefaultPoll;

	if( config.hasKey( "polltime" ) ) {
		defPoll = config.readNumEntry( "polltime", 
			KPollableDrop::DefaultPoll );
	}
	

	for( const char *box = boxes.first(); 
			box != 0; box = boxes.next() ) {
		// new monitor
		debug( "Configuring old mailbox: %s", box );
		KUnixDrop *drop = (KUnixDrop *)newMonitor( "mbox" );

		if( drop == 0 ) {
			warning( "KDropManager::readOldConfig: creation "
				"of unix box failed." );
			continue;
		}

		// configure
		config.setGroup( box );

		if( config.hasKey( "box" ) ) {
			drop->setFile( config.readEntry( "box" )  );
		}

		drop->setCaption( config.readEntry( "Name", 
				i18n("MBOX Monitor") ) );

		drop->setNewmailCmd( config.readEntry( "audio", defAudio ) );
		drop->setClickCmd( config.readEntry( "command", defCmd ) );
		drop->setFreq( config.readNumEntry( "polltime", defPoll ) );
	}

	return true;
}

bool KDropManager::readConfig( KConfigBase& config, const char *group )
{
	KConfigGroupSaver save( &config, group );

	// check if new config system works
	if( !config.hasKey( BoxNumConfigKey ) ) {
		return readOldConfig( config, group );
	}

	// split box names up
	int boxcount = config.readNumEntry( BoxNumConfigKey );

	if( boxcount <= 0 ) {
		return false;
	}

	// read and create boxes;
	QString type;
	QString grp;
	QString c;

	for( int count = 0; count < boxcount; count++ ) {

		// get type
		grp = "box-";
		c.setNum( count );
		grp += c;

		config.setGroup( grp );
		type = config.readEntry( "type" );

		if ( type.isEmpty() ) {
			warning( "KDropManager::readConfig: "
					"box %d has no type.", count );	

			continue;
		}

		// new monitor
		KMailDrop *drop = newMonitor( type );

		if( drop == 0 ) {
			warning( "KDropManager::readConfig: creation of %s box "
					"failed.", type.data() );
			continue;
		}

		drop->readConfigGroup( config );
	}

	return true;
}

bool KDropManager::writeConfig( KConfigBase& config, 
	const char *group ) const
{
	assert( group );

	KConfigGroupSaver ( &config, group );

	QListIterator<KMailDrop> iter( *_monitors );

	QString grp;
	QString boxes = "";

	int count = 0;
	QString c;

	for( ; iter.current(); ++iter ) {
		boxes += iter.current()->caption();
		boxes += BoxConfigSep;

		grp = "box-";
		c.setNum( count++ );
		grp += c;

		config.setGroup( grp );

		iter.current()->writeConfigGroup( config );

	}

	config.setGroup( group );
	config.writeEntry( BoxNumConfigKey, count );
	config.sync();
	return true;
}

bool KDropManager::createBasicConfig()
{
	KUnixDrop *drop = (KUnixDrop *)newMonitor( "mbox" );

	drop->setCaption( i18n("Inbox") );

	// find mailbox
	const char *s = getenv( "MAIL" );

	if( s == 0 ) {
		QMessageBox::warning( 0, i18n( "Can't find mailbox" ), 
			i18n( "Unable to find $MAIL environment variable. "
			"You'll have to configure the mailboxes yourself." ),
			i18n( "OK" ));
	}
	else {
		drop->setFile( s );
	}

	return true;
}

KMailDrop *KDropManager::newMonitor( const char *type )
{
	assert( type );

	KMailDrop *proto = _prototypes->find( type );

	if( !proto ) {
		return 0;
	}

	KMailDrop *newdrop = proto->clone();

	if( newdrop != 0 ) {
		_monitors->append( newdrop );
		connect( newdrop, SIGNAL(configChanged()),
			this, SLOT(raiseConfig()) );
	}

	emit monitorCreated();

	return newdrop;
}

KMailDrop *KDropManager::cloneMonitor( const KMailDrop *monitor )
{
	assert( monitor );

	// clone monitor

	KMailDrop *newdrop = monitor->clone();

	if( newdrop == 0 ) {
		warning( "cloneMonitor: couldn't clone %s.",
				monitor->caption().ascii() );
		return 0;
	}

	// register 

	_monitors->append( newdrop );
	connect( newdrop, SIGNAL(configChanged()),
			this, SLOT(raiseConfig()) );

	// append " (clone)" to the caption to keep it
	// legal.

	QString caption = newdrop->caption();
	caption += i18n( " (clone)" );
	newdrop->setCaption( caption );

	emit monitorCreated();

	return newdrop;
}

bool KDropManager::deleteMonitor( KMailDrop *monitor )
{
	// disconnect clients
	monitor->notifyClients();

	// delete monitor
	if( _monitors->removeRef( monitor ) == false ) {
		return false;
	}

	emit monitorDeleted();

	return true;
}

void KDropManager::addPrototype( const KMailDrop *p )
{
	_prototypes->insert( p->type(), p );
	_types->append( p->type() );
}

void KDropManager::raiseConfig()
{
	emit configChanged();
}

const char *KDropManager::BoxConfigKey = "boxes";
const char *KDropManager::BoxNumConfigKey = "numboxes";
const char KDropManager::BoxConfigSep = '|';
