/*
    yahooaccount.h - Manages a single Yahoo account

    Copyright (c) 2003 by Gav Wood               <gav@kde.org>
    Copyright (c) 2003 by Matt Rogers            <mattrogers@sbcglobal.net>
    Based on code by Olivier Goffart             <ogoffart @ kde.org>
    Kopete    (c) 2003 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 YAHOOIDENTITY_H
#define YAHOOIDENTITY_H

// Qt
#include <qobject.h>
#include <qmap.h>

// Kopete
#include "kopetepasswordedaccount.h"
#include "kopeteawaydialog.h"

// Local
#include "yahooprotocol.h"
#include "yahootypes.h"

class QColor;
class KAction;
class KActionMenu;
class YahooContact;
class YahooAccount;
class YahooProtocol;
class YahooWebcam;
class YahooConferenceChatSession;
class KTempFile;
struct KURL;
namespace Kopete{
class Transfer;
class ChatSession;
class FileTransferInfo;
}
class Client;
class YABEntry;
namespace KIO{
	class Job;
}
class YahooAwayDialog : public KopeteAwayDialog
{
public:
	YahooAwayDialog(YahooAccount *account, QWidget *parent = 0, const char *name = 0);
	virtual void setAway(int awayType);

private:
	YahooAccount *theAccount;
};

class YahooAccount : public Kopete::PasswordedAccount
{
	Q_OBJECT

public:

	enum SignalConnectionType { MakeConnections, DeleteConnections };

	YahooAccount(YahooProtocol *parent,const QString& accountID, const char *name = 0L);
	~YahooAccount();

	/*
	 * Returns a contact of name @p id
	 */
	YahooContact *contact(const QString &id);

	virtual KActionMenu* actionMenu();

	/**
	 * Sets the yahoo away status
	 */
	virtual void setAway(bool, const QString &);

	/**
	 * The session
	 */
	Client *yahooSession();

	/**
	 * Returns true if contact @p id is on the server-side contact list
	 */
	bool isOnServer(const QString &id) { return IDs.contains(id); }

	/**
	 * Returns true if we have the server-side contact list
	 */
	bool haveContactList() const { return theHaveContactList; }

	void setUseServerGroups(bool newSetting);

	void setImportContacts(bool newSetting);

	/**
	 * Set the pager server
	 */
	void setServer( const QString &server );
	
	/**
	 * Set the port of the pager server
	 */
	void setPort( int port );

	/**
	 * Set Buddy Icon
	 */
	void setBuddyIcon( KURL url );

	/**
	 * Return flag describing wether or not we send a buddy icon
	 * 0 = no image, 2 = buddy icon, 1 = avatar?
	 */
	int pictureFlag();

	void verifyAccount( const QString &word );

	void sendConfMessage( YahooConferenceChatSession *s, Kopete::Message &message );
	void prepareConference( const QString &who );
	void sendFile( YahooContact *to, const KURL &url );
public slots:
	/**
	 * Connect to the Yahoo service
	 */
	virtual void connectWithPassword( const QString & );
	/**
	 * Disconnect from the Yahoo service
	 */
	virtual void disconnect();

	/** Reimplemented from Kopete::Account */
	void setOnlineStatus( const Kopete::OnlineStatus&, const QString &reason = QString::null);


signals:
	/**
	 * Emitted when we receive notification that the person we're talking to is typing
	 */
	void receivedTypingMsg(const QString &contactId, bool isTyping);

	/**
	 * Emitted when our Buddy Icon has changed
	 */
	void signalBuddyIconChanged( int type );

protected:
	/**
	 * Adds our Yahoo contact to a metacontact
	 */
	virtual bool createContact(const QString &contactId,  Kopete::MetaContact *parentContact);

	/**
	 * Gets the just-received message color
	 */
	QColor getMsgColor(const QString& msg);
	/**
	 * Remove color codes from a message
	 */
	QString stripMsgColorCodes(const QString& msg);

