/*
    ircprotocol.h - IRC Protocol

    Copyright (c) 2002      by Nick Betcher <nbetcher@kde.org>

    Kopete    (c) 2002-2004 by the Kopete developers <kopete-devel@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.                                   *
    *                                                                       *
    *************************************************************************
*/

#ifndef IRCPROTOCOL_H
#define IRCPROTOCOL_H

#include "kopeteonlinestatus.h"
#include "kopeteprotocol.h"
#include "kopetecontactproperty.h"
#include "kopetemimetypehandler.h"

#include <dom/dom_node.h>
#include <tqdict.h>

#define m_protocol (IRCProtocol::protocol())

namespace Kopete
{
class Account;
class MetaContact;
}

class AddContactPage;

class EditAccountWidget;
class IRCAccount;

class TQStringList;
class TQWidget;
class KopeteView;

class IRCNetwork;
class IRCHost;
class NetworkConfig;

class IRCProtocolHandler : public Kopete::MimeTypeHandler
{
	public:

		IRCProtocolHandler();

		void handleURL( const KURL &url ) const;
};

static const TQString CHAT_VIEW( TQString::fromLatin1("kopete_chatwindow") );

/**
 * @author Nick Betcher <nbetcher@kde.org>
 */
class IRCProtocol : public Kopete::Protocol
{
	TQ_OBJECT
  

public:
	enum IRCStatus
	{
		Offline        = 1,                 //! An offline user.
		Connecting     = 2,                 //! User that is connecting.
		Away           = 4,                 //! User that is away. May be regular user, voiced user or (server) operator.
		Online         = 8,                 //! This user is online.
		Voiced         = 16,                //! This user is voiced.
		Operator       = 32,                //! This user is a channel operator.
		ServerOperator = 1024,              //! This user is a server operator.
		OfflineChannel = 4096,              //! This channel is offline.
		OnlineChannel  = 8192,              //! This channel is online.
		OfflineServer  = 16384,             //! This server is offline.
		OnlineServer   = 32768              //! This server is online.
	};

	IRCProtocol( TQObject *parent, const char *name, const TQStringList &args );
	~IRCProtocol();

	/** Kopete::Protocol reimplementation */
	virtual AddContactPage *createAddContactWidget(TQWidget *parent, Kopete::Account *account);

	/**
	 * Deserialize contact data
	 */
	virtual Kopete::Contact *deserializeContact( Kopete::MetaContact *metaContact,
		const TQMap<TQString, TQString> &serializedData, const TQMap<TQString, TQString> &addressBookData );

	virtual KopeteEditAccountWidget* createEditAccountWidget(Kopete::Account *account, TQWidget *parent);

	virtual Kopete::Account* createNewAccount(const TQString &accountId);

	virtual TQPtrList<TDEAction> *customChatWindowPopupActions( const Kopete::Message &, DOM::Node & );

	static IRCProtocol *protocol();

	/**
	 * Maps the given IRC status to Kopete::OnlineStatus.
	 */
	const Kopete::OnlineStatus statusLookup( IRCStatus status ) const;

	const Kopete::OnlineStatus m_ServerStatusOnline;
	const Kopete::OnlineStatus m_ServerStatusOffline;

	const Kopete::OnlineStatus m_ChannelStatusOnline;
	const Kopete::OnlineStatus m_ChannelStatusOffline;

	const Kopete::OnlineStatus m_UserStatusOpVoice;
	const Kopete::OnlineStatus m_UserStatusOpVoiceAway;
	const Kopete::OnlineStatus m_UserStatusOp;
	const Kopete::OnlineStatus m_UserStatusOpAway;
	const Kopete::OnlineStatus m_UserStatusVoice;
	const Kopete::OnlineStatus m_UserStatusVoiceAway;
	const Kopete::OnlineStatus m_UserStatusOnline;
	const Kopete::OnlineStatus m_UserStatusAway;
	const Kopete::OnlineStatus m_UserStatusConnecting;
	const Kopete::OnlineStatus m_UserStatusOffline;

	const Kopete::OnlineStatus m_StatusUnknown;

	// irc channnel-contact properties
	const Kopete::ContactPropertyTmpl propChannelTopic;
	const Kopete::ContactPropertyTmpl propChannelMembers;
	const Kopete::ContactPropertyTmpl propHomepage;

