/*
Datei............: Aufg1126.java
Projekt..........: Einführung in die Java-Programmierung
Erstellt.........: 21.11.97, Guido Krüger
Geändert.........: --
Aufgabe..........: Musterlösung zu Aufgabe 11.26
Kommentare.......:

Die nachfolgend dargestellte Lösung zu dieser Aufgabe unterteilt das
Problem in die zwei Teilprobleme

- Sammeln sovieler Worte, wie in eine Zeile passen.
- Formatiertes Ausgaben der Worte in einer Zeile.

Das erste Teilproblem kann mit Hilfe eines StringTokenizers elegant 
gelöst werden. Dazu werden einfach soviele Worte in einem Vektor 
gesammelt, wie inklusive der mindestens erforderlichen ein Zeichen
breiten Zwischenräume in die aktuelle Zeile passen. Sind es 
ausreichend viele, werden Sie mit der Methode linebufToString
formatiert und der Vektor wird geleert. Paßt das zuletzt gefundene
Wort dagegen noch komplett in die aktuelle Zeile, so wird es an
den Zeilenvektor angehängt und mit dem nächsten Wort fortgefahren.
Eine Sonderbehandlung erfahren Worte, die einzeln zu lang für 
eine komplette Zeile sind, sie werden unverändert ausgegeben.

Zur Formatierung eines Zeilenvektors wird zunächst geprüft, wieviel
Worte ausgegeben werden sollen. Die Anzahl der zu füllenden Lücken
ist um 1 kleiner. Um die Zeilen einigermaßen harmonisch aussehen
zu lassen, verfolgt das Programm die Strategie, die Lücken möglichst
gleich breit zu machen. Dazu wird die Gesamtzahl an verfügbaren 
Leerzeichen ganzzahlig durch die Anzahl der Lücken geteilt und
dieser Wert als Standard-Lückenbreite verwendet. Zusätzlich werden
die ersten n Lücken um ein Leerzeichen breiter, wobei n der Rest
der ganzzahligen Division der Gesamtzahl der verfügbaren Leerzeichen
durch die Anzahl der Lücken ist. Auf diese Weise stehen die etwas
breiteren Lücken immer links, was aber in der Praxis kaum störend
auffällt und die breiteste Lücke unterscheidet sich von der 
kürzesten um nicht mehr als ein Leerzeichen. Eine Sonderbehandlung
erfahren Zeilen, die nur ein Wort enthalten (hier gibt es gar keine
Lücken) und die letzte Zeile (alle Lücken haben die Breite 1).
*/
import java.util.*;

public class Aufg1126
{
  public static void main(String args[])
  {
	String s = "";
	s += "Schreiben Sie eine Methode leftRightAlign, die einen String ";
	s += "und ein int als Argument erwartet. Der übergebene String soll ";
	s += "dabei entsprechend der im zweiten Argument angegebenen ";
	s += "Zeilenbreite im Blocksatz formatiert und an den Aufrufer ";
	s += "zurückgegeben werden.";
	System.out.println(leftRightAlign(s, 40));
  }

  public static String leftRightAlign(String s, int maxlinelen)
  {
	StringTokenizer st = new StringTokenizer(s);
	Vector linebuf = new Vector();
	int lenwords = 0;
	String ret = "";
	while (st.hasMoreTokens()) {
	  String word = st.nextToken();
	  if (lenwords + linebuf.size() + word.length() > maxlinelen) {
		//Zeilenpuffer ausgeben
		ret += linebufToString(linebuf, maxlinelen, lenwords, false);
		//Zeilenpuffer leeren
		linebuf = new Vector();
		lenwords = 0;
	  }
	  if (word.length() >= maxlinelen) {
		//Wort in einer einzelnen Zeile ausgeben
		ret += word + "\r\n";
	  } else {
		//Wort an den Zeilenpuffer anhängen
		linebuf.addElement(word);
		lenwords += word.length();
	  }
	}
	ret += linebufToString(linebuf, maxlinelen, lenwords, true);
	return ret;
  }

  private static String linebufToString(
	Vector linebuf, int maxlinelen, int lenwords, boolean lastline
  )
  {
	String ret = "";
	if (linebuf.size() > 1) {
	  //Mindestens zwei Worte in der Zeile
	  int stndgap = (maxlinelen - lenwords) / (linebuf.size() - 1);
	  int biggaps = (maxlinelen - lenwords) % (linebuf.size() - 1);
	  for (int i = 0; i < linebuf.size(); ++i) {
		if (i >= 1) {
		  if (lastline) {
			ret += " ";
		  } else {
			for (int j = 0; j < stndgap; ++j) {
			  ret += " ";
			}
			if (i <= biggaps) {
			  ret += " ";
			}
		  }
		}
		ret += (String)linebuf.elementAt(i);
	  }
	  ret += "\r\n";
	} else if (linebuf.size() > 0) {
	  //Nur ein Wort in der Zeile
	  ret += (String)linebuf.elementAt(0);
	  ret += "\r\n";
	}
	return ret;
  }
}


