/* The Other Realm Account Code */

#include <sys/types.h>
#include <sys/time.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
#include "include.h"

extern const struct	acnt_cmdfun_type acnt_cmdfun_table[];

void account_gen(DESCRIPTOR_DATA *d, char *arg )
{	ACCOUNT *pAcnt;
	char buf[MSL];

	if(d->account) pAcnt = d->account;
	switch(d->connected)
	{	case CON_GET_ACCOUNT_NAME:
			if( ( pAcnt = load_account(d, arg ) ) == NULL )
			{	sprintf(buf, "{DWelcome to The Other Realm. The account by the name {r'{W%s{r'{D\r\n" 
							 "was not found. Your account name is rarely used; mostly for OOC purposes\n\r"
							 "such as in the who list, global channels, and the like. By choosing this\n\r"
							 "this name, you will not be able to create a character with the same name.\n\r"
							 "If this is a problem, use another name. You do not need to keep the name\n\r"
							 "Rpish, {r({WUnlike the name of your character{r){D however, you should keep\n\r"
							 "it decent. As it will be shown globally. {r({WIe. No swearing, racial slurs and the like.{r){D\n\r"
							 "\n\rWould you like to create a new account, going by that name? {r[{WY{D/{WN{r]{x\n\r", capitalize(arg) );
				write_to_buffer(d, buf, 0 );
				pAcnt = account_new();
				pAcnt->name = str_dup(capitalize(arg) );
				d->account	= pAcnt;
				pAcnt->desc = d;
				d->connected = CON_CONFIRM_ACCOUNT_NAME;
				return;
			}


			write_to_buffer(d, "{DPlease enter your password\n\r{W-->", 0 );
			d->connected = CON_CHECK_ACCOUNT_PASSWORD;
			return;
		case CON_CONFIRM_ACCOUNT_NAME:
			switch(UPPER(arg[0] ) )
			{	case 'Y':
					sprintf(buf, "{W%s{D it is! Welcome. Now, we require a password for your account\n\r{W-->{x", pAcnt->name );
					write_to_buffer(d, buf, 0);
					d->connected = CON_GET_ACCOUNT_PASSWORD;
					break;
				case 'N':
					write_to_buffer(d, "{DOk then. What shall your name be?{x\n\r", 0);
					free_account(pAcnt);
					d->connected = CON_GET_ACCOUNT_NAME;
					break;
				default:
					write_to_buffer(d, "{DPlease choose either {WY{Des, or {WN{Do{x.\n\r",0);
					break;
			}
			break;
		case CON_GET_ACCOUNT_PASSWORD:
			while(isspace(*arg)) arg++;
			if(arg[0] == '\0' )
			{	write_to_buffer(d, "{DWhat type of password is that!? Please choose another\n\r{W-->",0);
				return;
			}
			pAcnt->password = str_dup(arg);
			write_to_buffer(d, "{DPlease retype so that we can confirm your password.\n\r{W-->", 0 );
			d->connected = CON_CONFIRM_ACCOUNT_PASSWORD;
			return;
		case CON_CONFIRM_ACCOUNT_PASSWORD:
			if(!strcmp(pAcnt->password, arg ) )
			{	write_to_buffer(d, "{DPassword confirmed.\n\r", 0);
				sprintf(buf, "{DWelcome to The Other Realm, {W%s{D. Please choose an option.\n\r\n\r", pAcnt->name );
				write_to_buffer(d, buf, 0);
				write_to_buffer(d, "No choice for you! To the Chat with you! Play with the Forums!\n\r", 0);
				d->connected = CON_OOC_CHAT;
				return;
			}
			free_string(pAcnt->password);
			write_to_buffer(d, "{DPasswords did not match. What would you like your password to be?\n\r{W-->", 0 );
			d->connected = CON_GET_ACCOUNT_PASSWORD;
			return;
		case CON_CHECK_ACCOUNT_PASSWORD:
			if(!strcmp(arg, pAcnt->password ) )
			{	sprintf(buf, "{DWelcome back to The Other Realm, {W%s{D. Please choose an option.\n\r\n\r", pAcnt->name );
				write_to_buffer(d, buf, 0);
				write_to_buffer(d, "No choice for you! To the Chat with you! Play with the Forums!\n\r", 0);
				d->connected = CON_OOC_CHAT;
				return;
			}
			write_to_buffer(d, "{DSorry, that password was incorrect.\n\r",0 );
			close_socket(d);
			free_account(pAcnt);
			return;
		case CON_ACCOUNT_MENU:
			if(arg[0] == '\0' )
			{	send_accnt_menu(pAcnt);
				return;
			}

			switch (arg[0])
			{	case '1':
					write_to_buffer(d, "{DWelcome to The Other Realm Chat Room, for OOC chatter.\n\r",0);
					d->connected = CON_OOC_CHAT;
					break;
				case '2':
					write_to_buffer(d, "The Forums havn't been written!\n\r", 0 );
  				return;
			  default: send_accnt_menu(pAcnt);
			  					break;
			}
			break;

		default: write_to_buffer(d, "You suck\n\r",0); break;
	}
	return;
			
}


