/**
 * Class HtmlPrintStream
 * extends PrintStream.
 * A custom made PrintStream which overrides methods println(String)
 * and print(String), so that when the out stream is set to this PrintStream
 * (with System.setOut method), some html markups are added to the output 
 * in a judicious way, regarding the effective text structure.
 * The resulting streaming output may be viewed by an HTML browser.
 **/

package axsvg;

import axsvg.*;
import java.io.*;

public class HtmlPrintStream extends PrintStream {

    // A boolean which is true if the last markup inserted in the descrciption
    // currently output is a <li> one.
    private boolean lastMarkupLi;

    // The standard Printstream. Its print(String) method will be called
    // to perform the output once the html markups have been added.
    private PrintStream out;

    /**
     * Method HtmlPrintStream
     * The constructor of the class.
     * @param a standard output stream (needed by super method)
     **/
    public HtmlPrintStream(PrintStream output) {
	super(output);
	out = output;
	lastMarkupLi = false;
    }

    /**
     * Method println
     * @param the String to be printed
     * Calls this object method print(String), and draws a new line.
     **/
    public void println(String string) {
	this.print(string);
	out.println();
	
    }


    /**
     * Method print
     * @param the String to be printed.
     * Checks if the String to be printed starts a new line, ends a line,
     * will be followed by a new enumeration, or is part of an enumeration.
     * Then, outputs the corresponding html tags (<p>, <ul>, <li>) at the
     * right place.
     * Calls customizedPrint to print the resulting string.
     **/
    public void print(String string) {
	boolean startline = false;
	boolean endline = false;
	boolean newenum = false;
	boolean newli = false;

	Character first= new Character(string.charAt(0));
	if(first.isUpperCase(string.charAt(0))) {
	    startline = true;
	}
	else {
	    startline = false;
	}
	if(string.endsWith(":")) {
	    newenum = true;
	}
	else {
	    newenum = false;
	}
	if(string.startsWith(" -")) {
	    //eliminate the "-" replaced by the <li> markup.
	    string = string.substring(2);
	    newli = true;
	}
	else {
	    newli = false;
	}
	if(string.endsWith(".") ||
	   string.equals("In this document: "))
	   endline = true; else endline = false;

	if(startline) {
	    if(lastMarkupLi) {
		out.println("</ul>");
		out.println("</p>");
		lastMarkupLi = false;
	    }
	    out.print("<p>");
	}

	if(newli) {
	    out.print("<li>");
	    lastMarkupLi = true;
	}

	this.customizedPrint(string);

	if(newenum) {
	    out.println();
	    out.println("<ul>");
	    lastMarkupLi = false;
	}

	if(endline) {
	    if(lastMarkupLi) {
		out.println("</li>");
	    }
	    else {
		out.println("</p>");
		lastMarkupLi = false;
	    }
	}
    }


    /**
     * Method customizedPrint
     * @param the string to be output.
     * Finds the entity names in the string to be output, and embraces them
     * with <strong></strong> markups.
     **/
    private void customizedPrint(String string) {
	int entityNameIndex = string.indexOf("#");
	if(entityNameIndex != -1) {
	    int entityEndIndex = string.indexOf("#",entityNameIndex+1);
	    String firstPart = string.substring(0,entityNameIndex);
	    String entity = string.substring(entityNameIndex+1,entityEndIndex);
	    String lastPart = string.substring(entityEndIndex+1);
	    
	    out.print(firstPart);
	    out.print("<strong>");
	    out.print(entity);
	    out.print("</strong>");
	    out.print(lastPart);
	}
	else {
	    out.print(string);
	}
    }	
}


