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

/* VARIABLES */
extern struct _col_table_ col_table[];
extern struct descriptor_data *desc_list;
extern struct player_index_element *player_table;

extern int  top_of_p_table;
extern char buf[SMALL_BUFSIZE];
extern char buf1[SMALL_BUFSIZE];
extern char buf2[SMALL_BUFSIZE];

struct descriptor_data *desc, *desc_next;
struct char_data *who, *who_next;

void  do_gossip(struct char_data *ch, char *arg)
{
   if(!get_arg(buf,arg,-1)) {
      send_2_output("What do you want to gossip about?\n\r",ch->desc);
      return;
   }

   sprintf(buf1,"\033[35mgossips %s\033[0m",buf);

   for(desc=desc_list;desc;desc=desc_next) {
      desc_next=desc->next_in_list;
      if(ch->desc != desc && !BTST(desc->character->PREFS,NO_GOSS))
         send_2_char(ch,desc->character,INVIS_CHK,buf1);
   }

   sprintf(buf1,"\033[35mYou gossip %s\033[0m\n\r",buf);
   send_2_output(buf1,ch->desc);

   return;
}

void  do_tell(struct char_data *ch, char *arg)
{
   if(!get_arg(buf,arg,1) || !get_arg(buf1,arg,-2)) {
      send_2_output("Tell who, what??\n\r",ch->desc);
      return;
   } else if(!shrt_cmp(buf,ch->name)) {
      send_2_output("I suggest you see a doctor.\n\r",ch->desc);
      return;
   }

   if(((who = get_player(buf)) && see_char_chk(ch,who))) {
   	if(BTST(who->PREFS,NO_TELL) || who->CON_STATE != CON_PLYNG) {
      	send_2_output("They can't hear you at the moment.\n\r",ch->desc);
         return;
      } else {
         sprintf(buf,"\033[1mtells you %s\033[0m",buf1);
         send_2_char(ch,who,INVIS_CHK,buf);
         sprintf(buf,"\033[1mYou tell %s %s\033[0m\n\r",who->name,buf1);
         send_2_output(buf,ch->desc);
         return;
      }
   }
   send_2_output("They don't appear to be around...\n\r",ch->desc);
   return;
}

void  do_say(struct char_data *ch, char *arg)
{
   if(!get_arg(buf,arg,-1)) {
      send_2_output("You don't have much to say, do you?\n\r",ch->desc);
      return;
   }

	if(ch->STATE < STAT_OK)
	{
		int	ctr;
		for(ctr = 0;ctr < strlen(buf);ctr++)
		{
			if(rand() % 100 <= 34)
				buf[ctr] = toupper(buf[ctr]);
		}
	}

   sprintf(buf1,"\033[1m\033[32msays %s\033[0m",buf);
   send_2_room(ch,INVIS_CHK,buf1);

   sprintf(buf1,"\033[1m\033[32mYou say %s\033[0m\n\r",buf);
   send_2_output(buf1,ch->desc);
   return;
}

void  do_no_msg(struct char_data *ch, char *arg)
{
   if(!shrt_cmp(arg,"notell")) {
      if(BTST(ch->PREFS,NO_TELL)) {
         send_2_output("notell off.\n\r",ch->desc);
      } else {
         send_2_output("notell on.\n\r",ch->desc);
      }
      BCHG(ch->PREFS,NO_TELL);
   } else if(!shrt_cmp(arg,"brief")) {
      if(BTST(ch->PREFS,BRIEF)) {
         send_2_output("Brief mode off.\n\r",ch->desc);
      } else {
         send_2_output("Brief mode on.\n\r",ch->desc);
      }
      BCHG(ch->PREFS,BRIEF);
   } else if(!shrt_cmp(arg,"nogossip")) {
      if(BTST(ch->PREFS,NO_GOSS)) {
         send_2_output("nogossip off.\n\r",ch->desc);
      } else {
         send_2_output("nogossip on.\n\r",ch->desc);
      }
      BCHG(ch->PREFS,NO_GOSS);
	}
}

void  do_emote(struct char_data *ch, char *arg)
{
   if(!get_arg(buf,arg,-1)) {
      send_2_output("You keep your emotions to yourself.\n\r",ch->desc);
      send_2_room(ch,INVIS_CHK,"seems unemotional.");
   } else {
      sprintf(buf1,"You emote %s\n\r",buf);
      send_2_output(buf1,ch->desc);
      send_2_room(ch,INVIS_CHK,buf);
   }
   return;
}

void  send_2_inc(struct char_data *ch,char *msg)
{
   /* Are we in a room? */
   if(!IN_ROOM(ch))
      return;

   for(who=ch->in_room->people;who;who=who_next) {
      who_next=who->next_in_room;
         send_2_output(msg,who->desc);
   }
}

void  send_2_room(struct char_data *ch,char invis_chk,char *msg)
{
   /* Are we in a room? */
   if(!IN_ROOM(ch))
      return;

   for(who=ch->in_room->people;who;who=who_next) {
      who_next=who->next_in_room;
      if(who != ch)
         send_2_char(ch,who,invis_chk,msg);
   }
}

