legend/
legend/area/
legend/player/
/*
 */
#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#include <sys/time.h>
#endif

#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <stdarg.h>
#include "merc.h"
#include "changes.h"

/*   
 * Globals
 */
char *current_date args ((void));
int nnum_changes args ((void));

/*
 * Local Functions
 */

int maxChanges;
#define  NULLSTR( str )  ( str == NULL || str[0] == '\0' )
NEWCHANGE_DATA *changes_table;

char *nshort_date (time_t time)
{
   static char buf[20];
   char tmp[20];
   char *date;

   if (time < 0)
   {
      time = current_time;
   }

   date = ctime (&time);

   tmp[0] = date[4];
   tmp[1] = date[5];
   tmp[2] = date[6];
   tmp[3] = '\0';
   if (!str_cmp (tmp, "jan"))
   {
      buf[0] = '0';
      buf[1] = '1';
   }
   else if (!str_cmp (tmp, "feb"))
   {
      buf[0] = '0';
      buf[1] = '2';
   }
   else if (!str_cmp (tmp, "mar"))
   {
      buf[0] = '0';
      buf[1] = '3';
   }
   else if (!str_cmp (tmp, "apr"))
   {
      buf[0] = '0';
      buf[1] = '4';
   }
   else if (!str_cmp (tmp, "may"))
   {
      buf[0] = '0';
      buf[1] = '5';
   }
   else if (!str_cmp (tmp, "jun"))
   {
      buf[0] = '0';
      buf[1] = '6';
   }
   else if (!str_cmp (tmp, "jul"))
   {
      buf[0] = '0';
      buf[1] = '7';
   }
   else if (!str_cmp (tmp, "aug"))
   {
      buf[0] = '0';
      buf[1] = '8';
   }
   else if (!str_cmp (tmp, "sep"))
   {
      buf[0] = '0';
      buf[1] = '9';
   }
   else if (!str_cmp (tmp, "oct"))
   {
      buf[0] = '1';
      buf[1] = '0';
   }
   else if (!str_cmp (tmp, "nov"))
   {
      buf[0] = '1';
      buf[1] = '1';
   }
   else if (!str_cmp (tmp, "dec"))
   {
      buf[0] = '1';
      buf[1] = '2';
   }
   else
   {
      buf[3] = '9';
      buf[4] = '9';
   }

   buf[2] = '/';

   if (date[8] == ' ')
      buf[3] = '0';
   else
      buf[3] = date[8];

   buf[4] = date[9];

   buf[5] = '/';

   buf[6] = date[20];
   buf[7] = date[21];
   buf[8] = date[22];
   buf[9] = date[23];

   return buf;
}

void load_changes (void)
{
   FILE *fp;
   int i;

   if (!(fp = fopen (CHANGES_FILE, "r")))
   {
      bug ("Could not open Changes File for reading.", 0);
      return;
   }

   fscanf (fp, "%d\n", &maxChanges);

   /* Use malloc so we can realloc later on */
   changes_table = malloc (sizeof (NEWCHANGE_DATA) * (maxChanges + 1));

   for (i = 0; i < maxChanges; i++)
   {
      changes_table[i].change = fread_string (fp);
      changes_table[i].coder = fread_string (fp);
      changes_table[i].date = fread_string (fp);
      changes_table[i].mudtime = fread_number (fp);
   }

   changes_table[maxChanges].coder = str_dup ("");
   fclose (fp);
   return;			/* just return */
}

char *ncurrent_date ()
{
   static char buf[128];
   struct tm *t;
   time_t nowtime;
   nowtime = time (&current_time);
   t = localtime (&nowtime);
   strftime (buf, 100, "%-d-%M-%Y", t);
   return buf;
}

void save_changes (void)
{
   FILE *fp;
   int i;

   if (!(fp = fopen (CHANGES_FILE, "w")))
   {
      perror (CHANGES_FILE);
      return;
   }

   fprintf (fp, "%d\n", maxChanges);
   for (i = 0; i < maxChanges; i++)
   {
      fprintf (fp, "%s~\n", changes_table[i].change);
      fprintf (fp, "%s~\n", changes_table[i].coder);
      fprintf (fp, "%s~\n", changes_table[i].date);
      fprintf (fp, "%ld\n", (long)changes_table[i].mudtime);
      fprintf (fp, "\n");
   }
   fclose (fp);

   return;
}

void delete_change (int iChange)
{
   int i, j;
   NEWCHANGE_DATA *new_table;

   new_table = malloc (sizeof (NEWCHANGE_DATA) * maxChanges);

   if (!new_table)
      return;

   for (i = 0, j = 0; i < maxChanges + 1; i++)
   {
      if (i != iChange)
      {
	 new_table[j] = changes_table[i];
	 j++;
      }
   }

   free (changes_table);
   changes_table = new_table;
   maxChanges--;
   save_changes ();
   return;
}