void send_accnt_menu(ACCOUNT *pAcnt )
{	write_to_buffer(pAcnt->desc, "{D*****************************************************\n\r",0 ); 
	write_to_buffer(pAcnt->desc, "{D* * * * * * * * * * * * * * * * * * * * * * * * * * *\n\r",0 ); 
	write_to_buffer(pAcnt->desc, "{D*****************************************************\n\r",0 ); 
	write_to_buffer(pAcnt->desc, "{D* *{W          Other Realm Account Menu             {D* *\n\r",0 ); 
	write_to_buffer(pAcnt->desc, "{D*{r*{D*{W Please choose one of the Following Options    {D*{r*{D*\n\r",0 ); 
	write_to_buffer(pAcnt->desc, "{D* ************************************************* *\n\r",0 ); 
	write_to_buffer(pAcnt->desc, "{D*{r*{D* * * * * * * * * * * * * * * * * * * * * * * * *{r*{D*\n\r",0 ); 
	write_to_buffer(pAcnt->desc, "{D* ************************************************* *\n\r",0 );
  write_to_buffer(pAcnt->desc, "{D* {r({D1{r){w Log into Chat           {r({D2{r){w Check MUD-Forum   {D*\n\r",0 );
	write_to_buffer(pAcnt->desc, "{D*****************************************************\n\r",0 ); 
	write_to_buffer(pAcnt->desc, "{D* * * * * * * * * * * * * * * * * * * * * * * * * * *\n\r",0 ); 
	write_to_buffer(pAcnt->desc, "{D*****************************************************\n\r",0 ); 
	write_to_buffer(pAcnt->desc, "{D\n\rPlease choose an option\n\r{W-->", 0 );
	return;
}



void interp_acnt_cmd(ACCOUNT *pAcnt, char *argument )
{	ACNT_CMD *pCmd;
	char cmd[MSL];

	while(isspace(*argument)) argument++;
	if(argument[0] == '\0' )
		return;
	argument = one_argument(argument,cmd);
	for(pCmd = acnt_cmd_list ; pCmd ; pCmd = pCmd->next )
	{	if (LOWER(cmd[0]) == LOWER(pCmd->name[0])
        &&  !str_prefix( cmd,pCmd->name))
        {	if(pCmd->level > pAcnt->level )
				break;
			( *pCmd->do_fun ) (pAcnt, argument );
			return;
		}
	}
	write_to_buffer(pAcnt->desc, "That isn't a valid command.\n\r",0 );
	return;
}

void load_accnt_cmds()
{	FILE *fp;
	ACNT_CMD *pCmd;
	char *word;
	char buf[MSL];

	sprintf(buf, "%s%s%s", DATA_DIR, CMD_DIR, ACNT_CMD_FILE );
	if( ( fp = fopen(buf, "r") ) == NULL )
	{	perror(buf);
		return;
	}

	for(word = fread_word(fp); strcasecmp(word, END_CHAR); word = fread_word(fp) )
	{	if(!strcasecmp(word, "name" ) )
		{	pCmd = acnt_cmd_new();
			if(!acnt_cmd_list)
				acnt_cmd_list = pCmd;
	
			if(acnt_cmd_last)
				acnt_cmd_last->next = pCmd;

			acnt_cmd_last = pCmd;
			SREAD(pCmd->name);
			continue;
		}
		if(!strcasecmp(word, "dofun" ) )
		{	if( (pCmd->do_fun = acntdofun_lookup(fread_string(fp)) ) == NULL ) //When I get a logging function. Gotta be added here.
			{	logfp("CmdFun not found: %s" word);
				break;
			}
			continue;
		}

		IREAD("Lvl", pCmd->level );
		

		//Another logging function here to state that something wasn't valid.
	}
	fclose(fp);
	return;
}

