     //////////////////////////////////
    // LINE-SPLITTER                 //
   // Written by Andrew Broad       ///
  //                               ////
 // Lines.java (2003:03:05 13:58) /////
///////////////////////////////////////
// Methods of Lines:              /////
// - static maxLineLength         ////
// - static splitLongLines        ///
// - static main                  //
///////////////////////////////////

import java.io.*;

/*****************************************************************************
** The class `Lines' implements two related functions: to compute the maximum
** line-length of a text file, and to split lines that are longer than a given
** maximum by inserting newlines (e.g. 78 for printing on LaserJet2).
*****************************************************************************/

public class Lines {
	/********************************************************************/
	// static Lines.maxLineLength : BufferedReader -> int
	/*********************************************************************
	** Computes the maximum line-length of a text file.
	** @param br A BufferedReader object representing the text file.
	** @return The maximum line-length of the file.
	*********************************************************************/

	private static int maxLineLength (BufferedReader br) {
		String line;
		int maxLineLength= 0;
		try {
			while ((line= br.readLine()) != null) {
				if (line.length() > maxLineLength) {
					maxLineLength= line.length();
				}
			}
		} catch (IOException ioe) {
			System.err.println("Lines.maxLineLength: IOException "
			+ "thrown by BufferedReader.readLine()");
			System.exit(1);
		}
		return maxLineLength;
	}

	/********************************************************************/
	// static Lines.splitLongLines : BufferedReader x int -> void
	/*********************************************************************
	** Outputs a text file to stdio such that lines longer than a
	** specified limit are split by inserting newlines.
	** @param br A BufferedReader object representing the text file.
	** @param maxLineLength The maximum line-length of the file.
	*********************************************************************/

	private static void splitLongLines (BufferedReader br,
	                                    int maxLineLength)
	{
		if (maxLineLength < 1) {
			System.err.println("Lines.splitLongLines(" + br + ", "
			+ maxLineLength + "): maxLineLength must be a positiv"
			+ "e integer!");
			System.exit(1);
		}
		String line;
		try {
			while ((line= br.readLine()) != null) {
				StringBuffer lineSB= new StringBuffer(line);
				for (int offset= maxLineLength;
				     offset < lineSB.length();
				     offset+= maxLineLength + 1)
				{
					lineSB.insert(offset, "\r\n");	
				}
				System.out.println(lineSB);
			}
		} catch (IOException ioe) {
			System.err.println("Lines.splitLongLines: IOException"
			+ " thrown by BufferedReader.readLine()");
			System.exit(1);
		}
	}

	/********************************************************************/
	// static Lines.main : String[] -> void
	/*********************************************************************
	** The entry-point of Lines. This implements two functions: either
	** computing and printing the maximum-line length of a text file, or
	** splitting lines over a given length limit by inserting newlines.
	** In the latter case, the processed text file is output on stdio, the
	** intention being to redirect it to a text file.
	** @param argv The vector of command line arguments. There should be
	**             at least one of these: the first argument must be the
	**             filename of a text file, and the optional second
	**             argument is the maximum line-length of the file - any
	**             lines over this length will be split by inserting
	**             new lines. If the second argument is absent, the
	**             program computes and prints the maximum line-length of
	**             the file instead.
	*********************************************************************/

	public static void main (String argv[]) {
		if (argv.length < 1 || argv.length > 2) {
			System.err.println("Usage: java Lines <filename.txt>"
			+ "\nor     java Lines <filename1.txt> <max_line_leng"
			+ "th> > <filename2.txt>"
			+ "\n       where filename1.txt != filename2.txt");
			System.exit(1);
		}

		BufferedReader br= null; FileInputStream fis= null;
		try {
			br= new BufferedReader(new InputStreamReader
		                 (fis= new FileInputStream(argv[0])));
		} catch (FileNotFoundException fnfe) {
			System.err.println("Lines.main: FileNotFoundException"
			+ " for \"" + argv[0] + "\"");
			System.exit(1);
		}

		if (argv.length == 1) {
			System.out.println("Maximum line length is "
			+ maxLineLength(br) + ".");
		} else {
			try {
				splitLongLines(br, Integer.parseInt(argv[1]));
			} catch (NumberFormatException nfe) {
				System.err.println(argv[1] + " doesn't parse "
				+ "as an integer!");
				System.exit(1);
			}
		}

		try {
			fis.close();
		} catch (IOException ioe) {
			System.err.println("FileInputStream.close threw an "
			+ "IOException!");
			System.exit(1);
		}
	}
}