void do_naddchange (CHAR_DATA * ch, char *argument)
{
   NEWCHANGE_DATA *new_table;
   char buf[MSL];
   if (IS_NPC (ch))
      return;

   if (argument[0] == '\0')
   {
      send_to_char ("Syntax: Addchange $ChangeString\n\r", ch);
      send_to_char ("Type 'changes' to view the list.#n\n\r", ch);
      return;
   }

   maxChanges++;
   new_table =
      realloc (changes_table, sizeof (NEWCHANGE_DATA) * (maxChanges + 1));

   if (!new_table)
   {				/* realloc failed */
      send_to_char ("Memory allocation failed. Brace for impact.\n\r", ch);
      return;
   }
   changes_table = new_table;
   changes_table[maxChanges - 1].change = str_dup (argument);
   changes_table[maxChanges - 1].coder = str_dup (ch->name);
   changes_table[maxChanges - 1].date = str_dup (current_date ());
   changes_table[maxChanges - 1].mudtime = current_time;
   sprintf (buf, "#wYou added the following change:\n\r       #r%s\n\r",
	    argument);
   stc (buf, ch);
   sprintf (buf,
	    "#c%s #whas added a new change, type '#ychanges#w' to see what it was",
	    ch->name);
   do_info (NULL, buf);
   save_changes ();
   return;
}
void do_chsave (CHAR_DATA * ch, char *argument)
{
   char arg1[MAX_INPUT_LENGTH];
   char arg2[MAX_INPUT_LENGTH];
   char buf[MSL];

   argument = one_argument (argument, arg1);
   argument = one_argument (argument, arg2);

   if (IS_NPC (ch))
      return;

   if (!ch->desc || NULLSTR (arg1))
   {
      stc ("Syntax: editchange load/save\n\r", ch);
      stc ("Syntax: editchange delete (change number)\n\r", ch);
      stc ("Syntax: editchange rename (change number)\n\r", ch);
      return;
   }
   else if (!str_cmp (arg1, "load"))
   {
      load_changes ();
      send_to_char ("Changes Loaded.\n\r", ch);
      return;
   }
   else if (!str_cmp (arg1, "save"))
   {
      save_changes ();
      send_to_char ("Changes Saved.\n\r", ch);
      return;
   }
   else if (!str_cmp (arg1, "delete"))
   {
      int num;

      if (NULLSTR (arg2) || !is_number (arg2))
      {
	 send_to_char
	    ("#wFor editchange delete, you must provide a change number.#n\n\r",
	     ch);
	 send_to_char ("Syntax: editchange delete (change number)\n\r", ch);
	 return;
      }

      num = atoi (arg2);

      if (num < 0 || num > maxChanges)
      {
	 sprintf (buf, "Valid changes are from 0 to %d.\n\r", maxChanges);
	 stc (buf, ch);
	 return;
      }

      delete_change (num);
      send_to_char ("Change deleted.\n\r", ch);

      return;
   }
   else if (strcmp (arg1, "rename") == 0)
   {
      int num;
      if (NULLSTR (arg2) || !is_number (arg2) || NULLSTR (argument))
      {
	 send_to_char
	    ("#yFor editchange rename, you must choose a change number.#n\n\r",
	     ch);
	 send_to_char
	    ("Syntax: editchange rename (change number) 'New Change'#n\n\r",
	     ch);
	 return;
      }
      num = atoi (arg2);
      if (num < 0 || num > maxChanges)
      {
	 char buf[MAX_STRING_LENGTH];
	 sprintf (buf, "Valid changes are from 0 to %d.\n\r", maxChanges);
	 send_to_char (buf, ch);
	 return;
      }
      changes_table[num - 1].change = str_dup (argument);
      save_changes ();
      send_to_char ("Change renamed.\n\r", ch);
      return;
   }

   stc ("Syntax: editchange load/save\n\r", ch);
   stc ("Syntax: editchange delete (change number)\n\r", ch);
   stc ("Syntax: editchange rename (change number)\n\r", ch);
   return;
}

