#ifndef _MERC_H
#define _MERC_H
/***************************************************************************
 *  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
 *  Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.   *
 *                                                                         *
 *  Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael          *
 *  Chastain, Michael Quan, and Mitchell Tse.                              *
 *                                                                         *
 *  In order to use any part of this Merc Diku Mud, you must comply with   *
 *  both the original Diku license in 'license.doc' as well the Merc       *
 *  license in 'license.txt'.  In particular, you may not remove either of *
 *  these copyright notices.                                               *
 *                                                                         *
 *  Much time and thought has gone into this software and you are          *
 *  benefitting.  We hope that you share your changes too.  What goes      *
 *  around, comes around.                                                  *
 ***************************************************************************/

/**********************************************************
 * Function defs, and other stuff                         *
 **********************************************************/
#define args(args) args
#define DECLARE_ACNT_FUN(cmd) AC_CMD cmd
#define ACCOUNT_COMMAND(cmd) void cmd(ACCOUNT *pAcnt, char *argument )
#include <list>
#include <mysql/mysql.h>

/**********************************************************
 * Short scalar types.                                    *
 * Diavolo reports AIX compiler has bugs with short types.*
 **********************************************************/
typedef short int sh_int;
class CodeBlob;
extern std::list<CodeBlob *>		codeList;
/**********************************************************
 * Bool definitions for not C++ users                     *
 **********************************************************/
#ifndef __cplusplus
typedef int bool;
#define true 1
#define false 0
#endif

/**********************************************************
 * Standardise ending character for File I/O              *
 **********************************************************/ 

#define		END_CHAR	"$"

/**********************************************************
 * Global Variables                                       *
 **********************************************************/
/******************************************
 * String and memory management parameters*
 ******************************************/
#define		MAX_KEY_HASH			1024
#define		MAX_STRING_LENGTH		4096
#define		MAX_INPUT_LENGTH		1500
#define		MSL						MAX_STRING_LENGTH
#define		MIL						MAX_INPUT_LENGTH

/******************************************
 * Game parameters.                       *
 ******************************************/
#define PULSE_PER_SECOND	    4
#define MAX_ACNT_LEVEL			5

/******************************************
 *  Connection states for Accounts        *
 ******************************************/
#define CON_GET_ACCOUNT_NAME		9
#define CON_CHECK_ACCOUNT_PASSWORD	10
#define CON_CONFIRM_ACCOUNT_NAME	11
#define CON_GET_ACCOUNT_PASSWORD	12
#define CON_CONFIRM_ACCOUNT_PASSWORD	13
#define CON_ACCOUNT_MENU		14
#define CON_OOC_CHAT			15
#define CON_ASK_RECONNECT		16
#define CON_GET_MUD			17
#define CON_GET_URL			18

/******************************************
 * Values for asprintf                    *
 ******************************************/
#define TO_CHAR				0
#define NOTCHAR_WORLD		1
#define NOTVICT_WORLD		2
#define TO_VICT				3
#define TO_WORLD			4
#define NOTARGET_WORLD		5

/******************************************
 * Log types                              *
 ******************************************/
#define LOG_BUG				0
#define LOG_SITE			1
#define LOG_CMD				2
#define LOG_TYPO			3
#define LOG_BANS			4
#define LOG_MAX				5

/******************************************
 * OBJ declaration for Command Interpreter*
 ******************************************/

#define DIR_OBJ		0
#define INDIR_OBJ		1
#define CMDOBJ_MAX		2

/******************************************
 * Structure ID's                         *
 ******************************************/
#define CHID			0
#define OBJID			1
#define ACNTID			3
#define MAX_STRUCT_ID	4

/**********************************************************
 * Bit Vector Variables                                   *
 **********************************************************/

/******************************************
 * Common Flags Bits                      *
 ******************************************/
#define COMMON_AFK			0
#define COMMON_BANNED			1
#define COMMON_LINKDEAD			2
#define COMMON_MAX			3
/******************************************
 * Channel Flags Bits                     *
 ******************************************/
