/*
 * $Source: /afs/sipb.mit.edu/project/sipbsrc/src/xscreensaver/RCS/wordwrap.c,v $
 * $Author: jik $
 * 
 * This file is part of xscreensaver.  It contains routines for
 * wrapping a string of words into separate lines (and a routine for
 * discarding a set of wrapped lines).
 *
 * Author: Jonathan Kamens, MIT Project Athena and
 *                          MIT Student Information Processing Board
 *
 * Copyright (c) 1989 by Jonathan Kamens.  This code may be
 * distributed freely as long as this notice is kept intact in its
 * entirety and every effort is made to send all corrections and
 * improvements to the code back to the author.  Also, don't try to
 * make any money off of it or pretend that you wrote it.
 */

#ifndef lint
static char rcsid_wordwrap_c[] = "$Header: /afs/sipb.mit.edu/project/sipbsrc/src/xscreensaver/RCS/wordwrap.c,v 1.3 90/02/01 13:50:12 jik Exp $";
#endif

#include "xsaver.h"
#include "globals.h"

extern char *my_malloc();




static char *string_less_than_n(str, n, next)
char *str;
int n;
char **next; /* RETURN */
{
     char *buf;
     char *beginptr, *endptr;

     beginptr = str;
     /* First, throw away any blanks at the beginning of the line */
     while (*beginptr == ' ')
	  beginptr++;
     /* Next, check if there is a linebreak within the required line */
     /* length */
     endptr = index(beginptr, '\n');
     if (endptr && (endptr - beginptr <= n)) {
	  /* There is a linebreak, so we return everything up to the */
	  /* linebreak as the string, and return one past the */
	  /* linebreak as the next string */
	  buf = my_malloc(endptr - beginptr + 1, "lock message");
	  strncpy(buf, beginptr, endptr - beginptr);
	  buf[endptr - beginptr] = '\0';
	  *next = endptr + 1;
	  return(buf);
     }
     if (strlen(beginptr) > n) {
	  /* find the first space within the requested length */
	  endptr = beginptr + n;
	  while ((*endptr != ' ') && (endptr > beginptr))
	       endptr--;
	  if (endptr == beginptr) {
	       /* there are no spaces, so we make the return string */
	       /* the maximum width, put a null at the end of it and */
	       /* return as the next pointer one after the last */
	       /* character in buf.  */
	       buf = my_malloc(n + 1, "lock message");
	       strncpy(buf, beginptr, n);
	       buf[n] = '\0';
	       *next = beginptr + n;
	       return(buf);
	  }
	  else {
	       /* we've found a space.  The character before it is the */
	       /* last character in the return array. */
	       buf = my_malloc(endptr - beginptr + 1, "lock message");
	       strncpy(buf, beginptr, endptr - beginptr);
	       buf[endptr - beginptr] = '\0';
	       *next = endptr + 1;
	       return(buf);
	  }
     }
     else {
	  /* the string is less than the maximum length, so we return */
	  /* the whole thing */
	  buf = my_malloc(strlen(beginptr) + 1, "lock message");
	  strcpy(buf, beginptr);
	  *next = (char *) NULL;
	  return(buf);
     }
}



char **word_wrap(str, ln_lngth, max_lines)
char *str;
int ln_lngth, max_lines;
{
     char *next_string;
     char **string_list, **begin;
     
     begin = string_list = (char **) my_malloc(sizeof(char *) * 
					       (max_lines + 1),
					       "lock message");

     for (next_string = str; next_string && max_lines; 
	    max_lines--, string_list++)
	  *string_list = string_less_than_n(next_string, ln_lngth,
					    &next_string);
     *string_list = (char *) NULL;

     return(begin);
}




void discard_wrap(lines)
char **lines;
{
     char **ptr;

     for (ptr = lines; *ptr; ptr++)
	  free(*ptr);

     free(lines);
}


