/
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

olc_add.c				RoAOLC addon file for typo
					correction and various other
					goodies...
					Note: much of this code was
					      written by Freebie...

		******** 100% Completely Original Code ********
		*** BE AWARE OF ALL RIGHTS AND RESERVATIONS ***
		******** 100% Completely Original Code ********
		        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 "mail.h"
#include "lists.h"

#define FORMAT_LENGTH 78

/* protos */
void do_format_string(char **pstr);
char *format_str(char *str);
void insert_symbol(char *str, int pos, char symb);
void remove_symbol(char *str, int pos);
int symbols_till_next_space_or_return(char *str);
int symbols_till_next_return(char *str);
void delete_word(char *str, int line, int pos);
char *insert_word(char *str, int line, int pos, char *word);
char *one_argument_with_caps(char *arg1, char *arg2);

/* Formatting procedures */
void do_format_string(char **pstr)
{
  int k, i, j = 0, count = 0; 
  char *str;
  char *pback;
  char *newstr;

  /* make a very long string to avoid all probs */
  char string[2 * MAX_STRING_LENGTH];

  str = *pstr;

  /* First of all, remove all the extra spacing before the '\n's. */
  for(i=0;(i<MAX_STRING_LENGTH && *(str+i));i++) {
    if(*(str+i) != 32) {
      string[j] = *(str + i);
      j++;
      continue;
    }
    for(k = i; (*(str + k) == 32); k++) 
      ;

    /* look backwards to see if this is a new paragraph or not */
    for(pback = str+i; (pback != str) && (*pback == 32); pback--)
         ;
    if((k - i >= 2) && (*pback != '\n') && (*pback != '\r') && (pback != str)) continue;

    if(*(str+k) != '\n') {
      string[j] = *(str + i);
      j++;
    } 
  }
  string[j] = '\0';

  /* spacing removed....replace some '\n''s by spaces */
  /* all '\n's are removed except those that are followed by spaces, 'cause
     these are assumed to be the beginnings of new paragraphs */

  for(i = 0; (i < MAX_STRING_LENGTH && *(string + i)); i++) {
    if(string[i] == '\r') remove_symbol(string, i);
  }

  for(i = 0; (i < MAX_STRING_LENGTH && *(string + i));i++) 
    if((string[i] == '\n') && ((string[i+1] != '\t') && (string[i + 1] != 32))) 
      string[i] = 32;
      
  /* ok... now we finished transforming the string, so insert some breaks */
  for(i = 0;(i < MAX_STRING_LENGTH && string[i]);) {
    k = symbols_till_next_space_or_return(string+i+1);
    if((count > 0) && ((count + k) > FORMAT_LENGTH)) {
      string[i] = '\n';
      insert_symbol(str, i+1, '\r');
      i++;
      count = 0;
    }
    else {
      if((count == 0) && ((count + k) > FORMAT_LENGTH)) {
        string[i+k+1] = '\n';
        insert_symbol(str, i+k+2, '\r');
        i += (k+2);
        count = 1;
      }
      else  {
        /* if a return was not encountered, increase the counter */
        if(string[i + k] != '\n') {
          count += (k+1);
          i += (k+1);   
        }
        /* otherwise, reset the counter */
        else  {
          insert_symbol(str, i+k+1, '\r');
          i+= (k+2);
          count = 1;
        }
      }
    }
  }
  /* defend ourselves against long strings */
  /* stick back these \r's */
  string[2 * MAX_STRING_LENGTH - 2] = '\0';
  for(i = 0; i < 2 * MAX_STRING_LENGTH - 1; i++) {
   /* stick that last '\r' in the end */
    if(!string[i] && i && (string[i-1] != '\r'))  {
      insert_symbol(string, i, '\r'); 
      if(string[i-1] != '\n') insert_symbol(string, i, '\n');
      break;
    }
  }
  string[MAX_STRING_LENGTH] = '\0';
  CREATE(newstr, char, strlen(string)+1);
  strcpy(newstr, string);

  free(str);
  *pstr = newstr;
}  

