
#include <stdio.h>
#include "config.h"
#include "structs.h"
#include "interpreter.h"
#include "utils.h"
#include "db.h"
#include "functions.h"

/* EXTERNAL VARIABLES */
extern struct grid_index_element *grid_list;
extern struct zone_data *zone_list;
extern struct room_data *tmp_room;
extern struct cmd_mode mode[];
extern char buf[SMALL_BUFSIZE];
extern char buf1[SMALL_BUFSIZE];
extern int max_users, sock_playing, min_login;

void	interpreter(struct descriptor_data *d, char *arg)
{
	/* remove white spaces */
	while(isspace(*arg))
		arg++;

	if(d->connected > CON_PRIVATE) {
		((*mode[CON_PRIVATE].mode_pointer)(d->character,arg));
	} else {
		((*mode[d->connected].mode_pointer)(d->character,arg));
	}
}

/***************************************************************************
	Routines for the various connections (ie. editing, password entry, etc.)
***************************************************************************/
void	con_name(struct char_data *ch, char *arg)
{
	struct char_save_data tmp_store;
	int length;

	if(!*arg) {
		change_status(ch, CON_CLOSE);
		return;
	}

	length=_parse_name(buf1, arg);
	if(length <= 3 || length > MAX_NAM_LEN) {
		send_2_output("\033[31mInvalid name!\033[0m\n\rName: ",ch->desc);
		return;
	}
	/* Convert first letter to upper case */
	*buf1 = *buf1 & 223;

	/* Does player already exist? */
	if((ch->IDNUM=load_char(buf1,&tmp_store)) > -1 && !BTST(tmp_store.SPECIALS,DELETED)) {
		store_2_char(&tmp_store,ch);
		send_2_output(echo_off,ch->desc);

		/* Check if there are too many people connected */
		if((sock_playing >= max_users) && ch->LEVEL < IMP) {
			send_2_output("\033[31mThere are too many people connected at the moment.\033[0m\n\rPlease try again later.\n\r",ch->desc);
			change_status(ch, CON_CLOSE);
			return;
		} else if(ch->LEVEL < min_login) {
			sprintf(buf,"\033[31mSorry, game locked at level %d\033[0m\n\r",min_login);
			send_2_output(buf,ch->desc);
			change_status(ch, CON_CLOSE);
		} else {
			sprintf(buf,"\033[1m\033[33m%s\033[0m exists!\n\rPlease enter password: ",ch->name);
			send_2_output(buf,ch->desc);
			change_status(ch, CON_PWDNRM);
		}
	} else {
		/* We have to create one! */
                printf("[%d][%d]\n",sock_playing,max_users);
		if(sock_playing >= max_users) {
			send_2_output("\033[31mThe maximum number of users allowed has been exceeded.\033[0m\n\rPlease try again later.\n\r",ch->desc);
			change_status(ch, CON_CLOSE);
		} else if(min_login) {
			send_2_output("\033[31mSorry, but new characters are not being generated\033[0m\n\r",ch->desc);
			change_status(ch, CON_CLOSE);
		} else {
			strncpy(ch->name,buf1,MAX_NAM_LEN);
			sprintf(buf, "\033[1mNew character.\033[0m\n\rIs '%s' your name? (Y/N): ", buf1);
			send_2_output(buf,ch->desc);
			change_status(ch, CON_NMECNF);
		}
	}
	if(DEBUG_CHAR)
		printf("%s has connected.\n",ch->name);
}

void	con_nmecnf(struct char_data *ch,char *arg)
{
	if(*arg == 'y' || *arg =='Y') {
		send_2_output(echo_off,ch->desc);
		send_2_output("Please enter a password for this character: ",ch->desc);
		change_status(ch, CON_PWDGET);
		return;
	} else {
		send_2_output("What is your name then?: ",ch->desc);
		change_status(ch, CON_NME);
		return;
	}
}

