/
roa/
roa/lib/boards/
roa/lib/config/
roa/lib/edits/
roa/lib/help/
roa/lib/misc/
roa/lib/plrobjs/
roa/lib/quests/
roa/lib/socials/
roa/lib/www/
roa/lib/www/LEDSign/
roa/lib/www/LEDSign/fonts/
roa/lib/www/LEDSign/scripts/
roa/src/s_inc/
roa/src/sclient/
roa/src/sclient/binary/
roa/src/sclient/text/
roa/src/util/
/************************************************************************
	Realms of Aurealis 		James Rhone aka Vall of RoA

modify.c				A variety of things... name change
					cometh...

		******** Heavily modified and expanded ********
		*** BE AWARE OF ALL RIGHTS AND RESERVATIONS ***
		******** Heavily modified and expanded ********
		        All rights reserved henceforth. 

    Please note that no guarantees are associated with any code from
Realms of Aurealis.  All code which has been released to the general
public has been done so with an 'as is' pretense.  RoA is based on both
Diku and CircleMUD and ALL licenses from both *MUST* be adhered to as well
as the RoA license.   *** Read, Learn, Understand, Improve ***
*************************************************************************/
#include "conf.h"
#include "sysdep.h"

#include "structures.h"
#include "utils.h"
#include "interpreter.h"
#include "acmd.h"
#include "handler.h"
#include "db.h"
#include "comm.h"
#include "lists.h"
#include "boards.h"

/* ************************************************************************
*  modification of malloc'ed strings                                      *
************************************************************************ */
/* Add user input to the 'current' string (as defined by d->str) */
// note: this is the basic stock circle 'editor' of sorts -roa
void	string_add(dsdata *d, char *str, BOOL term)
{
   char	*scan;
   int	terminator = 0;

   /* determine if this is the terminal string, and truncate if so */
   if (term)
    *(str + (MAX_STRING_LENGTH -50)) = '\0'; 
   else
   for (scan = str; *scan; scan++)
      if ((terminator = (*scan == '@'))) {
	 *scan = '\0';
	 break;
      }

   if (!(*d->str)) 
   {
      if (strlen(str) > (unsigned) d->max_str) 
      {
	 send_to_char("String too long - Truncated.\n\r",d->character);
	 *(str + d->max_str) = '\0';
	 terminator = 1;
      }
      CREATE(*d->str, char, strlen(str) + 3);
      strcpy(*d->str, str);
   } 
   else 
   {
      if (strlen(str) + strlen(*d->str) > (unsigned) d->max_str) 
      {
	 send_to_char("String too long. Last line skipped.\n\r",d->character);
	 terminator = 1;
      } 
      else
      {
	 if (!(*d->str = (char *) realloc(*d->str, strlen(*d->str) + strlen(str) + 3))) 
         {
	    perror("string_add");
	    sprintf(buf,"SYSERR: string_add (%s) ...check char input",
		    d->character ? GET_NAME(d->character) : "nochar");
	    log(buf);
	    exit(1);
	 }
	 strcat(*d->str, str);
      }
   }

  // if we're done...call the descmenu or roaolc menu 7/20/98 -jtrhone
  if (terminator || term) 
  {
    // if in OLC, call menu function...  12/30/97 -jtrhone
    if (d->descmenu) 
      (*d->descmenu)(d, NULL);
    else
    if (d->roaolc_menu) 
      (*d->roaolc_menu)(d->character, NULL);

    d->str = NULL;
  } 
  else /* not done entering stuff, put a CR/LF on the string */
    strcat(*d->str, "\n\r");
}

/*********************************************************************
* New Pagination Code
* Michael Buselli submitted the following code for an enhanced pager
* for CircleMUD.  All functions below are his.  --JE 8 Mar 96
*
*********************************************************************/

/* Traverse down the string until the begining of the next page has been
 * reached.  Return NULL if this is the last page of the string.
 */
