/*
    msnaccount.h - Manages a single MSN account

    Copyright (c) 2003-2005 by Olivier Goffart       <ogoffart@ kde.org>
    Copyright (c) 2005      by Michaêl Larouche       <michael.larouche@kdemail.net>

    Kopete    (c) 2003-2005 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 MSNACCOUNT_H
#define MSNACCOUNT_H

#include <tqobject.h>

#include "kopetepasswordedaccount.h"

#include "msnprotocol.h"

class TDEAction;
class TDEActionMenu;

class MSNNotifySocket;
class MSNContact;

/**
 * MSNAccount encapsulates everything that is account-based, as opposed to
 * protocol based. This basically means sockets, current status, and account
 * info are stored in the account, whereas the protocol is only the
 * 'manager' class that creates and manages accounts.
 */
class MSNAccount : public Kopete::PasswordedAccount
{
	TQ_OBJECT
  

public:
	MSNAccount( MSNProtocol *parent, const TQString &accountID, const char *name = 0L );

	/*
	 * return the menu for this account
	 */
	virtual TDEActionMenu* actionMenu();

	//------ internal functions
	/**
	 * change the publicName to this new name
	 */
	void setPublicName( const TQString &name );
	void setPersonalMessage(MSNProtocol::PersonalMessageType type, const TQString &personalMessage );

	/**
	 * Returns the address of the MSN server
	 */
	TQString serverName();

	/**
	 * Returns the address of the MSN server port
	 */
	uint serverPort();

	MSNNotifySocket *notifySocket();

	/**
	 * return true if we are able to send mail, or to open hotmail inbox
	 */
	bool isHotmail() const;


	/**
	 * Return the picture url.
	 */
	TQString pictureUrl();

	/**
	 * Set the picture url.
	 */
	void setPictureUrl(const TQString &url);

	/**
	 * return the <msnobj> tag of the display picture
	 */
	TQString pictureObject();

	/**
	 * reset the <msnobj>.  This method should be called if the displayimage has changed
	 * If we are actualy connected, it will imediatly update the <msgobj> on the server, exepted
	 * if @param silent is set to true
	 * @param force Force the application of MSN picture
	 */
	void resetPictureObject(bool silent=false, bool force=false);

	//BEGIN Http

	bool useHttpMethod() const;

	//END

	/**
	 * Return the client ID for the myself contact of this account.
	 * It is dynamic to see if we really have a webcam or not.
	 */
	TQString myselfClientId() const;

public slots:
	virtual void connectWithPassword( const TQString &password ) ;
	virtual void disconnect() ;
	virtual void setOnlineStatus( const Kopete::OnlineStatus &status , const TQString &reason = TQString());

	/**
	 * Ask to the account to create a new chat session
	 */
	void slotStartChatSession( const TQString& handle );

	/**
	 * Single slot to display error message.
	 */
	void slotErrorMessageReceived( int type, const TQString &msg );

protected:
	virtual bool createContact( const TQString &contactId, Kopete::MetaContact *parentContact );


private slots:
	// Actions related
	void slotStartChat();
	void slotOpenInbox();
	void slotChangePublicName();

//#if !defined NDEBUG //(Stupid moc which don't see when he don't need to slot this slot)
	/**
	 * Show simple debugging aid
	 */
	void slotDebugRawCommand();
//#endif

	// notifySocket related
	void slotStatusChanged( const Kopete::OnlineStatus &status );
	void slotNotifySocketClosed();
	void slotPersonalMessageChanged(const TQString& personalMessage);
	void slotContactRemoved(const TQString& handle, const TQString& list, const TQString& contactGuid, const TQString& groupGuid );
	void slotContactAdded(const TQString& handle, const TQString& list, const TQString& publicName, const TQString& contactGuid, const TQString &groupGuid );
	void slotContactListed( const TQString& handle, const TQString& publicName, const TQString &contactGuid, uint lists, const TQString& groups );
	void slotNewContactList();
	/**
	 * The group has successful renamed in the server
	 * groupName: is new new group name
	 */
	void slotGroupRenamed(const TQString &groupGuid, const TQString& groupName );
	/**
	 * A new group was created on the server (or received durring an LSG command)
	 */
	void slotGroupAdded( const TQString& groupName, const TQString &groupGuid );
	/**
	 * Group was removed from the server
	 */
	void slotGroupRemoved( const TQString &groupGuid );
	/**
	 * Incoming RING command: connect to the Switchboard server and send
	 * the startChat signal
	 */
	void slotCreateChat( const TQString& sessionID, const TQString& address, const TQString& auth,
		const TQString& handle, const TQString& publicName );
	/**
	 * Incoming XFR command: this is an result from
	 * slotStartChatSession(handle)
	 * connect to the switchboard server and sen startChat signal
	 */
	void slotCreateChat( const TQString& address, const TQString& auth);


	// ui related
	/**
	 * A kopetegroup is renamed, rename group on the server
	 */
	void slotKopeteGroupRenamed( Kopete::Group *g );

	/**
	 * A kopetegroup is removed, remove the group in the server
	 **/
	void slotKopeteGroupRemoved( Kopete::Group* );

	/**
	 * add contact ui
	 */
	void slotContactAddedNotifyDialogClosed( const TQString &handle);

	/**
	 * When the dispatch server sends us the notification server to use.
	 */
	void createNotificationServer( const TQString &host, uint port );

	/**
 	 * When a global identity key get changed.
	 */
	void slotGlobalIdentityChanged( const TQString &key, const TQVariant &value );

private:
	MSNNotifySocket *m_notifySocket;
	TDEAction *m_openInboxAction;
	TDEAction *m_startChatAction;
	TDEAction *m_changeDNAction;

	// status which will be using for connecting
	Kopete::OnlineStatus m_connectstatus;

	TQStringList m_msgHandle;

	bool m_newContactList;


	/**
	 * Add the contact on the server in the given groups.
	 * this is a helper function called bu createContact and slotStatusChanged
	 */
	void addContactServerside(const TQString &contactId, TQPtrList<Kopete::Group> groupList);

	

public: //FIXME: should be private
	TQMap<TQString, Kopete::Group*> m_groupList;

	void addGroup( const TQString &groupName, const TQString &contactToAdd = TQString() );

	/**
	 * Find and retrive a MSNContact by its contactGuid. (Helper function)
	 */
	MSNContact *findContactByGuid(const TQString &contactGuid);
private:

	// server data
	TQStringList m_allowList;
	TQStringList m_blockList;
	TQStringList m_reverseList;

	Kopete::MetaContact *m_addWizard_metaContact;
	TQMap< TQString, TQStringList > tmp_addToNewGroup;
	TQMap< TQString, TQStringList > tmp_addNewContactToGroup;

	TQString m_pictureObj; //a cache of the <msnobj>
	TQString m_pictureFilename; // the picture filename.

	//this is the translation between old to new groups id when syncing from server.
	TQMap<TQString, Kopete::Group*> m_oldGroupList;

	/**
	 * I need the password in createNotificationServer.
	 * but i can't ask it there with password() because a nested loop will provoque crash
	 * at this place.   so i'm forced to keep it here.
	 * I would like an API to request the password WITHOUT askling it.
	 */
	TQString m_password;

	/**
	 * Cliend ID is a bitfield that contains supported features for a MSN contact.
	 */
	uint m_clientId;
};

#endif