void	con_pwdnrm(struct char_data *ch, char *arg)
{
	extern struct descriptor_data *desc_list;
	struct descriptor_data *desc, *tmp_desc, *tmp_d, *next_desc;
	struct char_data *tmp_char;
	int	 tmp_int;
	char	 tmp_byte;

	if(!*arg) {
		send_2_output(echo_on,ch->desc);
		send_2_output("\033[31mAborted!\033[0m\n\rEnter your name: ",ch->desc);
		change_status(ch, CON_NME);
		return;
	}  /* else if(strncmp(crypt(arg,ch->pwd),ch->pwd,MAX_PWD_LEN)) {
		send_2_output("\n\r\033[31mWrong password... bye!\033[0m\n\r",ch->desc);
		ch->BAD_PWDS++;
		save_char(ch);
		change_status(ch, CON_CLOSE);
		return;
	}
*/

	send_2_output(echo_on,ch->desc);
	if(ch->BAD_PWDS) {
		sprintf(buf1,"\nThere has been \033[31m%d\033[0m password failure(s) since last login\n\n\r",ch->BAD_PWDS);
		send_2_output(buf1,ch->desc);
		ch->BAD_PWDS=0;
	}

	for(desc=desc_list;desc;desc=next_desc) {
		next_desc=desc->next_in_list;
		if(!shrt_cmp(ch->name,desc->character->name) && ch->desc != desc) {

			/* Exchange the characters */
			tmp_char = desc->character;
			tmp_desc = ch->desc;
			
			desc->character = ch;
			ch->desc = desc;

			ch = tmp_char;
			ch->desc = tmp_desc;
			tmp_desc->character = ch;
			
			/* Send the other character to purgatory */
			desc->character->in_room = 0;

			/* Tidy the place up */
			if(desc->connected == CON_LINKLESS) {
				send_2_output("\033[36mYou are returned to your lonely body...\033[0m\n\r",ch->desc);
				sprintf(buf,"has come out of %s shell.\n\r",sex[ch->SEX].b);
				send_2_room(ch,IGNR_INVIS,buf);
			} else {
				send_2_output("\033[33mYou usurp a body already in existance!\033[0m\n\r", ch->desc);
				send_2_output("\n\r\033[1mGoodbye!\n\rYour body has been snatched...\033[0m\n\r",desc);
			}
			change_status(desc->character, CON_CLOSE);
			change_status(ch, CON_PLYNG);
			return;
		}
	}
	change_status(ch, CON_PLYNG);
	tmp_room = get_room(ch->LOAD_X,ch->LOAD_Y,ch->LOAD_Z,ch->LOAD_R);
	char_2_room(ch,tmp_room,"has entered the game.");
	return;
}

void  con_pwdget(struct char_data *ch, char  *arg)
{
	if((!*arg || strlen(arg) > 10 || strlen(arg) < 6) || (!str_cmp(arg,ch->name))) {
		send_2_output("\n\r\033[31mIllegal password!\033[0m\n\rPassword: ",ch->desc);
		return;
	}

	//strncpy(ch->pwd, crypt(arg,arg), MAX_PWD_LEN);
	*(ch->pwd+MAX_PWD_LEN)='\0';
	send_2_output("\n\rPlease confirm password: ",ch->desc);
	change_status(ch, CON_PWDCNF);
}

void  con_pwdcnf(struct char_data *ch, char *arg)
{
/*
	if(strncmp(crypt(arg, ch->pwd),ch->pwd, MAX_PWD_LEN)) {
		send_2_output("\n\r\033[31mPasswords don't match!\033[0m - Try again.\n\rPassword: ",ch->desc);
		change_status(ch, CON_PWDGET);
		return;
	}
*/
	send_2_output(echo_on,ch->desc);
	send_2_output("What is your sex? (M/F/N): ",ch->desc);
	change_status(ch, CON_QSEX);
}