#define CHANNEL_MAX					11

/**********************************************************
 * Structure types.                                       *
 **********************************************************/
typedef struct	descriptor_data		DESCRIPTOR_DATA;
typedef struct	account_data		ACCOUNT;
typedef struct	accnt_cmd_data		ACNT_CMD;
typedef void	AC_CMD				args( (ACCOUNT *pAcnt, char *argument ) );

/**********************************************************
 * Structure Types                                        *
 **********************************************************/
/******************************************
 * Structure for Log types with file path *
 ******************************************/

struct log_type
{	int log_value;
	char *string;
	char *path;
};


/******************************************
 * Structure Definition for Colour        *
 ******************************************/
struct colour_type
{	char * name;
	char * symbol;
	char * code;
};

/******************************************
 * Structure for Account command functions*
 ******************************************/
struct acnt_cmdfun_type
{	char *name;
	AC_CMD *do_fun;
};

/******************************************
 * Descriptor (channel) structure.        *
 ******************************************/
struct descriptor_data
{
    DESCRIPTOR_DATA *next;
    DESCRIPTOR_DATA *snoop_by;
    ACCOUNT *account;
	char *host;
    sh_int descriptor;
    sh_int connected;
    bool fcommand;
    char inbuf[4 * MAX_INPUT_LENGTH];
    char incomm[MAX_INPUT_LENGTH];
    char inlast[MAX_INPUT_LENGTH];
    int repeat;
    char *showstr_head;
    char *showstr_point;
    char *outbuf;
    int outsize;
    int outtop;
    int pagelen;
    void *pEdit;
    char **pString;	/* OLC */
};
class Topic;
class Post;
class Channel;
class Buffer;
/******************************************
 * One Account                            *
 ******************************************/
struct account_data
{	ACCOUNT		*	next;
	DESCRIPTOR_DATA	*	desc;
	char		*	name;
	char		*	password;
	char		*	afk_string;
	int			level;
	int			struct_id;
	int			common_flags[COMMON_MAX];
	int			nest;
	char		*	read;
	bool			editing;
	int			channel[CHANNEL_MAX];
	AC_CMD		*	lastfun;
	int			lastTID[CHANNEL_MAX];
	char		*	mud;
	char		*	url;
	int			initLogin;
	int			bufPos;
	int			bufEnd;	
	Buffer		*	buffer;
	char		*	custPost;
	char		*	custReply;
	char		*	custTopic;
	ACCOUNT 	*	reply;
	std::list<Topic *>	ignore[CHANNEL_MAX];
	char	*		genChanPrefix(Post *post, Topic *topic = NULL);
	void			addIgnore(Topic *topic, int );
	void			remIgnore(Topic *topic, int );
	bool			isIgnoring(Topic *topic, int );
	bool			canSend(Topic *topic, Channel *channl);
	void			page();
	void			sendChanHelp();
	void			showIgnore(Channel *);
	void			showLocked(Channel *);
};

/******************************************
 * One Account Command                    *
 ******************************************/
struct accnt_cmd_data
{	char		*	name;
	AC_CMD		*	do_fun;
	ACNT_CMD	*	next;
	int				level;
};

/******************************************
 * One Attendant                          *
 ******************************************/
class Attendant
{    public:
	char *name;
	char *mud;
	char *url;
};

/******************************************
 * One buffer                             *
 ******************************************/
class Buffer
{	public:
		std::list<std::string *> lines;
		int pos;
		int finish;
		bool isBlob;
		void Empty();
		void Send(ACCOUNT *pAcnt);
		void Add(char *fmt, ... );
		void AddBlob(char *);
};

/******************************************
 * One Code Blob                          *
 ******************************************/
