cdirt/ascii/
cdirt/data/BULL/
cdirt/data/ZONES/PENDING/
cdirt/pending/
cdirt/src/utils/
cdirt/utils/

#include "kernel.h"
#include "sflags.h"
#include "pflags.h"
#include "lflags.h"
#include "sendsys.h"
#include "mobile.h"
#include "nflags.h"
#include "bprintf.h"
#include "mud.h"
#include "commands.h"
#include "log.h"

#include <stdarg.h>

extern void noswear(const char *);

struct _send_msg_box {
  int mode;
  int min;
  int max;
  int x1;
  int x2;
  int lang;
};

/* Simple interfaces:
 */
void
broad (char *mesg)
{
  sendf (DEST_ALL, "%s", mesg);
}

void
sillycom (char *txt)
{
  send_msg (ploc (mynum), 0, pvis (mynum), LVL_MAX, mynum, NOBODY,
	    txt, pname (mynum), pname (mynum));
}

void
sillytp (int per, char *msg)
{
  sendf (per, "\001p%s\003 %s\n", pname (mynum), msg);
}

void p_sendto (int to, char *text)
{
  Boolean newstyle;

  if (!is_in_game(to) || !text)
    return;

  setup_globals (to);
  newstyle = ststflg(mynum, SFL_NEWSTYLE);

  if (cur_player->in_cmd) {
    if (newstyle)
      bprintf ("%s", text);
    else
      bprintf ("\n%s", text);
  }
  else {
    if (!ststflg(mynum, SFL_NOSWEAR)) 
      bprintf ("%c%s\r%s", newstyle ? '\r' : '\n', text, cur_player->cprompt);
    else
      noswear(text);
  }
}

/*
 * Values for destination:
 * negative values:            room number.
 * 0..max_players - 1          player with specified index.
 * max_players..numchars - 1   mobile with specified index.
 * DEST_ALL                    all players and mobiles.
 */

static Boolean
test_rcv (int player,		/* Who to send to */
	  int mode,		/* Flags to control sending */
	  int min,		/* Minimum level of recipient */
	  int max,		/* Maximum level of recipient */
	  int x1,		/* Do not send to him */
	  int x2,		/* Nor to him */
	  int lang)
{				/* Language */
  Boolean b;

  if (player == x1 || player == x2)
    return False;
  b = (plev (player) >= min && plev (player) < max);

  switch (lang & (MODE_LANG | MODE_NLANG)) {
  case MODE_LANG:
    b = b && ntstflg (player, lang & MODE_FLAGS);
    break;
  case MODE_NLANG:
    b = b && !ntstflg (player, lang & MODE_FLAGS);
    break;
  }

  if (mode & MODE_NOBLIND)
    b = b && !ststflg (player, SFL_BLIND);
  if (mode & MODE_NODEAF)
    b = b && !ststflg (player, SFL_DEAF);
  if (mode & MODE_NODUMB)
    b = b && !ststflg (player, SFL_DUMB);
  if (mode & MODE_NOCRIP)
    b = b && !ststflg (player, SFL_CRIPPLED);
  if (mode & MODE_QUIET)
    b = b && !ststflg (player, SFL_QUIET);
  if (mode & MODE_OUTDOORS)
    b = b && ltstflg (ploc (player), LFL_OUTDOORS);

  switch (mode & (MODE_PFLAG | MODE_NPFLAG)) {
  case MODE_PFLAG:
    b = b && ptstflg (player, mode & MODE_FLAGS);
    break;
  case MODE_NPFLAG:
    b = b && !ptstflg (player, mode & MODE_FLAGS);
    break;
  }

  switch (mode & (MODE_SFLAG | MODE_NSFLAG)) {
  case MODE_SFLAG:
    b = b && ststflg (player, (mode >> MODE_S) & MODE_FLAGS);
    break;
  case MODE_NSFLAG:
    b = b && !ststflg (player, (mode >> MODE_S) & MODE_FLAGS);
    break;
  }

  return b;
}

void trapfunc(void)
{
}

void send_g_msg (int destination,			/* Where to send to */
	    char *func (int plx, int arg, char *t),	/* Test function */
	    int arg,					/* Argument to test */
	    char *text)					/* Text to send */
{
  char *t;
  int p, me = real_mynum;

  if (text == NULL)
    trapfunc();

  if (destination >= 0) {                                     /* plr/mob */
    t = (func == NULL ? text : func(destination, arg, text));

    if (is_in_game(destination)) {
      if (destination < max_players)
        p_sendto(destination, t);
      else if (ststflg(destination, SFL_OCCUPIED))
        p_sendto(aliased_mob(destination), t);
    }
  } 
  else {                                                     /* room/all */
    for (p = 0; p < max_players; ++p)
      if (is_in_game (p) && !aliased(p))
        if (destination == DEST_ALL || destination == ploc(p)) {
          t = (func == NULL ? text : func (p, arg, text));
  	  p_sendto (p, t);
        }
  }
  setup_globals (me);
}

char *
check_send_msg (int plx, int a, char *t)
{
  struct _send_msg_box *b = (struct _send_msg_box *) a;

  if (test_rcv (plx, b->mode, b->min, b->max, b->x1, b->x2, b->lang))
    return t;
  return NULL;
}

void
send_msg (int destination,	/* Where to send to */
	  int mode,		/* Flags to control sending */
	  int min,		/* Minimum level of recipient */
	  int max,		/* Maximum level of recipient */
	  int x1,		/* Do not send to him */
	  int x2,		/* Nor to him */
	  char *format,...)
{				/* Format with args -> text to send */
  va_list pvar;
  char bf[2048];
  struct _send_msg_box b;
  char *bb;

  b.mode = mode;
  b.min = min;
  b.max = max;
  b.x1 = x1;
  b.x2 = x2;
  b.lang = NFL_ENGLISH;
  bb = format;
  va_start (pvar, format);
  vsprintf (bf, bb, pvar);
  va_end (pvar);
  send_g_msg (destination, check_send_msg, (int) &b, bf);
}


void
sendf (int destination, char *format,...)
{
  char b[2048];
  va_list pvar;

  va_start (pvar, format);
  vsprintf (b, format, pvar);
  va_end (pvar);
  send_g_msg (destination, NULL, 0, b);
}

void
gsendf (int destination,
	char *func (int plx, int arg, char *text),
	int arg,
	char *format,...)
{
  char b[2048];
  va_list pvar;

  va_start (pvar, format);
  vsprintf (b, format, pvar);
  va_end (pvar);
  send_g_msg (destination, func, arg, b);
}

void
lsend_msg (int destination,	/* Where to send to */
	   int lang,		/* The language to speak */
	   int mode,		/* Flags to control sending */
	   int min,		/* Minimum level of recipient */
	   int max,		/* Maximum level of recipient */
	   int x1,		/* Do not send to him */
	   int x2,		/* Nor to him */
	   char *format,...)
{				/* Format with args -> text to send */
  va_list pvar;
  char bf[2048];
  struct _send_msg_box b;
  char *bb;

  b.mode = mode;
  b.min = min;
  b.max = max;
  b.x1 = x1;
  b.x2 = x2;
  b.lang = lang;
  bb = format;

  va_start (pvar, format);
  vsprintf (bf, bb, pvar);
  va_end (pvar);

  send_g_msg (destination, check_send_msg, (int) &b, bf);
}