/*
    Kopete Yahoo Protocol

    Copyright (c) 2005-2006 André Duffeck <duffeck@kde.org>
    Copyright (c) 2004 Duncan Mac-Vicar P. <duncan@kde.org>
    Copyright (c) 2004 Matt Rogers <matt.rogers@kdemail.net>
    Copyright (c) 2004 SuSE Linux AG <http://www.suse.com>
    Copyright (C) 2003  Justin Karneges <justin@affinix.com>

    Kopete (c) 2002-2006 by the Kopete developers <kopete-devel@kde.org>

    *************************************************************************
    *                                                                       *
    * This library is free software; you can redistribute it and/or         *
    * modify it under the terms of the GNU Lesser General Public            *
    * License as published by the Free Software Foundation; either          *
    * version 2 of the License, or (at your option) any later version.      *
    *                                                                       *
    *************************************************************************
*/

#ifndef LIBYAHOO_CLIENT_H
#define LIBYAHOO_CLIENT_H

#include <tqobject.h>
#include <kurl.h>

#include "transfer.h"
#include "yahootypes.h"

#define YMSG_PROGRAM_VERSION_STRING "8.1.0.209"

class TQString;
class TQTimer;
class TQPixmap;
class TQDomDocument;
class ClientStream;
class KNetworkConnector;
class Task;
class KTemporaryFile;
struct YABEntry;

class Client : public TQObject
{
Q_OBJECT
  

	public:

		/*************
		  EXTERNAL API
		 *************/

		enum LogLevel { Debug, Info, Notice, Warning, Error, Critical };

		Client(TQObject *parent=0);
		~Client();

		/**
		 * Set the Yahoo Id of the account
		 * @param username The Yahoo Id
		 */
		void setUserId( const TQString& userName );

		/**
		 * Set the picture checksum
		 * @param username The checksum
		 */
		void setPictureChecksum( int cs );

		/**
		 * Start a connection to the server using the supplied @ref ClientStream.
		 * This is only a transport layer connection.
		 * Needed for protocol action P1.
		 * @param host The server to connect to.
		 * @param port The port to be used. The Yahoo server allows connection on arbitrary ports.
		 * @param userId The yahoo ID that will be connected.
		 * @param pass The password.
		 */
		void connect( const TQString &host, const uint port, const TQString &userId, const TQString &pass );

		/** Cancel active login attemps	 */
		void cancelConnect();

		/** Logout and disconnect */
		void close();

		/** Returns the errorcode */
		int error();

		/** Returns a description of the error */
		TQString errorString();

		/** Returns information about what went wrong */
		TQString errorInformation();

		/**
		 * Specifies the status we connect with.
		 * The Yahoo protocol supports connecting into Online and Invisible state.
		 * If status is any other status the Client connects into Online state and changes into the specified state after the login.
		 * @param status the status to connect with
		 */
		void setStatusOnConnect( Yahoo::Status status );

		/**
		 * Specifies the status message we connect with.
		 * The Yahoo protocol does not support connecting with a status message. If msg is not empty the Client
		 * will change the status message after the login.
		 * @param msg the status message to connect with
		 */
		void setStatusMessageOnConnect( const TQString &msg );

		/** Accessors needed for login */
		TQString host();
		int port();

		/**
		 * Send a Typing notification
		 * @param to the buddy that should be notified
		 * @param typing true if there is typing activity, false if not
		 */
		void sendTyping( const TQString &to, bool typing );

		/**
		 * Send a Message
		 * @param to the buddy that should receive the message
		 * @param msg the message
		 */
		void sendMessage( const TQString &to, const TQString &msg );

		/**
		 * Register / Unregister a chatsession
		 * @param to the buddy, the chatsession belongs to
		 * @param close if true, the chatsession will be closed, if false, it will be opened
		 */
		void setChatSessionState( const TQString &to, bool close );

		/**
		 * Send a Buzz
		 * @param to the buddy that should receive the buzz
		 */
		void sendBuzz( const TQString &to );

