/***************************************************************************
 *   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 EVAUSER_H
#define EVAUSER_H 

#include "evauserinfo.h"
#include "evafriendlist.h"
#include "evaqunlist.h"
#include <qobject.h>
#include <string>
#include <list>

class EvaLoginProcess : public QObject{
	Q_OBJECT
public:
	EvaLoginProcess();
	const int nextNumOperation();
	const short nextStep();
	void clearCommandFlag(const short cmd);
	void finishedCommand(const short cmd);
	const bool isReady();
	const bool isCommandFinished(const short cmd);
	void reset();
signals:
	void processReady();
private:
	int mCurrentStepTwo;
	int mNextStep;
	short mCommands[6];
	std::map<short, bool> mFlags;
	
	void initFlags();
};

class EvaUserSetting;
class CustomEvent;

class EvaUser : public QObject
{
	Q_OBJECT
public:
	EvaUser(const int id, const std::string &password);
	EvaUser(const int id, const char *md5Password);
	~EvaUser();
	
	enum UserStatus {Eva_Online, Eva_Offline, Eva_Invisible, Eva_Leave};
	const int getQQ() const { return qqNum; }
	const char *getMd5Password() const { return md5Password; }
	
	void setStatus(const UserStatus status) { this->status = status; }
	const UserStatus getStatus() const { return status; }
	static char getStatusCode(const UserStatus status) ;
	
	void setDetails(const ContactInfo &details) { this->details = details; }
	const ContactInfo &getDetails() const { return details; }
	
	FriendList &getFriendList() { return myFriends; }

	
	unsigned int getOnlineTime() const { return timeOnline;}     // the following 6 funs are about the level requst
	unsigned short getLevel() const { return level; }
	unsigned short getHoursToLevelUp() const { return hoursToLevelUp;}
	
	void setOnlineTime(const unsigned int time ) { timeOnline = time;}
	void setLevel(const unsigned short l ) { level = l;}
	void setHoursToLevelUp(const unsigned short time ) { hoursToLevelUp = time;}
		
	const bool newGroup(const std::string &name);
	void clearGroupNames();
	void removeGroupName(const int index);
	const int getGroupIndexOf(const std::string &name);
	void updateGroupName(const std::string &newName, const int index);
	
	void setQunGroupName(const std::string &name) { qunName = name; }
	void setAnonymousGroupName(const std::string &name) { anonymousName = name; }
	void setBlackGroupName(const std::string &name) { blackName = name; }	
	
	const std::string getQunGroupName() const { return qunName; }
	const std::string getAnonymousGroupName() const { return anonymousName; }
	const std::string getBlackGroupName() const { return blackName; }
	
	static int getQunIndex() { return qunIndex; }
	static int getAnonymousIndex() { return anonymousIndex; }
	static int getBlackIndex() { return blackIndex; }
	
	std::list<std::string> &getGroupNames() { return groupNames; }
	void setGroupNames(std::list<std::string> &list) { groupNames = list; }
	const std::string groupNameAtIndex(const int index);
	
	EvaUserSetting *getSetting() { return setting; }
	
	const bool loadGroupedBuddyList();
	const bool saveGroupedBuddyList();
	void setBuddyLoadedEnabled( const bool v) { isBuddyListLoaded = v; }
	const bool isBuddiesLoaded() const { return isBuddyListLoaded; }

	QunList *getQunList() { return &qunList; }
	const bool loadQunList();
	const bool saveQunList();
	const bool isQunLoaded() const { return isQunListLoaded; }
	
	void setExtraInfo( const unsigned short info) { mExtraInfo = info; }
	const unsigned short getExtraInfo() const { return mExtraInfo; }
	const bool hasSignature() { return mExtraInfo & QQ_EXTAR_INFO_SIGNATURE; }
	const bool hasQQTang() { return mExtraInfo & QQ_EXTAR_INFO_TANG; }
	const bool hasQQAlbum() { return mExtraInfo & QQ_EXTAR_INFO_ALBUM; }
	const bool hasPalEntry() { return mExtraInfo & QQ_EXTAR_INFO_PAL; }
	const bool hasUserHead() { return mExtraInfo & QQ_EXTAR_INFO_USER_HEAD; }
		
	void setSignature(const std::string sig, const unsigned int time) { mSignature = sig;  mSignatureModifyTime = time; }
	const std::string &getSignature() const { return mSignature; }
	const unsigned int getSignatureModifyTime() const { return mSignatureModifyTime; }
	
	EvaLoginProcess *loginManager() { return mLoginManager; }

signals:
	void loadGroupedBuddiesReady();
	void loadQunListReady();
protected:
	virtual void customEvent( QCustomEvent * e );
private:
	int qqNum;
	char *md5Password;
	UserStatus status;
	ContactInfo details;
	FriendList myFriends;
	std::list<std::string> groupNames;
	EvaUserSetting *setting;
	bool isBuddyListLoaded;
	bool isQunListLoaded;
	
	unsigned int timeOnline;
	unsigned short level;
	unsigned short hoursToLevelUp;
	
	unsigned short mExtraInfo;
	unsigned int mSignatureModifyTime;
	std::string mSignature;
	
	QunList qunList;
	
	EvaLoginProcess *mLoginManager;
	
	static std::string qunName;
	static std::string anonymousName;
	static std::string blackName;
	static const int qunIndex = 0xfffd;
	static const int anonymousIndex = 0xfffe;
	static const int blackIndex = 0xffff;
};

#endif