class CodeBlob
{	public:
		int id;
		char *blob;
		char *language;
		char *poster;
		char *subject;
		int viewed;
		Buffer *buffer; //This shall be the buffer everyone looks at.
				//Should speed it up a bit.
		CodeBlob(MYSQL_ROW row);
		static CodeBlob *find(int id)
		{	std::list<CodeBlob *>::iterator i;
			for( i = codeList.begin() ; i != codeList.end() ; ++i )
			{	if(id == (*i)->id)
					return (*i);
			}
			return NULL;
		}
};

/**********************************************************
 * Macro's                                                *
 **********************************************************/

/******************************************
 * Utility macros.                        *
 ******************************************/
#define UMIN(a, b)		((a) < (b) ? (a) : (b))
#define UMAX(a, b)		((a) > (b) ? (a) : (b))
#define URANGE(a, b, c)		((b) < (a) ? (a) : ((b) > (c) ? (c) : (b)))
#define LOWER(c)		((c) >= 'A' && (c) <= 'Z' ? (c)+'a'-'A' : (c))
#define UPPER(c)		((c) >= 'a' && (c) <= 'z' ? (c)+'A'-'a' : (c))

/******************************************
 * Account Macro's                        *
 ******************************************/
#define ACNT_LEVEL(wAcnt)		( (wAcnt)->level )
#define INIT_BUFFER(pAcnt)		\
if(!(pAcnt)->buffer) \
{	pAcnt->buffer = new Buffer(); \
	pAcnt->buffer->pos = 0; \
}

#define CUSTREPLY "{r[{WT{D:{W%t{r][{WP{D:{W%p{r]{W In reply to {D%R{r[{WP{D:{W%r{r] {W%A {Dsays{r:{W"
#define CUSTPOST "{r[{WT{D:{W%t{r][{WP{D:{W%p{r] {W%A{D says{r:{W"
#define CUSTTOPIC "{W%a has started a new topic{r[{WT{D:{W%t{r]{D: {W%T"
/******************************************
 * Character Macro's                      *
 ******************************************/


/******************************************
 * File I/O Macro's for reading.          *
 ******************************************/
#define IREAD(sKey, sPtr)             \
{                                     \
  if (!strcasecmp(sKey, word))           \
  {                                   \
    int sValue = fread_number(fp);    \
    sPtr = sValue;                    \
	continue;						  \
  }                                   \
}
#define SREAD(sPtr)					  \
{                                     \
    char *sValue = fread_string(fp);  \
	free_string(sPtr);				  \
	sPtr = str_dup(sValue);           \
}

/******************************************
 * Bit Macro's                            *
 ******************************************/
#define IS_SET(bArry, bit)      ( ( (bArry[(bit)]) ) )
#define SET_BIT(bArry, bit)		( ( (bArry[(bit)]) = true ) )
#define UNSET_BIT(bArry, bit )	( ( (bArry[(bit)]) = false ) )
#define TOGGLE_BIT(bArry, bit ) ( ( (bArry[(bit)]) ? UNSET_BIT((bArry), (bit)) : SET_BIT((bArry), (bit) ) ) )

/**********************************************************
 * Global Lists                                           *
 **********************************************************/
extern DESCRIPTOR_DATA		*	descriptor_list;
extern DESCRIPTOR_DATA		*	descriptor_free;
extern ACCOUNT				*	account_list;
extern time_t current_time;
extern ACNT_CMD				*   acnt_cmd_list;
extern ACNT_CMD				*   acnt_cmd_last;
extern std::list<Attendant *>		attendant_list;

/******************************************
 *global Booliens for the Copyover Code   *
 ******************************************/
extern bool	iCopyover; //A bool to tell if the muds in copyover mode for the new process
extern bool	oCopyover; //A bool to tell if the muds in copyover mode for the old process
extern bool	dCopyover; //A bool for the copyover.done file

/******************************************
 * Greet String                           *
 ******************************************/
extern char *help_greeting;

/**********************************************************
 * Our function prototypes.                               *
 * One big lump ... this is every function in Merc.       *
 **********************************************************/