		/**
		 * Change our status
		 * @param status the status that will be set
		 * @param message the status message that will be set
		 * @param type Yahoo::StatusTypeAvailable means that the user is available, Yahoo::StatusTypeAway means that the user is away from the keyboard
		 */
		void changeStatus(Yahoo::Status status, const TQString &message, Yahoo::StatusType type);

		/**
		 * Set the verification word that is needed for a account verification after
		 * too many wrong login attempts.
		 * @param word the verification word
		 */
		void setVerificationWord( const TQString &word );

		/**
		 * Add a buddy to the contact list
		 * @param userId the yahoo ID of the buddy that should be added
		 * @param group the group where the buddy will be placed
		 * @param message the message that will be sent to the buddy along the authorization request
		 */
		void addBuddy( const TQString &userId, const TQString &group, const TQString &message = TQString::fromLatin1("Please add me")  );

		/**
		 * Remove a buddy from the contact list
		 * @param userId the yahoo ID of the buddy that should be removed
		 * @param group the group where the buddy belongs to
		 */
		void removeBuddy( const TQString &userId, const TQString &group );

		/**
		 * Move a buddy into another group
		 * @param userId the yahoo ID of the buddy that should be moved
		 * @param oldGroup the group where the buddy belongs to
		 * @param newGroup the group where the buddy will be placed
		 */
		void moveBuddy( const TQString &userId, const TQString &oldGroup, const TQString &newGroup );

		/**
		 * Change the stealth status of a buddy
		 * @param userId the yahoo ID of the buddy that should be moved
		 * @param mode defines the Stealth mode that is changed. That can be "Appear Offline", "Appear Online" or "Apper permanently offline"
		 * @param state the status of the specified Stealth mode. Active, Not Active or Clear
		 */
		void stealthContact( TQString const &userId, Yahoo::StealthMode mode, Yahoo::StealthStatus state );

		/**
		 * Request the buddy's picture
		 * @param userId the yahoo ID of the buddy
		 */
		void requestPicture( const TQString &userId );

		/**
		 * Download the buddy's picture
		 * @param userId the yahoo ID of the buddy
		 * @param url the url of the picture
		 * @param checksum the checksum of the picture
		 */
		void downloadPicture( const TQString &userId, KURL url, int checksum );

		/**
		 * Send our picture
		 * @param url the file that should be sent as our buddy picture
		 */
		void uploadPicture( KURL url );

		/**
		 * Send checksum of our picture
		 * @param userId the yahoo ID of the buddy. Can be a null string if the picture has changed.
		 * @param checksum the checksum of the picture
		 */
		void sendPictureChecksum( const TQString &userId, int checksum );

		/**
		 * Send information about our picture
		 * @param userId the yahoo ID of the buddy that should be informed
		 * @param url the url of our picture
		 * @param checksum the checksum of the picture
		 */
		void sendPictureInformation( const TQString &userId, const TQString &url, int checksum );

		/**
		 * Notify the buddies about our new status
		 * @param flag the type of our picture (0=none, 1=avatar, 2=picture)
		 */
		void setPictureStatus( Yahoo::PictureStatus flag );

		/**
		 * Send a response to the webcam invite ( Accept / Decline )
		 * @param userId the yahoo ID of the sender
		 */
		void requestWebcam( const TQString &userId );

		/**
		 * Stop receiving of webcam
		 * @param userId the yahoo ID of the sender
		 */
		void closeWebcam( const TQString &userId );

		/**
		 * Invite the user to view your Webcam
		 * @param userId the yahoo ID of the receiver
		 */
		void sendWebcamInvite( const TQString &userId );

		/**
		 * transmit a new image to the watchers
		 * @param image the image data
		 */
		void sendWebcamImage( const TQByteArray &image );

		/** Stop the webcam transmission */
		void closeOutgoingWebcam();

		/**
		 * Allow a buddy to watch the cam
		 * @param userId the yahoo ID of the receiver
		 */
		void grantWebcamAccess( const TQString &userId );

		/**
		 * Invite buddies to a conference
		 * @param room the name of the conference
		 * @param members a list of members that are invited to the conference
		 * @param msg the invite message
		 */
		void inviteConference( const TQString &room, const TQStringList &members, const TQString &msg );