void  send_2_xcept(struct char_data *ch, struct char_data *pl, char invis_chk, char *msg)
{
   /* Are we in a room? */
   if(!IN_ROOM(ch))
      return;

   for(who=ch->in_room->people;who;who=who_next) {
      who_next=who->next_in_room;
      if(who != ch && who != pl)
         send_2_char(ch,who,invis_chk,msg);
   }
}

void	send_2_all(struct char_data *ch, char *msg)
{
	extern struct descriptor_data *desc_list;

	for(desc=desc_list;desc;desc=desc_next) {
		desc_next=desc->next_in_list;
		if(ch != desc->character)
         send_2_output(msg,desc);
	}
}

void do_join(struct char_data *ch, char *arg)
{
	int c;

   if(!get_arg(buf,arg,1)) {
      send_2_output("Use: join <player name>\n\r",ch->desc);
      return;
   } else if(!shrt_cmp(buf,ch->name)) {
      send_2_output("Come apart have you?\n\r",ch->desc);
      return;
   }

	/* First see if the user is logged on */
   if(!(who = get_player(buf))) {
		send_2_output("No one here by that name.\n\r",ch->desc);
		return;
	} else if(who->CON_STATE < CON_PRIVATE) {
		sprintf(buf,"%s is not on a channel!\n\r",who->name);
	} else {
		/* Check to see if they want the users company */
		for(c=0;c<MAX_COMPANY;c++) {
			if(!shrt_cmp(who->company[c].name,ch->name)) {
				if(who->CON_STATE == ch->CON_STATE) {
					send_2_output("You are already on the same channel!\n\r",ch->desc);
					return;
				} else if(who->company[c].type != 0) {
					/* Remove the first bit (for the once only invite) */
					BCLR(who->company[c].type,1);

					/* Let everyone know what's happening */
					sprintf(buf,"You join %s on their private channel.\n\r",who->name);
					send_2_output(buf,ch->desc);
					sprintf(buf,"has subscribed to channel %d\n\r",who->CON_STATE);
					send_2_room(ch,IGNR_INVIS,buf);
					change_status(ch,who->CON_STATE);
					sprintf(buf,"%s has joined your channel.\n\r",ch->name);
					send_2_output(buf,who->desc);
					return;
				}
			}
		}
		sprintf(buf,"%s has not invited you on their channel.\n\r",who->name);	
	}
	
	/* The other user WAS logged on - but DID NOT invite this user */
	/* Only report that they were uninvited if they can be seen */
	if(!see_char_chk(ch,who)) {
		send_2_output("No one here by that name.\n\r",ch->desc);
	} else {
		send_2_output(buf,ch->desc);
	}
}

void do_invite(struct char_data *ch, char *arg)
{
	extern char *invite[];
	int c,f;

	if(!get_arg(buf,arg,1)) {
		for(c=f=0;c<MAX_COMPANY;c++) {
			/* Check our invitation list */
			if(ch->company[c].type != 0) {
				f++;
				sprintf(buf,"%12s [%s]\n",ch->company[c].name,invite[ch->company[c].type]);
				send_2_output(buf,ch->desc);
			}
		}
		if(f>0) {
			sprintf(buf,"\nYou have %d characters on invitation.\n\r",f);
			send_2_output(buf,ch->desc);
			return;
		}
	} else if((!get_arg(buf1,arg,2)) || !shrt_cmp(buf1,"always")) {
		for(c=0;c<=top_of_p_table;c++) {
			if(!shrt_cmp(buf,player_table[c].name)) {
				/* Move to a blank invite form */
				for(f=0;f<MAX_COMPANY,ch->company[f].type != 0;f++)
					if(!shrt_cmp(buf,ch->company[f].name))
						break;

				/* Copy the name across */
				if(f != MAX_COMPANY)
					strcpy(ch->company[f].name,player_table[c].name);

				/* Set how many times it is valid for */	
				if(*buf1 == 'a')
					ch->company[f].type = 2;
				else
					ch->company[f].type = 1;

				sprintf(buf,"%s is now on your invitation list.\n\r",ch->company[f].name);
				send_2_output(buf,ch->desc);
				return;
			}
		}
		send_2_output("Could not find anyone by that name in the database.\n\r",ch->desc);
		return;
	}
	send_2_output("Use: invite <name> [always]\n\r",ch->desc);
}

char *cprintf(char *target, const char *format, ...)
{
	va_list 	arg;
	char     *fmt,*op=target;
	char  	ignore=FALSE;
	int 		x,y,c;

	va_start(arg, format);

//	fmt=va_arg(format, char *);
//	printf(fmt);

	while(*fmt != '\0')
	{
		switch(*fmt)
		{
		case '\\':
			//ignore = TRUE;
			break;
		case '%' :
			break;
		case '~' :
			if(*++fmt == '~') {
				printf("[%d]",va_arg(arg,char *));
				//x = atoi(va_arg(arg,char *));
				printf("-%d-",x);
				fflush(NULL);
				x = col_table[x].col[c];
				printf("-%d-",x);
			} else {
				x = (int)*fmt - 65;
			}
			fmt++;
			for(c=0;col_table[x].col[c];c++)
				*target++ = col_table[x].col[c];
			break;
		default:
			*target++ = *fmt++;
			break;
		}
	}

	*target = '\0';

	va_end(arg);

	return(op);
}

