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 <stdlib.h>
#include <string.h>
#include "externs.h"
#include "db.h"

#define MOTD 0
#define TODO 1

static char *motdfile = "db/motd.db";
static char *todofile = "db/todo.db";

struct todomotd_struct
{
  char *text;
  OBJ *player;
  struct todomotd_struct *next;
};

typedef struct todomotd_struct TODOMOTD;

TODOMOTD *motdlist = NULL;
TODOMOTD *todolist = NULL;

void save_todomotd(bool which)
{
  FILE *fp;
  int i;
  char *filename = (which == MOTD)?motdfile:todofile;
  TODOMOTD *ptr;

  if(!filename)
    return;

  if(!(fp = fopen(filename, "w")))
  {
    log_error(tprintf("Couldn't open \"%s\" for writing!", filename));
    return;
  }

  for(i = 0, ptr = (which == MOTD)?motdlist:todolist;ptr;ptr = ptr->next)
    i++;

  fprintf(fp, "%d\n", i);

  for(ptr = (which == MOTD)?motdlist:todolist;ptr;ptr = ptr->next)
  {
    fprintf(fp, "%s\n", ptr->text);
    fprintf(fp, "%d\n", ptr->player->dbref);
  }

  fclose(fp);
}

void load_todomotd(bool which)
{
  FILE *fp;
  int i, total;
  char *filename = (which == MOTD)?motdfile:todofile;
  TODOMOTD *ptr;
  char buf[4096];

  if(!filename)
    return;

  if(!(fp = fopen(filename, "r")))
  {
    log_error(tprintf("Couldn't open \"%s\" for reading!", filename));
    return;
  }

  total = getref(fp);

  for(i = 0;i < total;++i)
  {
    ptr = (TODOMOTD *)stack_alloc(sizeof(TODOMOTD), 1, 0);
    fgets(buf, sizeof(buf), fp);
    *(buf+strlen(buf)-1) = '\0';
    ptr->text = stack_string_alloc(buf, 1);
    fgets(buf, sizeof(buf), fp);
    ptr->player = find_object(atoi(buf));
    if(!(ptr->player))
    {
      stack_free(ptr->text);
      stack_free(ptr);
    }

    if(which == MOTD)
    {
      ptr->next = motdlist;
      motdlist = ptr;
    }
    else
    {
      ptr->next = todolist;
      todolist = ptr;
    }
  }

  fclose(fp);
}

static void todomotd_show(OBJ *player, bool which)
{
  int i = 0;
  TODOMOTD *ptr = (which == MOTD)?motdlist:todolist;

  if(!ptr)
  {
    notify(player, "There is nothing at this time.");
    return;
  }

  while(ptr)
  {
    notify(player, tprintf("|+Y|%3d|+W|) |+B|%s |+W|-- %s",
      ++i, ptr->text, name(ptr->player)));
    ptr = ptr->next;
  }
}

static TODOMOTD *new_todomotd(bool which)
{
  TODOMOTD *new;

  new = (TODOMOTD *)stack_alloc(sizeof(TODOMOTD), 1, 0);

  if(which == MOTD)
  {
    new->next = motdlist;
    motdlist = new;
  }
  else
  {
    new->next = todolist;
    todolist = new;
  }

  return(new);
}

static void todomotd_add(OBJ *player, char *arg, bool which)
{
  TODOMOTD *new;

  if(!power(player, POW_MISC))
  {
    notify(player, perm_denied());
    return;
  }

  if(!*arg)
  {
    notify(player, "Add what?");
    return;
  }

  new = new_todomotd(which);

  new->text = stack_string_alloc(arg, 1);
  new->player = player;

  notify(player, "Added.");
}

static void todomotd_del(OBJ *player, char *arg, bool which)
{
  int num, i = 0;
  TODOMOTD *ptr = (which == MOTD)?motdlist:todolist;
  TODOMOTD *prev = NULL;

  if(!power(player, POW_MISC))
  {
    notify(player, perm_denied());
    return;
  }

  if((num = atoi(arg)) < 1)
  {
    notify(player, "You must specify a valid item number to delete!");
    return;
  }

  while(ptr)
  {
    if(++i == num)
      break;
    prev = ptr;
    ptr = ptr->next;
  }

  if(!ptr)
  {
    notify(player, "You must specify a valid item number to delete!");
    return;
  }

  if(prev)
    prev->next = ptr->next;
  else
    (which == MOTD)?motdlist:todolist = ptr->next;

  stack_free(ptr->text);
  stack_free(ptr);

  notify(player, tprintf("Item number %d was deleted from the %s.",
    num, (which == MOTD)?"MOTD":"TODO list"));
}

static void do_todomotd(OBJ *player, char *arg1, char *arg2, bool which)
{
  int help;
  SUBCOMMAND *sc, commands[] =
  {
    { "add",    (void *)todomotd_add, 1 },
    { "delete", (void *)todomotd_del, 1 },
    { NULL }
  };

  if(!(sc = subcommand_match(player, arg1, commands, &help)))
  {
    if(help == 1)
      subcommand_print(player, (which == TODO)?"+todo":"+motd", commands);
    else
      todomotd_show(player, which);
  }
  else
    sc->func(player, arg2, which);
}

void do_motd(OBJ *player, char *arg1, char *arg2)
{
  do_todomotd(player, arg1, arg2, MOTD);
}

void do_todo(OBJ *player, char *arg1, char *arg2)
{
  do_todomotd(player, arg1, arg2, TODO);
}

void free_todomotd(void)
{
  TODOMOTD *p, *pnext;

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

    stack_free(p->text);
    stack_free(p);
  }

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

    stack_free(p->text);
    stack_free(p);
  }
}