/* The source code in this file was taken from the 
** 'fold' program that's part of the GNU textutils
** package, and *slightly* modified to suit Manhattan's
** needs.
**
** The original 'fold' program was written by:
**
**  David MacKenzie, djm@gnu.ai.mit.edu
**
** The original source code for the unaltered 'fold'
** utility is available as part of the coreutils package
** at:
**
**    http://ftp.gnu.org/pub/gnu/coreutils/
**
*/


#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
       
#include "../global.h"
#include "shared_cs_util.h"
#include "shared_msg_line.h"   /* for CONTINUATION_CHAR */

/* Assuming the current column is COLUMN, return the column that
   printing C will move the cursor to.
   The first column is 0. */

static size_t
adjust_column (size_t column, char c)
{
 
      if (c == '\b')
	{
	  if (column > 0)
	    column--;
	}
      else if (c == '\r')
	column = 0;
      else if (c == '\t')
	column = column + 8 - column % 8;
      else /* if (isprint (c)) */
	column++;
  return column;
}




void
write_folded(FILE *fp, char *string, int width)
{
#define REALLOC_SIZE 250
  char *ptr;
  register int c;
  size_t column = 0;		/* Screen column where next char will go. */
  size_t offset_out = 0;	/* Index in `line_out' for next char. */
  static char *line_out = NULL;
  static size_t allocated_out = 0;
    
  for(ptr=string; *ptr; ptr++)
    {
      c = *ptr;
      if(c == '\r')    /* strip carriage returns */
          continue;
          
      if (offset_out + 1 >= allocated_out)
       {
	line_out = realloc (line_out,REALLOC_SIZE );
	if(!line_out)
	   cs_critical_error(ERR_MALLOC_FAILED, "do_fold()");
	allocated_out += REALLOC_SIZE;
       }	   

      if (c == '\n')
	{
	  line_out[offset_out++] = c;
	  fwrite (line_out, sizeof (char), offset_out, fp);
	  column = offset_out = 0;
	  continue;
	}

    rescan:
      column = adjust_column (column, c);

      if (column > width)
	{
	  /* This character would make the line too long.
	     Print the line plus a newline, and make this character
	     start the next line. */
	      int found_blank = 0;
	      size_t logical_end = offset_out;

	      /* Look for the last blank. */
	      while (logical_end)
		{
		  --logical_end;
		  if ((line_out[logical_end] == ' ') || (line_out[logical_end] == '\t'))
		    {
		      found_blank = 1;
		      break;
		    }
		}

	      if (found_blank)
		{
		  size_t i;

		  /* Found a blank.  Don't output the part after it. */
		  logical_end++;
		  fwrite (line_out, sizeof (char), (size_t) logical_end,fp);
		  fprintf(fp,"%c", '\n');
		  /* Move the remainder to the beginning of the next line.
		     The areas being copied here might overlap. */
		  memmove (line_out, line_out + logical_end,
			   offset_out - logical_end);
		  offset_out -= logical_end;
		  for (column = i = 0; i < offset_out; i++)
		    column = adjust_column (column, line_out[i]);
		  goto rescan;
		}

	  if (offset_out == 0)
	    {
	      line_out[offset_out++] = c;
	      continue;
	    }

	  if(!found_blank)
	      line_out[offset_out++] = CONTINUATION_CHAR;  /* #defined in shared_msg_line.h */
	  line_out[offset_out++] = '\n';
	  fwrite (line_out, sizeof (char), (size_t) offset_out, fp);
	  column = offset_out = 0;
	  goto rescan;
	}

      line_out[offset_out++] = c;
    }


  if (offset_out)
    fwrite (line_out, sizeof (char), (size_t) offset_out, fp);

  if(line_out)
    free(line_out);


#undef REALLOC_SIZE
}





void
write_folded_text (char *fname, char *string, int width)
{
  FILE *fp;

  fp = fopen(fname, "w");
  if(!fp)
     cs_critical_error(ERR_FOPEN_WRITE_FAILED, fname);
  write_folded(fp, string, width);

  fclose(fp);

}


 

