musicmud-2.1.6/data/
musicmud-2.1.6/data/help/
musicmud-2.1.6/data/policy/
musicmud-2.1.6/data/wild/
musicmud-2.1.6/data/world/
musicmud-2.1.6/doc/
musicmud-2.1.6/src/ident/
musicmud-2.1.6/src/lua/
musicmud-2.1.6/src/lua/include/
musicmud-2.1.6/src/lua/src/lib/
musicmud-2.1.6/src/lua/src/lua/
musicmud-2.1.6/src/lua/src/luac/
/* 
 * MusicMUD Daemon, version 1.0
 * Copyright (C) 1998-2003 Abigail Brady
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 * 
 */
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include "wordwrap.h"
#include "vsprintf.h"
#include "charset.h"
#include "colour.h"

static bool newline(char a) { return a=='\n' || a=='\v'; }

static int wordlength(const char *w2) {
  int length = 0;
  int intag = 0;
  int lasth = 0;
  int lastamp = 0;
  while (*w2) {
    if (length) {
      if(!intag && (*w2 == ' ') || newline(*w2) || lasth) {
        return length;
      }
    }
    if (*w2=='-' && !lastamp)
      lasth=1;
    if (*w2=='\3')
      intag=1;
    if (*w2=='\4')
      intag=0;

    lastamp = *w2 == '&';

    if(*w2) w2++;
    length++;
  }
  return length;
}

string wordwrap(const char *source, int width, int indent, 
		     const colourinfo_t &cs, int *col) {
  //   char *dp = dest; const char *sp = source, *wp; // source, dest, and start of source word pointers

  const char *sp = source, *wp;

   bool isstart = true; /* whether this is the first word on the line */
   int bytes, spaces, n;
   signed int xleft = width-1; /* number of columns left on the line.
                                * don't use the last column. */

   if (col) {
     xleft -= *col;
     if (*col)
       isstart = 0;
   }

   string dbuf;

   while(*sp) {
      bytes = wordlength(sp);
      spaces = colour_strlenof(sp, bytes, cs);
      /* Spaces is the actual APPARENT WIDTH -- needs to be renamed, yes */

      if((!isstart) && (spaces > xleft) && (spaces <= width)) {
        /* So here, if its TOO WIDE to fit in the remaining space, we
           reset to the beginning of the line. */
         isstart = 1;
         xleft = width-1;
         dbuf += '\v'; /* change this to a soft-newline, if we want to go that route */

         while (*sp==' ')
	   sp++;
	 if (*sp == ' ' || newline(*sp))
            sp++;
         /* And here we have an inexplicable indent bit */
	 if(*sp && !(sp > source && newline(sp[-1]))) {
	    for(n = 0; n < indent; n++) {
	       dbuf += ' ';
	       xleft--;
            }
	 }
         continue;
      }

      /* Bytes is the number of actual CHARACTERS.
         Includes the first character, including ' ' and '\n' */
      wp = sp;
      for(n = 0; (n < bytes) && *sp; n++) {
        /* This is where the actual word gets put in there */
         dbuf += *sp++;         
         if(newline(*(sp-1))) {
            isstart = 1;
            xleft = width-1;
	    spaces-=2; /* so that we don't count \n as a character? */
	    indent=0;
	    goto blah;
         } else if ((sp>=(source+2)) && (*(sp-2) == '^') && (*(sp-1) == 'Z')) {
	   if ((indent = ((width-xleft)-1) + colour_strlenof(wp, n-1, cs)) < 0)
	     indent = 0;
	   if (indent > 2*width/3)
	     indent = 2*width/3;
         }
      }
      xleft -= spaces;
      isstart = 0;
   blah:
      ;
   }
   /* xleft will be (width-1)-column */
   if (col)
     *col = (width-1)-xleft;
   return dbuf;
}

void unwordwrap(char *dest, const char *source, int bufsize) {
   char *dp = dest; const char *sp = source;
   int length=1;

   if(bufsize < 1) {
      *dest = '\0';
   }

   dest[bufsize-1] = '\0';
   while(*sp && (length < bufsize)) {
      if(*sp == '\n') {
         if(*(sp+1) == '\n') {
            while(*sp == '\n') {
               *dp++ = '\n';
               if(!(++length < bufsize)) return;
	       sp++;
            }
         } else {
	    if(*(++sp)) {
               *dp++ = ' ';
            } else {
	       *dp++ = '\n';
	    }
            if(!(++length < bufsize)) return;
         }
      } else {
         *dp++ = *sp++;
         if(!(++length < bufsize)) return;
      }
   }
   *dp = '\0';
   return;
}