char *nline_indent (char *text, int wBegin, int wMax)
{
   static char buf[MAX_STRING_LENGTH];
   char *ptr;
   char *ptr2;
   int count = 0;
   bool stop = FALSE;
   int wEnd=0;
   buf[0] = '\0';
   ptr = text;
   ptr2 = buf;

   while (!stop)
   {
      if (count == 0)
      {
	 if (*ptr == '\0')
	    wEnd = wMax - wBegin;
	 else if (strlen (ptr) < (wMax - wBegin))
	    wEnd = wMax - wBegin;
	 else
	 {
	    int x = 0;

	    while (*(ptr + (wMax - wBegin - x)) != ' ')
	       x++;
	    wEnd = wMax - wBegin - (x - 1);
	    if (wEnd < 1)
	       wEnd = wMax - wBegin;
	 }
      }
      if (count == 0 && *ptr == ' ')
	 ptr++;
      else if (++count != wEnd)
      {
	 if ((*ptr2++ = *ptr++) == '\0')
	    stop = TRUE;
      }
      else if (*ptr == '\0')
      {
	 stop = TRUE;
	 *ptr2 = '\0';
      }
      else
      {
	 int k;

	 count = 0;
	 *ptr2++ = '\n';
	 *ptr2++ = '\r';
	 for (k = 0; k < wBegin; k++)
	    *ptr2++ = ' ';
      }
   }
   return buf;
}
/*
int newchanges (void)
{
   char *test;
   char change[100];
   CHAR_DATA *ch;
   int newchanges;
   int i;

   i = 0;

   sprintf (change, "%ld", ch->pcdata->changeplace);
   newchanges = 0;
   test = current_date ();

   for (i = 0; i < maxChanges; i++)
      if (!str_cmp (test, change))
	 newchanges++;

   return newchanges;
}
*/
int nnum_changes (void)
{
   char *test;
   int today;
   int i;

   i = 0;
   test = current_date ();
   today = 0;

   for (i = 0; i < maxChanges; i++)
      if (!str_cmp (test, changes_table[i].date))
	 today++;

   return today;
}
/*
void do_changes (CHAR_DATA * ch, char *argument)
{
   char arg[MIL], arg2[MIL], buf[MSL], *test;
   int i, page = 0, maxpage = 0, today;
   int display = 0;
   argument = one_argument (argument, arg);
   argument = one_argument (argument, arg2);

   if (IS_NPC (ch))
      return;
   if (maxChanges < 1)
      return;

   i = 0;
   test = current_date ();
   today = 0;


   for (i = 0; i < maxChanges; i++)
   {
      if (!str_cmp (test, changes_table[i].date))
	 today++;
   }

   if (is_number (arg))
      page = atoi (arg);
   //maxpage = (maxChanges/10)+1;
   maxpage = (maxChanges + 9) / 10;

   if (page > 0)
   {
      if (page > maxpage)
      {
	 sprintf (buf, "Show which page 1-%d\n\r", maxpage);
	 stc (buf, ch);
	 return;
      }
      page *= 10;
   }
   stc ("^1#wNUMBER #cCODER         #yDATE         #wCHANGE                                        #n\n\r", ch);

   stc ("#C--------------------------------------------------------------------------------#n\n\r", ch);

   if (!str_cmp (arg, "search"))
   {
      int dsp = 0;

      if (arg2[0] == '\0')
      {
	 stc ("What do you want to search for??.\n\r", ch);
	 return;
      }

      for (i = 0; i < maxChanges; i++)
      {
	 if (!str_infix (arg2, changes_table[i].change)
	     || !str_infix (arg2, changes_table[i].coder))

	 {
	    sprintf (buf, "#e[#w%4d#e] #c%-13s #y%11s #c- #w%-52s\n\r",
		     (++dsp),
		     changes_table[i].coder,
		     changes_table[i].date,
		     line_indent (changes_table[i].change, 35, 79));
	    stc (buf, ch);
	 }
      }
      if (dsp == 0)
	 stc ("There is NO match with what you have entered!.\n\r", ch);
      stc ("#C--------------------------------------------------------------------------------#n\n\r", ch);
      return;
   }


   for (i = 0; i < maxChanges; i++)
   {
//      if (page == 0
//	  && changes_table[i].mudtime + (4 * 24L * 3600L) < current_time)
//	 continue;
if (page == 0 &&
        str_prefix(test, changes_table[i].date) &&
        i < (maxChanges-10)) continue;
      display++;

//      if (page > 0 && (page > 0 && (i < (page - 10) || i >= page)))
//	 continue;

      if (page > 0 &&
        (page > 0 && (i < (page-10) || i >= page))) continue;

      sprintf (buf, "#e[#w%4d#e] #c%-13s #y%11s #c- #w%-55s\n\r",
	       (i + 1),
	       changes_table[i].coder,
	       changes_table[i].date,
	       line_indent (changes_table[i].change, 35, 79));
      stc (buf, ch);
   }
   ch->pcdata->changeplace = changes_table[i].mudtime;
   stc ("#C--------------------------------------------------------------------------------#n\n\r", ch);
   if (today > 0)
      sprintf (buf,
	       "#wThere is a total of [#r%d#w] changes of which [#c%d#w] %s been added today.#n",
	       maxChanges, today, today > 1 ? "have" : "has");
   else
      sprintf (buf, "#wThere is a total of [#r%d#w] changes.#n", maxChanges);
   cent_to_char (buf, ch);
   stc ("#C--------------------------------------------------------------------------------#n\n\r", ch);
   sprintf (buf, "#wTo see pages of changes use: 'changes <#c1#w-#r%d#w>'",
            maxpage);
   cent_to_char (buf, ch);
   cent_to_char
      ("#wTo search all changes for a change use: 'changes search <#cword#w>'#n",
       ch);
   stc ("#C--------------------------------------------------------------------------------#n\n\r", ch);

}
*/
void do_changes (CHAR_DATA * ch, char *argument)
{
   char arg[MIL], arg2[MIL], buf[MSL], *test;
   int i, page = 0, maxpage = 0, today;
   int display = 0;
   argument = one_argument (argument, arg);
   argument = one_argument (argument, arg2);

   if (IS_NPC (ch))
      return;
   if (maxChanges < 1)
      return;

   i = 0;
   test = current_date ();
   today = 0;


   for (i = 0; i < maxChanges; i++)
   {
      if (!str_cmp (test, changes_table[i].date))
	 today++;
   }

   if (is_number (arg))
      page = atoi (arg);
   //maxpage = (maxChanges/10)+1;
   maxpage = (maxChanges + 9) / 10;

   if (page > 0)
   {
      if (page > maxpage)
      {
	 sprintf (buf, "Show which page 1-%d\n\r", maxpage);
	 stc (buf, ch);
	 return;
      }
      page *= 10;
   }
   stc ("^1#wNUMBER #cCODER         #yDATE         #wCHANGE                                        #n\n\r", ch);

   stc ("#C--------------------------------------------------------------------------------#n\n\r", ch);

   if (!str_cmp (arg, "search"))
   {
      int dsp = 0;

      if (arg2[0] == '\0')
      {
	 stc ("What do you want to search for??.\n\r", ch);
	 return;
      }

      for (i = 0; i < maxChanges; i++)
      {
	 if (!str_infix (arg2, changes_table[i].change)
	     || !str_infix (arg2, changes_table[i].coder))

	 {
	    sprintf (buf, "#e[#w%4d#e] #c%-13s #y%11s #c- #w%-52s\n\r",
		     (++dsp),
		     changes_table[i].coder,
		     changes_table[i].date,
		     line_indent (changes_table[i].change, 35, 79));
	    stc (buf, ch);
	 }
      }
      if (dsp == 0)
	 stc ("There is NO match with what you have entered!.\n\r", ch);
      stc ("#C--------------------------------------------------------------------------------#n\n\r", ch);
      return;
   }


   for (i = 0; i < maxChanges; i++)
   {
//      if (page == 0
//	  && changes_table[i].mudtime + (4 * 24L * 3600L) < current_time)
//	 continue;
if (page == 0 &&
        str_prefix(test, changes_table[i].date) &&
        i < (maxChanges-10)) continue;
      display++;

//      if (page > 0 && (page > 0 && (i < (page - 10) || i >= page)))
//	 continue;

      if (page > 0 &&
        (page > 0 && (i < (page-10) || i >= page))) continue;

      sprintf (buf, "#e[#w%4d#e] #c%-13s #y%11s #c- #w%-55s\n\r",
	       (i + 1),
	       changes_table[i].coder,
	       changes_table[i].date,
	       line_indent (changes_table[i].change, 35, 79));
      stc (buf, ch);
   }
   ch->pcdata->changeplace = changes_table[i].mudtime;
   stc ("#C--------------------------------------------------------------------------------#n\n\r", ch);
   if (today > 0)
      sprintf (buf,
	       "#wThere is a total of [#r%d#w] changes of which [#c%d#w] %s been added today.#n",
	       maxChanges, today, today > 1 ? "have" : "has");
   else
      sprintf (buf, "#wThere is a total of [#r%d#w] changes.#n", maxChanges);
   cent_to_char (buf, ch);
   stc ("#C--------------------------------------------------------------------------------#n\n\r", ch);
   sprintf (buf, "#wTo see pages of changes use: 'changes <#c1#w-#r%d#w>'",
            maxpage);
   cent_to_char (buf, ch);
   cent_to_char
      ("#wTo search all changes for a change use: 'changes search <#cword#w>'#n",
       ch);
   stc ("#C--------------------------------------------------------------------------------#n\n\r", ch);

}