	// irc user-contact properties
	const Kopete::ContactPropertyTmpl propLastSeen;
	const Kopete::ContactPropertyTmpl propUserInfo;
	const Kopete::ContactPropertyTmpl propServer;
	const Kopete::ContactPropertyTmpl propChannels;
	const Kopete::ContactPropertyTmpl propHops;
	const Kopete::ContactPropertyTmpl propFullName;
	const Kopete::ContactPropertyTmpl propIsIdentified;

	bool commandInProgress(){ return m_commandInProgress; }
	void setCommandInProgress( bool ip ) { m_commandInProgress = ip; }

	TQDict<IRCNetwork> &networks(){ return m_networks; }
	void addNetwork( IRCNetwork *network );

	void editNetworks( const TQString &networkName = TQString() );

signals:
	void networkConfigUpdated( const TQString &selectedNetwork );

private slots:
	// FIXME: All the code for managing the networks list should be in another class - Will
	void slotUpdateNetworkConfig();
	void slotUpdateNetworkHostConfig();
	void slotMoveServerUp();
	void slotMoveServerDown();
	void slotSaveNetworkConfig();
	void slotReadNetworks();
	void slotDeleteNetwork();
	void slotDeleteHost();
	void slotNewNetwork();
	void slotRenameNetwork();
	void slotNewHost();
	void slotHostPortChanged( int value );
	// end of network list specific code

	void slotMessageFilter( Kopete::Message &msg );

	void slotRawCommand( const TQString &args, Kopete::ChatSession *manager );
	void slotQuoteCommand( const TQString &args, Kopete::ChatSession *manager );
	void slotCtcpCommand( const TQString &args, Kopete::ChatSession *manager );
	void slotPingCommand( const TQString &args, Kopete::ChatSession *manager );

	void slotMotdCommand( const TQString &args, Kopete::ChatSession *manager);
	void slotListCommand( const TQString &args, Kopete::ChatSession *manager);
	void slotTopicCommand( const TQString &args, Kopete::ChatSession *manager);
	void slotJoinCommand( const TQString &args, Kopete::ChatSession *manager);
	void slotNickCommand( const TQString &args, Kopete::ChatSession *manager);
	void slotWhoisCommand( const TQString &args, Kopete::ChatSession *manager);
	void slotWhoWasCommand( const TQString &args, Kopete::ChatSession *manager);
	void slotWhoCommand( const TQString &args, Kopete::ChatSession *manager);
	void slotMeCommand( const TQString &args, Kopete::ChatSession *manager);
	void slotAllMeCommand( const TQString &args, Kopete::ChatSession *manager);
	void slotModeCommand( const TQString &args, Kopete::ChatSession *manager);
	void slotQueryCommand( const TQString &args, Kopete::ChatSession *manager);

	void slotKickCommand( const TQString &args, Kopete::ChatSession *manager);
	void slotBanCommand( const TQString &args, Kopete::ChatSession *manager);
	void slotOpCommand( const TQString &args, Kopete::ChatSession *manager);
	void slotDeopCommand( const TQString &args, Kopete::ChatSession *manager);
	void slotVoiceCommand( const TQString &args, Kopete::ChatSession *manager);
	void slotDevoiceCommand( const TQString &args, Kopete::ChatSession *manager);
	void slotQuitCommand( const TQString &args, Kopete::ChatSession *manager);
	void slotPartCommand( const TQString &args, Kopete::ChatSession *manager);
	void slotInviteCommand( const TQString &args, Kopete::ChatSession *manager);

	void slotViewCreated( KopeteView * );

private:
	static IRCProtocol *s_protocol;

	void simpleModeChange( const TQString &, Kopete::ChatSession *, const TQString &mode );

	// FIXME: All the code for managing the networks list should be in another class - Will
	void storeCurrentNetwork();
	void storeCurrentHost();

	NetworkConfig *netConf;
	TQString m_uiCurrentNetworkSelection;
	TQString m_uiCurrentHostSelection;
	// end of network list specific code

	DOM::Node activeNode;
	IRCAccount *activeAccount;

	bool m_commandInProgress;

	TQDict<IRCNetwork> m_networks;
	TQDict<IRCHost> m_hosts;
	IRCProtocolHandler *m_protocolHandler;
};

#endif
