/***************************************************************************
 *   Copyright (C) 2004 by yunfan                                          *
 *   yunfan_zg@163.com                                                     *
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#ifndef EVAPACKETMANAGER_H 
#define EVAPACKETMANAGER_H

#include "libeva.h"
#include "evauser.h"
#include <map>
#include <qobject.h>
#include <qdatetime.h>
#include <qstringlist.h>
#include <qvaluelist.h>


// passing a connected EvaConnecter in, otherwise whenever sending a packet will cause an exception
class QTimer;
class EvaConnecter;
class QTextCodec;

class EvaPacketManager : public QObject {
	Q_OBJECT
public:
	EvaPacketManager(EvaUser *user, EvaConnecter *connecter);
	~EvaPacketManager();
	
	EvaUser *getUser() { return user; }
	EvaConnecter *getConnecter() { return connecter; }
	
	QStringList convertDetails(const ContactInfo &info);
	
	const int getNumOnlineUsers() const { return numOnlineUsers; }
public slots:
	void doRequestLoginToken();
	void doLogin();
	void doLogout();
	void doGetUserInfo(const int id);
	void doModifyDetails(QStringList info, QString oldPwd = QString::null, QString newPwd = QString::null);
	
	void doChangeStatus(EvaUser::UserStatus newStatus);
	void doGetAllFriends();
	
	void doGetAllLevels();
	void requestFriendLevel(const int id);
	
	void doSendMessage(const int receiver, const bool isNormal, QString &message, const char fontSize = 9, 
			const bool u = false, const bool i = false, const bool b = false, 
			const char blue = 0, const char green = 0, const char red = 0);
			
	void doGetGroups();
	void doUploadGroups();
	
	void doDeleteBuddy(const int id);
	
	void doAddBuddy(const int id);
	void doAddAuthBuddy(const int id, const QString &message);
	void doApproveBuddy(const int id);
	void doRejectBuddy(const int id, const QString &message);

	void doSearchUsers(const bool isSearchAll = true, const QString page = "0", const QString id ="", 
			const QString nick = "", const QString email = "", const bool match = false);
	
	void doDeleteMeFrom(const int id);
	
	void doRequestQunInfo(const int id);
	void doRequestQunMemberInfo(const int id, const std::list<int> &l);
	void doRequestQunOnlineMembers(const int id);
	
	void doSendQunMessage(const int receiver, QString &message, const char fontSize = 9, 
			const bool u = false, const bool i = false, const bool b = false, 
			const char blue = 0, const char green = 0, const char red = 0);
	void doSearchQun(const int extID);
	void doJoinQun(const int qunID);
	void doJoinQunAuth(const int qunID,  const QString &);
	
	void doApproveQun(const int, const int);
	void doRejectQun(const int, const int, const QString &);
	
	void doModifyQunInfo(const int id, unsigned char auth, unsigned short cate, QString name, QString notice, QString description);
	void doModifyQunCard(const int id,  const int qqID, QString name, unsigned char gender, QString phone, QString email, QString memo);
	void doQunSetAdmin(const int id, const int qq, const bool isSetAdmin);
	void doQunTransfer(const int id, const int qq);
	void doModifyQunMembers(const int id, const std::list<int>members, const bool isAdd);
	void doRequestQunCard( const int id,  const int qq);
	void doQunExit(const int id);
	void doQunCreate(const QString &name, const unsigned short category, const unsigned char auth, const QString &notice, 
			const QString &description, const std::list<int> &members);
	
	void doRequestExtraInfo();
	void doModifySignature(const QString signature); // only for user use only
	void doDeleteSignature();   // only for user use only
	void doRequestSignature( const int start = 0);  // for all your buddies
	
	void lastLoginStep();
signals:
	void networkException(int);
	void packetException(int);
	void serverBusy();
	
	void loginOK();
	void logoutOK(); 
	void onlineReady();
	void offlineReady();
	void invisibleReady();
	void leaveReady();
	void kickedOut(const QString);
	
	void friendStatusChanged(int id);
	void friendListReady();
	void myInfoReady();
	void userInfoReady(QStringList info);
	void extraInfoReady();
	void modifyInfo(bool);
	
	void sentMessageResult(int ,bool);
	void txtMessage(int sender, bool isNormal, QString message, QDateTime time, const char fontSize, 
			const bool u, const bool i, const bool b, 
			const char blue, const char green, const char red);
	void sysMessage(int type, QString message);
	
	void wrongPassword(QString);
	
	void friendGroupsReady();
	void friendGroupsUploadReady(bool);
		
	void deleteBuddyReady(int, bool);
	
	void addingBuddy(int);
	void addBuddyReady();
	void addBuddyRejected();
	void addBuddyNeedAuth();
	void addAnonymous(const int,const short);

	void addBuddySentToServer(bool);
	
	void systemMeBeenAdded(int);
	void systemAddMeRequest(int, QString);
	void systemAddRequestApproved(int);
	void systemAddRequestRejected(int, QString);
	void systemNotification(int, QString);
	
	void searchUsersReady(const bool finished, const std::list<OnlineUser> list);
	void deleteMeReady(bool);
	
	void friendSignatureChanged(const int, const QDateTime, const QString);
	
	void qunSentMessageResult(int, bool, QString);
	void qunTxtMessage(int qunID, int senderQQ, QString message, QDateTime time, const char fontSize, 
			const bool u, const bool i, const bool b, 
			const char blue, const char green, const char red);
	void qunInfomationReady(const int, const bool, QString);
	void qunMemberInfoReady(const int);
	void qunOnlineListReady(const int);
	void qunSearchReady(const std::list<QunInfo>, QString);
	
	void qunJoinReplyOK(const int);
	void qunJoinReplyNeedAuth(const int);
	void qunJoinReplyDenied(const int);
	void qunJoinAuthReply(const int);  // note that this signal only means the server received your request correctly, nothing else
	void qunSystemMessageRequest(const int, QString);
	void qunRequestUpdateDisplay();
	void qunModifyInfoReply(const int, const bool, QString);
	void qunModifyQunCardReply(const int, const bool, const int, QString);
	void qunSetAdminReply(const int , const bool , const int, const bool , QString);
	void qunTransferReply(const int , const bool, const int, QString);
	void qunModifyQunMembersReply(const int, const bool, QString);
	void qunRequestQunCardReply(const int, const bool, const int, QString, const unsigned char, QString, QString, QString, QString);
	void qunExitReply(const int, const bool, QString);
	void qunCreateDone(const int);
	void qunCreateFailed(QString);
	void qunActiveQunFailed(QString);
	
	void signatureModifyReply(const bool);
	void signatureDeleteReply(const bool);
private:
	QTextCodec *codec;
	EvaUser *user;
	EvaConnecter *connecter;
	QTimer *timer; // keep online and get online friends
	std::map<short, int>sendRemoveCacheList; // packet sequence(key), qq id
	int numOnlineUsers;
	int addingBuddyQQ;
	int deletingBuddyQQ;
	int processQunID;
	bool qunMemberInfoFinished;
	ContactInfo changingDetails;
	QValueList<int>receivedPacketList;
	QValueList<int>receivedCacheList;
	
	void redirectTo(const int ip, const short port);
	void doGetOnlineFriends();
	void parsePacket(InPacket *packet);
	
	void saveBuddyQQ(const int id, const short seq);
	void removeSequence(const short seq);
	const int getSavedBuddyQQ(const short seq);
	
	void doGetGroupedFriends();
	
	void processRequestLoginTokenReply(const InPacket *in);
	void processLoginReply(const InPacket *in);
	void processGetUserInfoReply(const InPacket *in);
	void processChangeStatusReply(const InPacket *in);
	void processGetFriendListReply(const InPacket *in);
	void processSendIMReply(const InPacket *in);
	void processGetOnlineFriendReply(const InPacket *in);
	void processReceiveIM(const InPacket *in);
	void processKeepAliveReply(const InPacket *in);
	void processFriendChangeStatus(const InPacket *in);
	void processGroupNameOp(const InPacket *in);
	void processDownloadGroupFriendReply(const InPacket *in);
	void processUploadGroupFriendReply(const InPacket *in);
	void processDeleteFriendReply(const InPacket *in);
	void processAddFriendReply(const InPacket *in);
	void processAddFriendAuthReply(const InPacket *in);
	void processSystemNotification(const InPacket *in);
	void processModifyInfoReply(const InPacket *in);
	void processSearchUserReply(const InPacket *in);
	void processDeleteMeReply(const InPacket *in);
	void processQunReply(const InPacket *in);
	void processGetLevelReply(const InPacket *in);
	void processRequestKeyReply(const InPacket *in);
	void processRequestExtraInfoReply(const InPacket *in);
	void processSignatureReply(const InPacket *in);
private slots:
	void newPacketSlot();
	void networkExceptionSlot(int);
	void packetExceptionSlot(int);
	void timerSlot();
	
};

#endif 