/* This is slightly different from the above, only slightly though */
/* This one takes a pointer to the string and returns a (new) pointer to the
   formatted string */

char *format_string(char *pstr)
{
  int k, i, j = 0, count = 0; 
  char *str;
  char *newstr;
  char *pback;

  /* make a very long string to avoid all probs */
  char string[2 * MAX_STRING_LENGTH];

  str = pstr;

  /* First of all, remove all the extra spacing before the '\n's. */
  for(i=0;(i<MAX_STRING_LENGTH && *(str+i));i++) {
    if(*(str+i) != 32) {
      string[j] = *(str + i);
      j++;
      continue;
    }
    for(k = i; (*(str + k) == 32); k++) 
      ;

    /* Skip more than once space, unless a beginning of a new paragraph */
    for(pback = str+i; ((pback != str) && (*pback == 32)); pback--)
         ;

    if((k - i >= 2) && (*pback != '\r') && (*pback != '\n') && (pback != str)) continue;

    if(*(str+k) != '\n') {
      string[j] = *(str + i);
      j++;
    } 
  }
  string[j] = '\0';

  /* spacing removed....replace some '\n''s by spaces */
  /* all '\n's are removed except those that are followed by spaces, 'cause
     these are assumed to be the beginnings of new paragraphs */

  for(i = 0; (i < MAX_STRING_LENGTH && *(string + i)); i++) {
    if(string[i] == '\r') remove_symbol(string, i);
  }

  for(i = 0; (i < MAX_STRING_LENGTH && *(string + i));i++) 
    if((string[i] == '\n') && ((string[i + 1] != 32) && (string[i+1] != '\t'))) 
      string[i] = 32;
      
  /* ok... now we finished transforming the string, so insert some breaks */
  for(i = 0;(i < MAX_STRING_LENGTH && string[i]);) {
    k = symbols_till_next_space_or_return(string+i+1);
    if((count > 0) && ((count + k) > FORMAT_LENGTH)) {
      string[i] = '\n';
      insert_symbol(str, i+1, '\r');
      i++;
      count = 0;
    }
    else {
      if((count == 0) && ((count + k) > FORMAT_LENGTH)) {
        string[i+k+1] = '\n';
        insert_symbol(str, i+k+2, '\r');
        i += (k+2);
        count = 1;
      }
      else  {
        /* if a return was not encountered, increase the counter */
        if(string[i + k] != '\n') {
          count += (k+1);
          i += (k+1);   
        }
        /* otherwise, reset the counter */
        else  {
          insert_symbol(str, i+k+1, '\r');
          i+= (k+2);
          count = 1;
        }
      }
    }
  }
  /* defend ourselves against long strings */
  /* stick back these \r's */
  string[2 * MAX_STRING_LENGTH - 2] = '\0';
  for(i = 0; i < 2 * MAX_STRING_LENGTH - 1; i++) {
   /* stick that last '\r' in the end */
    if(!string[i] && i && (string[i-1] != '\r'))  {
      insert_symbol(string, i, '\r'); 
      if(string[i-1] != '\n') insert_symbol(string, i, '\n');
      break;
    }
  }

  string[MAX_STRING_LENGTH] = '\0';
  /* Now allocate space and copy the string into it */
  newstr = (char *) malloc((strlen(string) + 1) * sizeof(char));
  strcpy(newstr, string);

  /* return pointer to the new formatted string */
  return newstr;
}  




/* the name of the function says it all. num of symbols till space or return 
   or end of the string is found */
int symbols_till_next_space_or_return(char *str)
{
  int i;
  for(i = 0; *(str+i);i++) {    
    if((*(str+i) == 32) || (*(str+i) == '\n') ) 
      return i;
  }
  return i;
}

/* Same as above, except spaces dont count now */
int symbols_till_next_return(char *str)
{
  int i;
  for(i = 0; *(str+i);i++) {    
    if(*(str+i) == '\n') 
      return i;
  }
  return i;
}