		/**
		 * Invite buddies to a already existing conference
		 * @param room the name of the conference
		 * @param who a list of members that are additionally invited to the conference
		 * @param members a list of members that are already in the conference
		 * @param msg the invite message
		 */
		void addInviteConference( const TQString &room, const TQStringList &who, const TQStringList &members, const TQString &msg );

		/**
		 * Join a conference
		 * @param room the name of the conference
		 * @param members a list of members that are already in the conference
		 */
		void joinConference( const TQString &room, const TQStringList &members );

		/**
		 * Decline to join a conference
		 * @param room the name of the conference
		 * @param members a list of members that are in the conference
		 * @param msg the reason why we don't want to join
		 */
		void declineConference( const TQString &room, const TQStringList &members, const TQString &msg );

		/**
		 * Leave the conference
		 * @param room the name of the conference
		 * @param members a list of members that are in the conference
		 */
		void leaveConference( const TQString &room, const TQStringList &members );

		/**
		 * Send a message to the conference
		 * @param room the name of the conference
		 * @param members a list of members that are in the conference
		 * @param msg the message
		 */
		void sendConferenceMessage( const TQString &room, const TQStringList &members, const TQString &msg );

		/**
		 * Send a authorization request response
		 * @param userId the yahoo ID of the requesting buddy
		 * @param accept true, if the user is allowed to see our status, false if not
		 * @param msg the reason for our decision
		 */
		void sendAuthReply( const TQString &userId, bool accept, const TQString &msg );

		/**
		 * Fetches all entries of the YAB
		 * @param lastMerge the YAB-Revision that was last merged with the local YAB
		 * @param lastRemoteRevision the latest known YAB-Revision
		 */
		void getYABEntries( long lastMerge, long lastRemoteRevision );

		/**
		 * Saves a modified YAB entry
		 * @param entry the YAB entry
		 */
		void saveYABEntry( YABEntry &entry );

		/**
		 * Creates a new YAB entry
		 * @param entry the YAB entry
		 */
		void addYABEntry( YABEntry &entry );

		/**
		 * Deletes a YAB entry
		 * @param entry the YAB entry
		 */
		void deleteYABEntry( YABEntry &entry );

		/**
		 * Send a file to a buddy
		 * @param transferId the unique ID of the transfer
		 * @param userId yahoo ID of the receiver
		 * @param msg a description of the file to be sent
		 * @param url the location of the file to be sent
		 */
		void sendFile( unsigned int transferId, const TQString &userId, const TQString &msg, KURL url );

		/**
		 * Receive a file from a buddy
		 * @param transferId the unique ID of the transfer
		 * @param userId yahoo ID of the sender
		 * @param remoteURL the url of the file
		 * @param localURL the location where the file should be stored
		 */
		void receiveFile( unsigned int transferId, const TQString &userId, KURL remoteURL, KURL localURL );

		/**
		 * Reject a file offered by a buddy
		 * @param userId yahoo ID of the sender
		 * @param remoteURL the url of the file
		 */
		void rejectFile( const TQString &userId, KURL remoteURL );

		/**
		 * Canceled a filetransfer
		 * @param transferId the unique ID of the transfer
		 */
		void cancelFileTransfer( unsigned int transferId );

		/**
		 * Get the list of yahoo chat categories
		 */
		void getYahooChatCategories();

		/**
		 * Get the list of chatrooms for the given category
		 */
		void getYahooChatRooms( const Yahoo::ChatCategory &category );

		/**
		 * Join a chat room
		 */
		void joinYahooChatRoom( const Yahoo::ChatRoom &room );

		/**
		 * Leave the chat room
		 */
		void leaveChat();

		/**
		 * Send a chat message
		 */
		void sendYahooChatMessage( const TQString &msg, const TQString &handle );

		/*************
		  INTERNAL (FOR USE BY TASKS) METHODS
		 *************/
		/**
		 * Send an outgoing request to the server
		 * @param request the transfer to be sent
		 */
		void send( Transfer *request );

		/**
		 * Print a debug statement
		 */
		void debug( const TQString &str );

		/** The current user's user ID */
		TQString userId();

		/** The current user's password */
		TQString password();

		/** current Session ID */
		uint sessionID();

