/***************************************************************************
                          wpprotocol.cpp  -  WP Plugin
                             -------------------
    begin                : Fri Apr 26 2002
    copyright            : (C) 2002 by Gav Wood
    email                : gav@kde.org

    Based on code from   : (C) 2002 by Duncan Mac-Vicar Prett
    email                : duncan@kde.org
 ***************************************************************************

 ***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

// QT Includes
#include <tqmap.h>
#include <tqdict.h>

// KDE Includes
#include <tdeapplication.h>
#include <kdebug.h>
#include <kgenericfactory.h>
#include <tdemessagebox.h>
#include <tdesimpleconfig.h>
#include <tdestandarddirs.h>

// Kopete Includes
#include "kopeteaccountmanager.h"
#include "kopeteuiglobal.h"

// Local Includes
#include "wpprotocol.h"
#include "wpeditaccount.h"
#include "wpaccount.h"
#include "wpcontact.h"

class TDEPopupMenu;

WPProtocol *WPProtocol::sProtocol = 0;

typedef KGenericFactory<WPProtocol> WPProtocolFactory;
K_EXPORT_COMPONENT_FACTORY( kopete_wp, WPProtocolFactory( "kopete_wp" )  )

// WP Protocol
WPProtocol::WPProtocol( TQObject *parent, const char *name, const TQStringList & /* args */ )
: Kopete::Protocol( WPProtocolFactory::instance(), parent, name ),
	WPOnline(  Kopete::OnlineStatus::Online,  25, this, 0,  TQString(), i18n("Online"),  i18n("Online")),
	WPAway(    Kopete::OnlineStatus::Away,    20, this, 1,  "wp_away",     i18n("Away"),    i18n("Away")),
	WPOffline( Kopete::OnlineStatus::Offline, 0,  this, 2,  TQString(), i18n("Offline"), i18n("Offline"))
{
//	kdDebug(14170) << "WPProtocol::WPProtocol()" << endl;

	sProtocol = this;

	// Load Status Actions
//	initActions();
	// TODO: Maybe use this in the future?

	addAddressBookField( "messaging/winpopup", Kopete::Plugin::MakeIndexField );

	readConfig();

	popupClient = new WinPopupLib(smbClientBin, groupCheckFreq);
	TQObject::connect(popupClient, TQ_SIGNAL(signalNewMessage(const TQString &, const TQDateTime &, const TQString &)),
		this, TQ_SLOT(slotReceivedMessage(const TQString &, const TQDateTime &, const TQString &)));
}

// Destructor
WPProtocol::~WPProtocol()
{
//	kdDebug(14170) <<  "WPProtocol::~WPProtocol()" << endl;

	sProtocol = 0;
}

AddContactPage *WPProtocol::createAddContactWidget(TQWidget *parent, Kopete::Account *theAccount)
{
//	kdDebug(14170) << "WPProtocol::createAddContactWidget(<parent>, " << theAccount << ")" << endl;

	return new WPAddContact(parent, dynamic_cast<WPAccount *>(theAccount));
}

Kopete::Contact *WPProtocol::deserializeContact( Kopete::MetaContact *metaContact,
	const TQMap<TQString, TQString> &serializedData,
	const TQMap<TQString, TQString> & /* addressBookData */ )
{
	TQString contactId = serializedData[ "contactId" ];
	TQString accountId = serializedData[ "accountId" ];

	WPAccount *theAccount = static_cast<WPAccount *>(Kopete::AccountManager::self()->findAccount(protocol()->pluginId(), accountId));
	if(!theAccount)	{
		kdDebug(14170) <<  "Account " << accountId << " not found" << endl;
		return 0;
	}

	if(theAccount->contacts()[contactId]) {
		kdDebug(14170) << "User " << contactId << " already in contacts map" << endl;
		return 0;
	}

	theAccount->addContact(contactId, metaContact, Kopete::Account::DontChangeKABC);
	return theAccount->contacts()[contactId];
}

KopeteEditAccountWidget *WPProtocol::createEditAccountWidget(Kopete::Account *account, TQWidget *parent)
{
	return new WPEditAccount(parent, account);
}

Kopete::Account *WPProtocol::createNewAccount(const TQString &accountId)
{
	return new WPAccount(this, accountId);
}

void WPProtocol::settingsChanged()
{
	kdDebug(14170) <<  "WPProtocol::slotSettingsChanged()" << endl;

	readConfig();
	popupClient->settingsChanged(smbClientBin, groupCheckFreq);
}

void WPProtocol::readConfig()
{
	TDEGlobal::config()->setGroup("WinPopup");
	smbClientBin = TDEGlobal::config()->readEntry("SmbcPath", "/usr/bin/smbclient");
	groupCheckFreq = TDEGlobal::config()->readNumEntry("HostCheckFreq", 60);
}

void WPProtocol::installSamba()
{
//	kdDebug(14170) <<  "WPProtocol::installSamba()" endl;

	TQStringList args;
	args += TDEStandardDirs::findExe("winpopup-install.sh");
	args += TDEStandardDirs::findExe("winpopup-send.sh");
	if (TDEApplication::tdeinitExecWait("tdesu", args) == 0)
		KMessageBox::information(Kopete::UI::Global::mainWidget(), i18n("The Samba configuration file is modified."), i18n("Configuration Succeeded"));
	else
		KMessageBox::error(Kopete::UI::Global::mainWidget(), i18n("Updating the Samba configuration file failed."), i18n("Configuration Failed"));
}

/**
 * search the contact for the new message and give it to its account
 */
void WPProtocol::slotReceivedMessage(const TQString &Body, const TQDateTime &Time, const TQString &From)
{
	bool foundContact = false;
	TQString accountKey = TQString();
	TQDict<Kopete::Account> Accounts = Kopete::AccountManager::self()->accounts(protocol());
	for (TQDictIterator<Kopete::Account> it(Accounts); it.current(); ++it) {
		TQDict<Kopete::Contact> Contacts = it.current()->contacts();
		Kopete::Contact *theContact = Contacts[From];
		if (theContact != 0) {
			foundContact = true;
			dynamic_cast<WPAccount *>(it.current())->slotGotNewMessage(Body, Time, From);
			break;
		}

		if (accountKey.isEmpty() && it.current()->isConnected()) accountKey = it.currentKey();
	}

	// What to do with messages with no contact?
	// Maybe send them to the next online account? GF
	if (!foundContact) {
		if (!accountKey.isEmpty())
			dynamic_cast<WPAccount *>(Accounts[accountKey])->slotGotNewMessage(Body, Time, From);
		else
			kdDebug(14170) << "No contact or connected account found!" << endl;
	}
}

void WPProtocol::sendMessage(const TQString &Body, const TQString &Destination)
{
	popupClient->sendMessage(Body, Destination);
}

#include "wpprotocol.moc"