#define DD  DESCRIPTOR_DATA
#define AC  ACNT_CMD
/******************************************
 * account.c                              *
 ******************************************/
ACCOUNT	*	load_account		args((DESCRIPTOR_DATA *d, char *name));
void		send_accnt_menu		args((ACCOUNT *pAcnt ));
void		account_gen			args((DESCRIPTOR_DATA *d, char *arg ));
void		interp_acnt_cmd		args((ACCOUNT *pAcnt, char *argument ));
void		load_accnt_cmds		args(());
AC_CMD  *	acntdofun_lookup	args(( const char *name ));
void		save_account		args((ACCOUNT *pAcnt ));
ACCOUNT *	get_account			args(( const char *name ));
void 		reconnect_account	(ACCOUNT *pAcnt );
bool 		check_reconnect		(ACCOUNT *pAcnt );


/******************************************
 * colour.c                               *
 ******************************************/
char    *	colour_string		args(( const char *txt ));

/******************************************
 * comm.c                                 *
 ******************************************/
void		close_socket		args((DESCRIPTOR_DATA * dclose));
void		write_to_buffer		args((DESCRIPTOR_DATA * d, const char *txt, int length));
void		show_string			args((DESCRIPTOR_DATA * d, char *input));
char    *	capitalize			args(( const char *str ));
bool		file_exists			args(( const char *path ));
void		logfp					args((int log_value, char *fmt, ... ));
void		acnt_act			args((ACCOUNT *ch, void *vo, int to_flag, char *fmt, ... ));
void		copyover_loop		args(());
bool		check_parse_name	args((char *name));
void		recover_accounts	args(());
void		ptc					args((ACCOUNT *ch, char *fmt, ...));
void seperateArgs(char *string, char *arg1, char *arg2);
void disarmString(char *);
void addAttendant(ACCOUNT *pAcnt);
void infoChan(char *txt, ...);
/******************************************
 * db.c                                   *
 ******************************************/
void		boot_db				args((void));
void    *	alloc_mem			args((int sMem));
void    *	alloc_perm			args((int sMem));
void		free_mem			args((void *pMem, int sMem));
char	*	str_dup				args((const char *str));
void		free_string			args((char *pstr));
void		tail_chain			args((void));
int			fread_number		args(( FILE *fp ));
char	*	fread_string		args(( FILE *fp ));
char	*	fread_word			args(( FILE *fp ));
bool		str_prefix			args(( const char *astr, const char *bstr ));
bool		is_number			args((char *arg));
char	*	one_argument		args((char *argument, char *arg_first));
void		load_greet			args(());
void		fread_to_eol		args(( FILE *fp ));

/******************************************
 * htmlParser.c                           *
 ******************************************/
char *readTillTag(char *tag, char *blob);
char *grabNextEntity(char *blob, char *tag, char prelim);
char *parseHtmlString(char *blob);

/******************************************
 * recycle.c                              *
 ******************************************/
DD *		copyover_desc		args((void));
ACCOUNT *	account_new			args(());
void		free_account		args((ACCOUNT *pAcnt ));
void		free_acnt_cmd		args((ACNT_CMD *cmd));
AC		*	acnt_cmd_new		args(());
/******************************************
 * string.c                               *
 ******************************************/
void		string_append		args(( ACCOUNT *ch, char **pString ));
void		string_add			args(( ACCOUNT *ch, char *argument ));
char * string_replace( char * orig, char * old, char * snew );

#undef  DD
#undef  AC
/**********************************************************
 * File path declarations (For File I/O)                  *
 **********************************************************/

#define DATA_DIR		"../data/"		//General Data dir.
#define CMD_DIR			"cmd/"			//Command directory. In Data Directory
#define ACNT_CMD_FILE	"cmd.accnt"		//Command file for Accounts.
#define EXE_FILE		"../src/tor"	//The execution file
#define ACCOUNT_DIR		"../account/"   //Account Directory

#endif