protected slots:
	void slotConnected();
	void slotGoOnline();
	void slotGoOffline();
	void slotOpenInbox();			// Open Yahoo Mailbox in browser
	void slotOpenYAB();			// Open Yahoo Addressbook in browser
	void slotEditOwnYABEntry();		// Show own Yahoo Addressbook entry

	void slotGoStatus(int status, const QString &awayMessage = QString::null);
	void slotLoginResponse(int succ, const QString &url);
	void slotDisconnected();
	void slotLoginFailed();
	void slotGotBuddy(const QString &userid, const QString &alias, const QString &group);
	void slotAuthorizationAccepted( const QString &who );
	void slotAuthorizationRejected( const QString &who, const QString &msg );
	void slotgotAuthorizationRequest( const QString &, const QString &, const QString & );
	void slotContactAddedNotifyDialogClosed( const QString & );
	void slotGotIgnore(const QStringList &);
	void slotGotIdentities(const QStringList &);
	void slotStatusChanged(const QString &who, int stat, const QString &msg, int away, int idle);
	void slotStealthStatusChanged(const QString &who, Yahoo::StealthStatus state);
	void slotGotIm(const QString &who, const QString &msg, long tm, int stat);
	void slotGotBuzz(const QString &who, long tm);
	void slotGotConfInvite(const QString &who, const QString &room, const QString &msg, const QStringList &members);
	void slotConfUserDecline(const QString &who, const QString &room, const QString &msg);
	void slotConfUserJoin(const QString &who, const QString &room);
	void slotConfUserLeave(const QString &who, const QString &room);
	void slotConfMessage(const QString &who, const QString &room, const QString &msg);
	void slotConfLeave( YahooConferenceChatSession *s );
	void slotInviteConference( const QString &room, const QStringList &who, const QStringList &members, const QString &msg );
	void slotAddInviteConference( const QString &room, const QStringList &who, const QStringList &members, const QString &msg );
	void slotGotFile(const QString &who, const QString &url, long expires, const QString &msg, const QString &fname, unsigned long fesize);
	void slotContactAdded(const QString &myid, const QString &who, const QString &msg);
	void slotRejected(const QString &, const QString &);
	void slotTypingNotify(const QString &, int );
	void slotGameNotify(const QString &, int);
	void slotMailNotify(const QString &, const QString &, int);
	void slotSystemMessage(const QString &);
	void slotRemoveHandler(int fd);
	//void slotHostConnect(const QString &host, int port);
	void slotGotWebcamInvite(const QString &);
	void slotWebcamNotAvailable( const QString &who );
	void slotGotWebcamImage(const QString&, const QPixmap&);
	void slotWebcamReadyForTransmission();
	void slotWebcamStopTransmission();
	void slotOutgoingWebcamClosing();
	void slotWebcamClosed(const QString&, int);
	void slotWebcamPaused(const QString&);
	void slotWebcamViewerJoined( const QString & );
	void slotWebcamViewerLeft( const QString & );
	void slotWebcamViewerRequest( const QString & );
	void slotPictureStatusNotiy( const QString&, int);
	void slotGotBuddyIcon(const QString&, KTempFile*, int);
	void slotGotBuddyIconInfo(const QString&, KURL, int);
	void slotGotBuddyIconChecksum(const QString&, int);
	void slotGotBuddyIconRequest(const QString &);
	void slotBuddyIconChanged(const QString&);
	void slotGotYABEntry( YABEntry *entry );
	void slotGotYABRevision( long revision, bool merged );
	void slotSaveYABEntry( YABEntry &entry );
	void slotModifyYABEntryError( YABEntry *entry, const QString & );

	void slotReceiveFileAccepted( Kopete::Transfer *trans, const QString& fileName );
	void slotReceiveFileRefused( const Kopete::FileTransferInfo& info );
	void slotFileTransferComplete( unsigned int id );
	void slotFileTransferError( unsigned int id, int error, const QString &desc );
	void slotFileTransferBytesProcessed( unsigned int id, unsigned int bytes );
	void slotFileTransferResult( KIO::Job * );
	void slotError( int level );

private slots:
	/**
	 * When a global identity key get changed.
	 */
	void slotGlobalIdentityChanged( const QString &key, const QVariant &value );
private:

	/**
	 * Handle the signal and slot connections and disconnects
	 */
	void initConnectionSignals( enum SignalConnectionType sct );

	QString prepareIncomingMessage( const QString &msg );

	/**
	 * internal (to the plugin) controls/flags
	 * This should be kept in sync with server - if a buddy is removed, this should be changed accordingly.
	 */
	QMap<QString, QPair<QString, QString> > IDs;

	/**
	 * Conferences list, maped by room name (id)
	 */
	QMap<QString, YahooConferenceChatSession *> m_conferences;
	QStringList m_pendingConfInvites;
	QStringList m_pendingWebcamInvites;
	QStringList m_pendingFileTransfers;

	QMap<unsigned int, Kopete::Transfer *> m_fileTransfers;

	void setPictureFlag( int flag );

	bool theHaveContactList;	// Do we have the full server-side contact list yet?
	int stateOnConnection;		// The state to change to on connection

	/**
	 * External Settings and Descriptors
	 */
	bool m_useServerGroups;		// Use the groups on the server for import
	bool m_importContacts;		// Import the contacts from the server
	int m_sessionId;		// The Yahoo session descriptor
	int m_lastDisconnectCode;	// The last disconnect code.
	int m_currentMailCount;
	int m_pictureFlag;			// Describes if we send a buddy icon or not
	long m_YABLastMerge;		// The YAB Revision on which the last merge was done
	long m_YABLastRemoteRevision;	// The last remote YAB Revision on which a sync was done
	YahooProtocol *m_protocol;	// The Protocol Object

	YahooWebcam *m_webcam;

	YahooAwayDialog *theAwayDialog;	// Our away message dialog

	KAction *m_openInboxAction;	// Menu item openInbox
	KAction *m_openYABAction;	// Menu item openYahooAddressbook
	KAction *m_editOwnYABEntry;	// Menu item editOwnYABEntry
	
	Client *m_session;		// The Connection object
};


#endif

