alRom/bin/
alRom/data/class/
alRom/data/command/
alRom/data/guild/
alRom/data/help/
alRom/data/lang/
alRom/data/race/
alRom/data/religion/
alRom/data/skill/
alRom/note/
#ifndef _KING_H
#define _KING_H
/* Kingdoms.h */
#include <iostream>
#include <list>
#include <bitset>
#include <algorithm>
#include <string>
#include "merc.h"
#include "String.h"
class Member;
class Rank;
class Faction;
class Kingdom;
#define bitset_to_string(arg) \
  arg.template to_string<char, char_traits<char>,allocator<char> > ()
#define PREPSQL  MYSQL_ROW row;\
		 MYSQL_RES *rez;\
		 String query;

typedef std::list<Member *>::iterator MembI;
typedef std::list<Rank *>::iterator RankI;
typedef std::list<Faction *>::iterator FactI;
typedef std::list<Kingdom *>::iterator KingI;

enum Privleges { isGuards, isNoble, canAddFaction, canRecruit, canBoot, isIndependy, canBank, maxPrivs };
enum memberFlags { isOnline, isDead, isInvis, maxMemberFlags };

class Cabal
{	private:
		std::bitset<maxPrivs> privs;
	public:
		bool Privs(Privleges i, bool set = false);
		bool IsGuards(bool set = false);
		bool IsNoble(bool set = false);
		bool CanAddFaction(bool set = false);
		bool CanRecruit(bool set = false);
		bool CanBoot(bool set = false);
		bool CanBank(bool set = false);
		void LoadBits(char * bitz);
};

class Kingdom : public Cabal
{	private:
		int id;
		char *name;
		Faction *initial;
		int initId;
		AREA_DATA *pArea;
		std::list<Faction *> factions;

	public:
		static std::list<Kingdom *> List;
		Kingdom();
		Member *findMember(int index);
		Faction * findFaction(int index);
		void Induct(CHAR_DATA *ch);
		void LoadFactions();				
		static void Load()
		{	PREPSQL;
			Kingdom *king;
			query << "SELECT * FROM `Kingdoms`";
			if(!(rez = query.Query() ) )
				return;
			if(!mysql_num_rows(rez) )
				return;
			while( ( row = mysql_fetch_row(rez) ) )
			{	king = new Kingdom();
				king->id = atoi(row[0]);
				king->pArea = area_lookup(atoi(row[1]) );
				king->initId = atoi(row[2]);
				free_string(king->name);
				king->name = str_dup(row[3]);
				king->LoadBits(row[4]);
				king->LoadFactions();
			}
			mysql_free_result(rez);
		};
};		

class Member
{	private:
		int charId;
		int id;
		int level;
		CHAR_DATA *ch;
		char *chName;
		Rank *rank;
 		time_t lastOn;
		std::bitset<maxMemberFlags> flags;
	public:
		Member(CHAR_DATA *newMem);
		Member(MYSQL_ROW *row, Rank *to );
		void SetRank(Rank *pos);
		int CharId();
		void Update();
		static Member *Find(int index)
		{	Member *pMem;
			for(KingI kI= Kingdom::List.begin() ; kI != Kingdom::List.end() ; ++kI)
			{	Kingdom *king = (*kI);
				if( (pMem = king->findMember(index) ) )
					return pMem;
			}
			return NULL;
		}
		
};	
			

class Rank : public Cabal
{	private:
		int id;
		char *name;
		Faction *of;
		int recall;
		int auth; //1 - leader. 2. 2nd in command, etc.
		std::list<Member *> members;
	public:
		Rank();
		Rank(MYSQL_ROW *row, Faction *to);
		void LoadMemebers();
		void Update();
		Member *findMember(int index);
		int Auth();
		void Induct(Member *pMem);
		int Id();
		Rank & operator+=(Member *pMem);
};

class Faction : public Cabal
{	private:
		int id;
		char *name;
		std::list<Rank *> ranks;
		Kingdom *of;
		Faction *parent;
		std::list<Faction *> factions;
	public:
		Faction();
		Faction(MYSQL_ROW &row, Kingdom *king);
		void LoadRanks();
		void Update();
		Rank *initRank();
		Member *findMember(int index);
		void Induct(Member *pMem);
		Faction * findFaction(int index);
		Faction & operator+=(Faction *fact);
		Faction & operator+=(Rank *rank);
		static Faction *Find(int index)
		{	Faction *pFac;
			for(KingI i = Kingdom::List.begin() ; i != Kingdom::List.end() ; ++i)
				if( (pFac = (*i)->findFaction(index) ) )
					return king;
			return NULL;
		}
};
#endif