/***************************************************************************
 *   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 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 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 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);
signals:
	void networkException(int);
	void packetException(int);
	void serverBusy();
	
	void loginOK();
	void logoutOK(); 
	void onlineReady();
	void offlineReady();
	void invisibleReady();
	void leaveReady();
	void kickedOut();
	
	void friendStatusChanged(int id);
	void friendListReady();
	void myInfoReady();
	void userInfoReady(QStringList info);
	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();
	
// 	void groupNamesDownloadReady();
// 	void groupNamesUploadReady();
	void friendGroupsReady();
	void friendGroupsUploadReady(bool);
		
	void deleteBuddyReady(int, bool);
	
	void addingBuddy(int);
	void addBuddyReady();
	void addBuddyRejected();
	void addBuddyNeedAuth();
	
	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);
private:
	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;
	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 removeSenquence(const short seq);
	const int getSavedBuddyQQ(const short seq);
	
	void doGetGroupedFriends();
	
	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);
private slots:
	//void isReadySlot();
	void newPacketSlot();
	void networkExceptionSlot(int);
	void packetExceptionSlot(int);
	void timerSlot();
	
};

#endif 
