#ifndef SERVICE_H
#define SERVICE_H

#include "stdafx.h"
#include "CNet.h"
#include "ServiceDef.h"

struct info;
class service;
class centre;
class user;
class room;

struct info{
	char name[256];
	CString addr;
	int port;
	bool login;
	info(){
		login = false;
		strcpy(name, "Unknown");
	}
};

class Hcentre{
public:
	virtual void sAccept(int, CString, int) = 0;
	virtual void sClose(int) = 0;
	virtual void sLogin(CString, int, CString, int) = 0;
	virtual void sReject(CString) = 0;
	virtual void sReg(CString) = 0;
	virtual void sSetPort(int, int) = 0;
};
class Huser{
public:
	virtual void OnLoginReject() = 0;
	virtual void OnRegDone() = 0;
	virtual void OnLogin() = 0;
	virtual void OnUpdateID(int) = 0;
	virtual void OnUserOn(int, char *, CString *, int) = 0;
	virtual void OnUserOff(int) = 0;
	virtual void OnTerminateServe() = 0;
	virtual void OnIDProb() = 0;
	virtual void OnMsgIn(int, CString*) = 0;
	virtual void OnCenQuit() = 0;
	virtual void OnConnect(int, CString *, int) = 0;
};

class service : public CNetHandler{
protected:
	CNet m_Net;
public:
	virtual int BeginService(int) = 0;
	virtual void EndService() = 0;
};

class centre : public service{
private:
	CENTREDLG parent;
	std::list<int> *idlist;
	std::map<int, info*> *idToInfo;
	std::map<CString, CString> *usrToPsw;
public:
	centre(CENTREDLG);
	~centre();
	int BeginService(int);
	void EndService();
	void Kick(int); 
	void introduce();
	void addpair(CString, CString);
	void detach();

	void onBoard(int);
	void offBoard(int);
	void closeAll();

	int OnAccept(int);
	void OnRecv(NETOBJ *);
	void OnClose(int);
	void OnBeClose(int);
};


class room : public service{
private:
	user *parent;
	ROOMDLG dlg;
	std::list<int *> ids;
public:
	room(user* u, ROOMDLG d){
		parent = u;
		dlg = d;
		ids.clear();
	}
	int BeginService(int port = 525){
		m_Net.SetHandler(this);
		return m_Net.Run(port);
	};
	void EndService(){
		m_Net.Stop();
		closeAll();
	};
	int OnAccept(int id){
		return 0;
	};
	void OnRecv(NETOBJ *obj){};
	void OnClose(int id){
	}
	void invite(int id){
	}
	void leave(){
	}
	void broadcast(CString *s){
	}
	void ear(int id, CString *s){
	}
	void closeAll(){ // null function
	}
};

class user : public service{
private:
	USERDLG parent;
	int cenCon;
	int myID;
	int myPt;
	bool served;
	std::list<room *> rooms;
	std::list<int> conlist;
	std::list<int> idlist;
	std::map<int, int> conToId;
	std::map<int, int *> idToCon;
	std::map<int, char *>  idToName;
	std::map<int, CString *> conToIp;
	std::map<int, CString *> idToIp;
	std::map<int, int> idToPort;
public:
	user(USERDLG);
	// To UI
	int BeginService(int);
	void EndService();
	// To Server
	int RequestService(CString, int);
	void TerminateService();

	void Login(char *, char *);
	void message(int, CString *);

	room* newRoom(ROOMDLG);
	int BeginRoom(room *, int);

	void QueryAll();
	int connect(int, int, bool);
	void disconnect(int);
	void QueryID();
	void identity(int);
	void closeAll();
	int OnAccept(int);
	void OnRecv(NETOBJ *);
	void OnClose(int);
};

#endif