		/**
		 * return the pictureFlag describing the status of our buddy icon
		 * 0 = no icon, 2 = icon, 1 = avatar (?)
		 */
		int pictureFlag();

		/**
		 * return the picture checksum
		 */
		int pictureChecksum();

		/** Get our status */
		Yahoo::Status status();

		/**
		 * Set our status
		 * @param status the new status
		 */
		void setStatus( Yahoo::Status status );

		/** Access the root Task for this client, so tasks may be added to it. */
		Task* rootTask();

		/**
		 * Accessors to the cookies
		 */
		TQString yCookie();
		TQString tCookie();
		TQString cCookie();

		/**
		 * Error
		 */
		void notifyError( const TQString &info, const TQString &errorString, LogLevel level );
	signals:
		/** CONNECTION EVENTS */
		/**
		 * Notifies that the login process has succeeded.
		 */
		void loggedIn( int, const TQString& );

		/**
		 * Notifies that the login process has failed
		 */
		void loginFailed();

		/**
		 * Notifies tasks and account so they can react properly
		 */
		void connected();
		/**
		 * Notifies tasks and account so they can react properly
		 */
		void disconnected();
		/**
		 * We were disconnected because we connected elsewhere
		 */
		void connectedElsewhere();

		void error( int level );
		/**
		 * Notifies about our buddies and groups
		 */
		void gotBuddy( const TQString &, const TQString &, const TQString & );
		/**
		 * Notifies about adding buddies
		 */
		void buddyAddResult( const TQString &, const TQString &, bool );
		/**
		 * Notifies about removing buddies
		 */
		void buddyRemoveResult( const TQString &, const TQString &, bool );
		/**
		 * Notifies about buddies changing groups
		 */
		void buddyChangeGroupResult( const TQString &, const TQString &, bool );
		/**
		 * Notifies about the status of online buddies
		 */
		void statusChanged( const TQString&, int, const TQString&, int, int, int );
		/**
		 * Notifies about the stealth status of buddies
		 */
		void stealthStatusChanged( const TQString &, Yahoo::StealthStatus );
		/**
		 * Notifies about mails
		 */
		void mailNotify( const TQString&, const TQString&, int );
		/**
		 * We got a new message
		 */
		void gotIm( const TQString&, const TQString&, long, int );
		/**
		 * We got a new system message
		 */
		void systemMessage( const TQString& );
		/**
		 * The buddy is typing a message
		 */
		void typingNotify( const TQString &, int );
		/**
		 * The buddy has invited us to view his webcam
		 */
		void gotWebcamInvite(const TQString &);
		/**
		 * Notifies about a BUZZ notification
		 */
		void gotBuzz( const TQString &, long );
		/**
		 * Notifies about a changed picture status
		 */
		void pictureStatusNotify( const TQString &, int );
		/**
		 * Notifies about a picture checksum
		 */
		void pictureChecksumNotify( const TQString &, int );
		/**
		 * Notifies about a picture
		 */
		void pictureInfoNotify( const TQString &, KURL, int );
		/**
		 * The iconLoader has successfully downloaded a picutre
		 */
		void pictureDownloaded( const TQString &, const TQByteArray &, int );
		/**
		 * A Buddy asks for our picture
		 */
		void pictureRequest( const TQString & );
		/**
		 * Information about the picture upload
		 */
		void pictureUploaded( const TQString &, int );
		/**
		 * We've received a webcam image from a buddy
		 */
		void webcamImageReceived( const TQString &, const TQPixmap &);
		/**
		 * The requested Webcam is not available
		 */
		void webcamNotAvailable( const TQString & );
		/**
		 * The connection to the webcam was closed
		 */
		void webcamClosed( const TQString &, int );
		/**
		 * The webcamtransmission is paused
		 */
		void webcamPaused(const TQString&);
		/**
		 * The webcam connection is ready for transmission
		 */
		void webcamReadyForTransmission();
		/**
		 * The webcam should stop sending images
		 */
		void webcamStopTransmission();
		/**
		 * A new buddy watches the cam
		 */
		void webcamViewerJoined( const TQString & );
		/**
		 * A buddy no longer watches the cam
		 */
		void webcamViewerLeft( const TQString & );
		/**
		 * A buddy wants to watch the cam
		 */
		void webcamViewerRequest( const TQString & );
		/**
		 * A buddy invited us to a conference
		 */
		void gotConferenceInvite( const TQString &, const TQString &, const TQString &, const TQStringList & );
		/**
		 * A conference message was received
		 */
		void gotConferenceMessage( const TQString &, const TQString &, const TQString & );
		/**
		 * A buddy joined the conference
		 */
		void confUserJoined( const TQString &, const TQString & );
		/**
		 * A buddy left the conference
		 */
		void confUserLeft( const TQString &, const TQString & );
		/**
		 * A buddy declined to join the conference
		 */
		void confUserDeclined( const TQString &, const TQString &, const TQString & );
		/**
		 * A buddy accepted our authorization request
		 */
		void authorizationAccepted( const TQString & );
		/**
		 * A buddy rejected our authorization request
		 */
		void authorizationRejected( const TQString &, const TQString & );
		/**
		 * A buddy requests authorization
		 */
		void gotAuthorizationRequest( const TQString &, const TQString &, const TQString & );
		/**
		 * A revision of the Yahoo Addressbook was received
		 */
		void gotYABRevision( long rev, bool merged );
		/**
		 * A entry from the Yahoo Addressbook was retrieved
		 */
		void gotYABEntry( YABEntry * );
		/**
		 * An error occurred while saving a Yahoo Addressbook entry
		 */
		void modifyYABEntryError( YABEntry *, const TQString & );
		/**
		 * number of Bytes transferred for FileTransfer id
		 */
		void fileTransferBytesProcessed( unsigned int, unsigned int );
		/**
		 * filetransfer completed
		 */
		void fileTransferComplete( unsigned int );
		/**
		 * An error occurred during the filetransfer
		 */
		void fileTransferError( unsigned int, int, const TQString & );
		/**
		 * filetransfer canceled
		 */
		void fileTransferCanceled( unsigned int );
		/**
		 * A buddy is trying to send us a file
		 */
		void incomingFileTransfer( const TQString &, const TQString &, long, const TQString &,
			const TQString &, unsigned long, const TQPixmap & );
		/**
		 * We have received the list of yahoo chat categories
		 */
		void gotYahooChatCategories( const TQDomDocument & );
		/**
		 * We have received the list of chatrooms for the categories
		 */
		void gotYahooChatRooms( const Yahoo::ChatCategory &, const TQDomDocument & );
		/**
		 * We have joined a chatroom
		 */
		void chatRoomJoined( int, int, const TQString &, const TQString & );
		/**
		 * A buddy has joined a chatroom
		 */
		void chatBuddyHasJoined( const TQString &, const TQString &, bool );
		/**
		 * A buddy has left a chatroom
		 */
		void chatBuddyHasLeft( const TQString &, const TQString & );
		/**
		 * We have received a message in a chatroom
		 */
		void chatMessageReceived( const TQString &, const TQString &, const TQString & );
	protected slots:
		// INTERNAL, FOR USE BY TASKS' finished() SIGNALS //
		void lt_loginFinished();
		void lt_gotSessionID( uint );
		void cs_connected();
		void slotGotCookies();
		void streamDisconnected();

		/**
		 * Used by tasks to identify a response to a login attempt
		 */
		void slotLoginResponse( int, const TQString& );

		/**
		 * Used by the client stream to notify errors to upper layers.
		 */
		void streamError( int error );

		/**
		 * The client stream has data ready to read.
		 */
		void streamReadyRead();

		/**
		 * Send a Yahoo Ping packet to the server
		 */
		void sendPing();

		/**
		 * Send all queued buddy icon requests
		 */
		void processPictureQueue();

	private:
		void distribute( Transfer *transfer );

		/**
		 * create static tasks and connect their signals
		 */
		void initTasks();

		/**
		 * remove static tasks and their signal connections
		 */
		void deleteTasks();

		class ClientPrivate;
		ClientPrivate* d;
		KNetworkConnector *m_connector;

		TQTimer *m_pingTimer;
};

#endif