TinyMAZE/
TinyMAZE/config/
TinyMAZE/doc/
TinyMAZE/run/msgs/
TinyMAZE/src/
TinyMAZE/src/db/
TinyMAZE/src/ident/
TinyMAZE/src/io/
TinyMAZE/src/prog/
TinyMAZE/src/softcode/
TinyMAZE/src/util/
#include <stdio.h>
#include <ctype.h>
#include "db.h"
#include "externs.h"

struct page_struct
{
  OBJ *player;
  int num_in_list;
  OBJ **list;
  struct page_struct *next;
};

struct page_struct *page_list = NULL;

static char *title(OBJ *player)
{
  char buf[4096];

  strcpy(buf, name(player));

  if(!*atr_get(player, "ALIAS"))
    sprintf(buf+strlen(buf), " (#%d)", player->dbref);
  else
    sprintf(buf+strlen(buf), " (%s)", atr_get(player, "ALIAS"));

  return(stack_string_alloc(buf, 0));
}

static struct page_struct *unparse_page_list(OBJ *player, char *list,
                                             char *msg, int *status)
{
  struct page_struct *p, *newp;
  OBJ *plyr;
  char buf[4096];
  char *s, *b;

  *status = 0;

  if(!*list)
    return(NULL);

  for(p = page_list;p;p = p->next)
    if(p->player == player)
      break;

/* They haven't paged before. Add a new entry */
  if(!p)
  {
    if(!*msg)
      return(NULL);

    newp = (struct page_struct *)stack_alloc(sizeof(struct page_struct), 1, 0);
    newp->player = player;
    newp->list = NULL;
    newp->num_in_list = 0;
    newp->next = page_list;
    page_list = newp;
    p = newp;
  }

  if(!*msg)
  {
    if(!p->list)
      return(NULL);
    return(p);
  }

  if(p->num_in_list)
    stack_free(p->list);
  p->list = NULL;
  p->num_in_list = 0;

  for(s = list, b = buf;*s;s++)
  {
    if(!isspace(*s))
    {
      *b++ = *s;
      continue;
    }

    *b = '\0';
    b = buf;

    if(!(plyr = match_player(NULL, buf)))
    {
      notify(player, no_match(buf));
      if(p->num_in_list)
        stack_free(p->list);
      p->list = NULL;
      p->num_in_list = 0;
      *status = 1;
      return(NULL);
    }

    if(!p->num_in_list)
      p->list = (OBJ **)stack_alloc(sizeof(OBJ *), 1, 0);
    else
      p->list = (OBJ **)stack_realloc(p->list,
        sizeof(OBJ *)*((p->num_in_list)+1));
    p->list[(p->num_in_list)++] = plyr;
  }

  *b = '\0';
  if(!(plyr = match_player(NULL, buf)))
  {
    notify(player, no_match(buf));
    if(p->num_in_list)
      stack_free(p->list);
    p->list = NULL;
    p->num_in_list = 0;
    *status = 1;
    return(NULL);
  }

  if(!p->num_in_list)
    p->list = (OBJ **)stack_alloc(sizeof(OBJ *), 1, 0);
  else
    p->list = (OBJ **)stack_realloc(p->list,
      sizeof(OBJ *)*((p->num_in_list)+1));
  p->list[(p->num_in_list)++] = plyr;

  return(p);
}

void do_page(OBJ *player, char *arg1, char *arg2)
{
  const char *hidden_msg = "is either hidden from you or not connected.";
  struct page_struct *plist;
  int i;
  int hidden;
  char *str;
  char *msg;
  int status;
  char buf[4096];
  int type;

  plist = unparse_page_list(player, arg1, arg2, &status);
  if(!plist)
  {
    if(!status)
      notify(player, "You must include a message!");
    return;
  }

  if(!*arg2)
    msg = arg1;
  else
    msg = arg2;

  type = unparse_tothink(player, msg, buf, 0, 0x2);

  for(i = 0;i < plist->num_in_list;i++)
  {
    hidden = 0;

    if(!is_connected_raw(plist->list[i]))
    {
      notify(player, tprintf("%s %s", name(plist->list[i]), hidden_msg));
      if(*Away(plist->list[i]))
        notify(player, tprintf("Away message from %s: %s",
          name(plist->list[i]), Away(plist->list[i])));
      continue;
    }

    if(!could_doit(player, plist->list[i], "LHIDE") &&
      !controls(player, plist->list[i], POW_WHO))
    {
      str = "|+W|(HIDDEN)|n| ";
      hidden = 1;
    }
    else
      str = "";
    if(hidden)
    {
      notify(player, tprintf("%s %s", name(plist->list[i]), hidden_msg));
      if(*Away(plist->list[i]))
        notify(player, tprintf("Away message from %s: %s",
          name(plist->list[i]), Away(plist->list[i])));
    }

    if(!could_doit(player, plist->list[i], "LPAGE") && !hidden)
      notify(player, tprintf("%s is not accepting pages.",
        name(plist->list[i])));

    if(!could_doit(player, plist->list[i], "LPAGE"))
      continue;

    if(type == 1)
    {
      notify(plist->list[i], tprintf("%s%s pages: %s %s",
        str, title(player), name(player), buf));
      if(!hidden)
        notify(player, tprintf("You paged %s with: %s %s",
          name(plist->list[i]), name(player), buf));
    }
    else if(type == 2)
    {
      notify(plist->list[i], tprintf("%s%s pages: %s %s",
        str, title(player), poss(player), buf));
      if(!hidden)
        notify(player, tprintf("You paged %s with: %s %s",
          name(plist->list[i]), poss(player), buf));
    }
    else
    {
      notify(plist->list[i], tprintf("%s%s pages: %s",
        str, title(player), msg));
      if(!hidden)
        notify(player, tprintf("You paged %s with: %s",
          name(plist->list[i]), msg));
    }

    if(!hidden)
    {
      did_it(player, plist->list[i], NULL, NULL, "PPAGE");
      if(*Idle(plist->list[i]) && is_idle(plist->list[i]))
      {
        notify(player, tprintf("Idle message from %s: %s",
          name(plist->list[i]), Idle(plist->list[i])));
        notify(plist->list[i],
          tprintf("Your Idle message has been sent to %s.",
          name(player)));
      }
    }
  }
}

void free_pages(void)
{
  struct page_struct *p, *pnext;

  for(p = page_list;p;p = pnext)
  {
    pnext = p->next;

    if(p->num_in_list)
      stack_free(p->list);
    stack_free(p);
  }
}