/* inserts a symbol in the string at a given position */
void insert_symbol(char *str, int pos, char symb)
{
  int i;
  char string[ 2 * MAX_STRING_LENGTH];
  strcpy(string, str);
  string[pos] = symb;

  for(i = pos; *(str + i); i++) 
     string[i+1] = *(str+i);
  
  string[i+1] = '\0';
  strcpy(str, string);
}




/* removes symbol from the string at a given position*/
void remove_symbol(char *str, int pos)
{
  int i;
  char string[2 * MAX_STRING_LENGTH];
  
  strcpy(string, str);
  for(i = pos; *(str + i); i++)
    string[i] = *(str + i + 1);
  
  strcpy(str, string);
}




/* Finds the specified word in the string and erases it */
void delete_word(char *str, int line, int pos)
{
  int i, k; 
  char *pstr = str;
  char word[MAX_INPUT_LENGTH];

  /* find the line */ 
  for(i=1;i<line;i++) {
    k = symbols_till_next_return(pstr);   
    if(!*(pstr + k)) return;
    pstr+=k; /* \n */
    pstr++;  /* \r */
    pstr++;  /* next symbol */
  } 

  if(pos == 1 && line > 1) pstr--;

  /* Find the word */
  for(i = 1;i < pos; i++) {
    pstr = one_argument_with_caps(pstr, word);
    if(!*pstr) return;
  }

  /* now skip some more spaces and get to the start of the needed word */
  while(*pstr == 32) pstr++;
  
  /* remove symbols one by one.. sorta lame but it works */
  while(*pstr && (*pstr!= 32) && (*pstr != '\n')) {
    remove_symbol(str, pstr - str);
  }

  /* if separated by space, remove it */
  if(*pstr == 32) remove_symbol(str, pstr - str);

}

/* inserts a symbol in the string at a given position */
char *insert_word(char *str, int line, int pos, char *word)
{

  int i, k; 
  char buf[MAX_INPUT_LENGTH];
  char string[2 * MAX_STRING_LENGTH];
  char *pstr;
  char *wptr;
  char *newstr;
   
  strcpy(string, str);
  pstr = string;

  /* find the line */ 
  for(i=1;i<line;i++) {
    k = symbols_till_next_return(pstr);   
    if(!*(pstr + k)) return NULL;
    pstr+=k; /* \n */
    pstr++;  /* \r */
    pstr++;  /* next symbol */
  } 

  /* if we need to insert in the very beginning of the line, back up one */
  if(pos == 1 && line > 1) pstr--;

  /* Find the word */
  for(i = 1;i < pos; i++) {
    pstr = one_argument_with_caps(pstr, buf);
    if(!*pstr) return NULL;
  }
 
  /* insert symbols one by one, sorta lame but it works */
  for(wptr = word, i = (pos == 1?0:1); *wptr; wptr++, i++) {
    insert_symbol(pstr, i, *wptr);
  } 

  insert_symbol(pstr, i, 32);

  string[MAX_STRING_LENGTH] = '\0';
  newstr = (char *)malloc((1 + strlen(string)) * sizeof(char));
 
  strcpy(newstr, string);
  return newstr;

}

ACMD(do_format)
{
  char *pnew;

  return;
  if(IS_NPC(ch)) return;

  one_argument(argument, arg);

  /* IF argument anything but "room", toggle the bit */
  if(!*arg || str_cmp(arg, "room")) 
  {
/*    REMOVE_BIT(PRF_FLAGS(ch), PRF_FORMAT);
    if(PRF_FLAGGED(ch, PRF_FORMAT)) 
      send_to_char("You will now format descriptions automatically.\r\n", ch);
    else 
      send_to_char("You will no longer format descriptions automatically.\r\n", ch);
*/
    return;
  }

  else {
    pnew = format_string(world[ch->in_room].description);
    free(world[ch->in_room].description);
    world[ch->in_room].description = pnew;
  }
  return;
}