// modified by jtrhone (roa) to work with RoA color code
char *next_page(char *str, int len)
{
  int col = 1, line = 1;

  for (;; str++) 
  {
    if (!*str)
      return NULL;
    else 
    if (line > len)
      return str;
    else 
    if (*str == '\r')
	col = 1;
    else 
    if (*str == '\n')
	line++;
  }
}


/* Function that returns the number of pages in the string. */
int count_pages(char *str, int len)
{
  int pages;

  for (pages = 1; (str = next_page(str, len)); pages++);
  return pages;
}

/* This function assigns all the pointers for showstr_vector for the
 * page_string function, after showstr_vector has been allocated and
 * showstr_count set.
 */
void paginate_string(char *str, dsdata *d)
{
  int i;
  int len;

  if (d->character && IS_PC(d->character))
    len = PAGE_LENGTH(d->character);
  else
    len = 22;

  // make sure it's set... 4/5/98 -jtrhone
  if (len <= 5)
    len = 22;

  if (d->showstr_count)
    *(d->showstr_vector) = str;

  for (i = 1; i < d->showstr_count && str; i++)
    str = d->showstr_vector[i] = next_page(str, len);

  d->showstr_page = 0;
}

/* The call that displays the next page. */
void show_string(dsdata *d, char *input)
{
  char buffer[MAX_STRING_LENGTH];
  int diff;

  one_argument(input, buf);

  /* Q is for quit. :) */
  if (LOWER(*buf) == 'q') 
  {
    free(d->showstr_vector);
    d->showstr_count = 0;
    if (d->showstr_head)
    {
      free(d->showstr_head);
      d->showstr_head = NULL;
    } 
   return;
  }
  /* R is for refresh, so back up one page internally so we can display
   * it again.
   */
  else 
  if (LOWER(*buf) == 'r')
    d->showstr_page = MAX(0, d->showstr_page - 1);

  /* B is for back, so back up two pages internally so we can display the
   * correct page here.
   */
  else if (LOWER(*buf) == 'b')
    d->showstr_page = MAX(0, d->showstr_page - 2);

  /* Feature to 'goto' a page.  Just type the number of the page and you
   * are there!
   */
  else if (isdigit(*buf))
    d->showstr_page = MAX(0, MIN(atoi(buf) - 1, d->showstr_count - 1));

  else if (*buf) {
    send_to_char(
		  "Valid commands while paging are RETURN, Q, R, B, or a numeric value.\r\n",
		  d->character);
    return;
  }
  /* If we're displaying the last page, just send it to the character, and
   * then free up the space we used.
   */
  if (d->showstr_page + 1 >= d->showstr_count) 
  {
    send_to_char(d->showstr_vector[d->showstr_page], d->character);
    free(d->showstr_vector);
    d->showstr_count = 0;
    if (d->showstr_head)
    {
      free(d->showstr_head);
      d->showstr_head = NULL;
    }
  }
  /* Or if we have more to show.... */
  else 
  {
    strncpy(buffer, d->showstr_vector[d->showstr_page],
	    diff = ((int) d->showstr_vector[d->showstr_page + 1])
	    - ((int) d->showstr_vector[d->showstr_page]));
    buffer[diff] = '\0';
    send_to_char(buffer, d->character);
    d->showstr_page++;
  }
}

/* The call that gets the paging ball rolling... */
void page_string(dsdata *d, char *str, int keep_internal)
{
  int len;

  if (!d)
    return;

  if (!str || !*str) {
    send_to_char("", d->character);
    return;
  }

  if (d->character && IS_PC(d->character))
    len = PAGE_LENGTH(d->character);
  else
    len = 22;

  // make sure it's set... 4/5/98 -jtrhone
  if (len <= 5)
    len = 22;

  CREATE(d->showstr_vector, char *, (d->showstr_count = count_pages(str, len)));

  if (keep_internal) {
    d->showstr_head = str_dup(str);
    paginate_string(d->showstr_head, d);
  } else
    paginate_string(str, d);

  show_string(d, "");
}