AC_CMD * acntdofun_lookup( const char *name )
{	int cmd;
	for( cmd = 0; acnt_cmdfun_table[cmd].name != NULL; cmd++ )
	{	if(LOWER(name[0]) == LOWER(acnt_cmdfun_table[cmd].name[0])
		&& !str_prefix(name, acnt_cmdfun_table[cmd].name ) )
			return acnt_cmdfun_table[cmd].do_fun;
	}
	return NULL;
}

void save_account(ACCOUNT *pAcnt )
{	FILE *fp;
	char buf[MSL];
	int i;

	sprintf(buf, "%s%s", ACCOUNT_DIR, pAcnt->name );
	if( ( fp = fopen(buf, "w" ) ) == NULL )
	{	logfp(LOG_BUG, "SAVE_ACCOUNT: Failed on Fopen, %s\n", pAcnt->name );
		return;
	}

	fprintf(fp, "Name %s~\n", pAcnt->name );
	fprintf(fp, "Pswd %s~\n", pAcnt->password );
	fprintf(fp, "Lvl  %d\n", pAcnt->level );
	fprintf(fp, "CmnF " ); save_flags(common_table, fp, COMMON_MAX, pAcnt->common_flags );
	if(IS_SET(pAcnt->common_flags, COMMON_AFK ) )
		fprintf(fp, "AfkS %s~\n", pAcnt->afk_string );
	fprintf(fp, "Read %s~\n", pAcnt->read );
	fprintf(fp, "%s\n", END_CHAR );
	fclose(fp);
	return;
}

ACCOUNT *load_account(DESCRIPTOR_DATA *d, char *name)
{	FILE *fp;
	char buf[MSL];
	char *word;
	ACCOUNT *pAcnt;
	int char_spot = 0;

	sprintf(buf, "%s%s", ACCOUNT_DIR, capitalize(name) );
	if( ( fp = fopen(buf, "r" ) ) == NULL )
		return NULL;
	pAcnt = account_new();
	for(word = fread_word(fp); strcmp(word, END_CHAR); word = fread_word(fp) )
	{	if(!strcasecmp(word, "Name" ) )
		{	SREAD(pAcnt->name);
			continue;
		}
		if(!strcasecmp(word, "Pswd" ) )
		{	SREAD(pAcnt->password);
			continue;
		}
		if(!strcasecmp(word, "Read") )
		{	SREAD(pAcnt->read);
			continue;
		}
		if(!strcasecmp(word, "CmnF" ) )
		{	load_flags(common_table, fp, COMMON_MAX, pAcnt->common_flags );
			continue;
		}
		if(!strcasecmp(word, "AfkS" ) )
		{	SREAD(pAcnt->afk_string );
			continue;
		}
		IREAD("lvl", pAcnt->level );
		logfp(LOG_BUG, "Unexpected reference in Account file %s: %s\n",name, word );
		continue;
	}
	d->account	= pAcnt;
	pAcnt->desc = d;
	return pAcnt;
}


ACCOUNT * get_account( const char *name )
{	ACCOUNT *pAcnt;
	
	for(pAcnt = account_list; pAcnt ; pAcnt = pAcnt->next )
	{	if(LOWER(pAcnt->name[0]) == LOWER(name[0]) 
		&& !str_prefix(name, pAcnt->name ) )
		return pAcnt;
	}
	return NULL;
}

const struct acnt_cmdfun_type acnt_cmdfun_table[] =
{	{ "acnt_who",		acnt_who	},
	{ "acnt_chat",		acnt_chat	},
	{ "acnt_save",		acnt_save	},
	{ "acnt_quit",		acnt_quit	},
	{ "acnt_typo",		acnt_typo	},
	{ "acnt_copyover",	acnt_copyover },
	{ "acnt_command",	acnt_command  },
	{ "acnt_afk",		acnt_afk	  },
	{ "acnt_advance",	acnt_advance  },
	{ "acnt_socket",	acnt_socket	  },
	{ "acnt_filecount", acnt_filecount},
	{ "acnt_olc",		acnt_olc		},
	{ "acnt_forums",	acnt_forums		},
	{ "acnt_thread",	acnt_thread		},
	{ "acnt_romcode",	acnt_romcode	},
	{ "acnt_smaugcode",	acnt_smaugcode	},
	{ "acnt_envycode",	acnt_envycode	},
	{ "acnt_circlecode",acnt_circlecode	},
	{ "acnt_lpccode",	acnt_lpccode	},
	{ "acnt_newbie",	acnt_newbie		},
	{ "acnt_admin",		acnt_admin		},
	{ "acnt_legal",		acnt_legal		},
	{ "acnt_building",	acnt_building	},
	{ NULL,			NULL		}
};