ACMD(do_delword)
{

  char buf[80];
  int line = 0, pos = 0;
  int vnum;
  int zone;
  char *prest;
    
  if (IS_NPC(ch))
    return;

  prest = one_argument(argument, buf);
  line = atoi(buf);
  prest = one_argument(prest, buf);
  pos = atoi(buf);
  prest = one_argument(prest, buf);
 
  /* For now, default to the room that one is in */
  vnum = world[ch->in_room].number;
 
  if(!pos || !line) {
    send_to_char("Usage: delword <line> <word>. \n\r", ch);
    return;
  }

  zone = world[ch->in_room].zone;
  if (GET_LEVEL(ch) < LEV_CIMP && 
	(zone == 0 || 
	 zone < ch->pc_specials->saved.olc_min_zone ||
	 zone > ch->pc_specials->saved.olc_max_zone))
    {
	send_to_char("You don't have privileges to edit that room.\n\r", 
		     ch);
	return;
    }

  if (GET_LEVEL(ch) < LEV_CIMP)
    if (zone_table[zone].locked_id != GET_IDNUM(ch)) {
       send_to_char("You must ZLOCK that zone before you can edit it.\n\r",ch);
       return;
    }
   
  delete_word(world[ch->in_room].description, line, pos);

/* format if asking 
  if(PRF_FLAGGED(ch, PRF_FORMAT)) {
    pnew = format_string(world[ch->in_room].description);
    free(world[ch->in_room].description);
    world[ch->in_room].description = pnew;
  }
*/
  /* send the corrected string */
  send_to_char(world[ch->in_room].description, ch);
}

ACMD(do_insword)
{

  char buf[80];
  int line = 0, pos = 0;
  int vnum;
  int zone;
  char *prest;
  char *pnew;
    
  if (IS_NPC(ch))
    return;


  /* get the arguments: Line num, position Num, and the word itself */
  prest = one_argument(argument, buf);
  line = atoi(buf);
  prest = one_argument(prest, buf);
  pos = atoi(buf);
  prest = one_argument_with_caps(prest, buf);
  vnum = world[ch->in_room].number;
 
  if(!pos || !line) {
    send_to_char("Usage: insword <line> <pos> <word>. \n\r", ch);
    return;
  }

  zone = world[ch->in_room].zone;
  if (GET_LEVEL(ch) < LEV_CIMP && 
	(zone == 0 || 
	 zone < ch->pc_specials->saved.olc_min_zone ||
	 zone > ch->pc_specials->saved.olc_max_zone))
    {
	send_to_char("You don't have privileges to edit that room.\n\r", 
		     ch);
	return;
    }

  if (GET_LEVEL(ch) < LEV_CIMP)
    if (zone_table[zone].locked_id != GET_IDNUM(ch)) 
    {
       send_to_char("You must ZLOCK that zone before you can edit it.\n\r",ch);
       return;
    }
   
  pnew  = insert_word(world[ch->in_room].description, line, pos, buf);
  if(pnew) {
    free(world[ch->in_room].description);
    world[ch->in_room].description = pnew;
  }

/* format it if asking 
  if(PRF_FLAGGED(ch, PRF_FORMAT)) {
    pnew = format_string(world[ch->in_room].description);
    if(pnew) {
      free(world[ch->in_room].description);
      world[ch->in_room].description = pnew;
    }
  }
*/
  /* Send the new string to char */
  send_to_char(world[ch->in_room].description, ch);
}


/* find the first sub-argument of a string, return pointer to first char in
   primary argument, following the sub-arg  do NOT Ignore fill words.*/
char	*one_argument_with_caps(char *argument, char *first_arg)
{
   int	found, begin, look_at;

   found = begin = 0;

    /* Find first non blank */
    for ( ; isspace(*(argument + begin)); begin++)
      ;

    /* Find length of first word */
    for (look_at = 0; *(argument + begin + look_at) > ' ' ; look_at++)

      /* Make all letters lower case, AND copy them to first_arg */
      *(first_arg + look_at) = *(argument + begin + look_at);

    *(first_arg + look_at) = '\0';
    begin += look_at;

   return(argument + begin);
}