void  con_qsex(struct char_data *ch,char *arg)
{
	int	ctr;

	switch(*arg | 32) {
	case 'm':
		ch->SEX=MALE;
		break;
	case 'f':
		ch->SEX=FEMALE;
		break;
	case 'n':
		ch->SEX=NEUTER;
		break;
	default:
		send_2_output("What is your sex? (M/F/N): ",ch->desc);
		return;
		break;
	}
	disp_classes(ch);
//	send_2_output("\n\rSelect a class:\n\r\n\r[C] Cleric.\n\r[M] Mage.\n\r[T] Thief.\n\r[W] Warrior.\n\r[D] Druid.\n\r\n\rClass: ",ch->desc);
	change_status(ch, CON_QCLASS);
}

void  con_qclass(struct char_data *ch,char *arg)
{
	switch(*arg | 32) {
	case 'm':
		ch->CLASS=MAGE;
		break;
	case 'w':
		ch->CLASS=WARRIOR;
		break;
	case 't':
		ch->CLASS=THIEF;
		break;
	case 'c':
		ch->CLASS=CLERIC;
		break;
	case 'd':
		ch->CLASS=DRUID;
		break;
	default:
		disp_classes(ch);
//		send_2_output("\n\rSelect a class:\n\r\n\r[C] Cleric.\n\r[M] Mage.\n\r[T] Thief.\n\r[W] Warrior.\n\r[D] Druid.\n\r\n\rClass: ",ch->desc);
   	return;
		break;
	}

	/* Try and initialise the player and it's home directory */
	if(init_char(ch)) {
		send_2_output("\n\r\033[31mMajor hassle, man...\033[0m\n\r\033[1mAn error occurred while trying to create a home for you.\033[0m\n\r",ch->desc);
		change_status(ch, CON_CLOSE);
		return;
	}

	/* See if we need to create a new entry */
	if(ch->IDNUM < 0)
		ch->IDNUM=create_char_entry(ch->name);

	/* Save the character */
	// CRTH - had to move the save after char_2_room cuz it buggered it all
	// up if you have the SAVE_LOC_NUM switched on.
	change_status(ch, CON_REROLL);
	do_score(ch);
	send_2_output("Are you happy with these stats (Y/N)?: ",ch->desc);
}

int _parse_name(char *buf1, char *arg)
{
	int c=0;

	while(*arg > 64 && *arg < 123) {
		*buf1++ = *arg++ | 32;
		c++;
	}
	*buf1='\0';
	return(c);
}
void	con_reroll(struct char_data *ch,char *arg)
{
	switch(*arg)
	{
		case 'y':
		case 'Y':	tmp_room = get_room(ch->LOAD_X,ch->LOAD_Y,ch->LOAD_Z,ch->LOAD_R);
						char_2_room(ch,tmp_room,"has entered the game.");
						// Setup save paths - moved from init_char in db.c
						sprintf(ch->home,"%s%c/%s",PLAYER_PATH,(*ch->name | 32),ch->name);
						sprintf(ch->bin,"%s.bin",ch->home);
						if(ch->LEVEL < IMP)
						{
							obj_2_char(clone_object(10,NEW_OBJECT),ch);
							obj_2_char(clone_object(11,NEW_OBJECT),ch);
						}
						save_char(ch);
						change_status(ch, CON_PLYNG);
						break;
		case 'n':
		case 'N':	send_2_output("What is your sex? (M/F/N): ",ch->desc);
						change_status(ch, CON_QSEX);
						break;	
		default :	send_2_output("Are you happy with these stats (Y/N)?: ",ch->desc);
						break;
	}
}
void	disp_classes(struct char_data *ch)
{
	int	ctr;

	send_2_output("Select a class:\n\r\n\r",ch->desc);
	for(ctr = 1;ctr<6;ctr++)
	{
		if(ctr != 3)
			sprintf(buf,"[%c] %s.\n",class[ctr].full[5],class[ctr].full);
		else
			sprintf(buf,"[%c] %s.\n",class[ctr].full[9],class[ctr].full);
		send_2_output(buf,ch->desc);
	}
	send_2_output("\n\rClass: ",ch->desc);
}

