
import java.awt.*;
import java.util.*;

import java.net.*;
import java.io.*;

/** PostScript output from ASCII,
 * to a file or for immediate printing,
 * if your printer can accept it.

 * Thin wrapper over PSGr just for text pages.

 * Java incorrectly treats font points and pixels as equivalent,
 * which requires scaling of screen images but is OK here,
 * since we care only about text.
 * We use a default 680 x 792 pixel (and point) space,
 * equivalent to 8.5 x 11 inch paper.
 *
 * @author Morris Hirsch IPD 1998 */

public class PSPrint {

    protected PSGr psg;

    protected Font font;

    protected Color fg = Color.black;

    protected Color bg = Color.white;

    protected int
	px,
	py;

    protected int leading = 0;

    protected int
	lines,
	pages;

    protected boolean striping = false;

    protected int points = 0;

    protected int
	page_margin,
	page_height,
	page_width;

/** Constructor using output Stream and reference Graphics.
 * Caller is responsible to later close the Stream.
 * @param fos -- output Stream,
 * @param g -- reference Graphics */

    public PSPrint (PrintStream fos, Graphics g) {
	this (new PSGr (fos, g));
    }

/** Constructor using output Stream and reference Graphics,
 * providing non-default page size and / or margin.
 * Caller is responsible to later close the Stream.
 * @param fos -- output Stream,
 * @param g -- reference Graphics
 * @param margin -- margin all four sides in points,
 * @param w -- page width in points,
 * @param h -- page height in points */

    public PSPrint (PrintStream fos, Graphics g, int margin, int w, int h) {
	this (new PSGr (fos, g, margin, w, h));
    }

/** Constructor using PSGr. */

    public PSPrint (PSGr psg) {
	this.psg = psg;

        page_margin = psg.getPageMargin ();
        page_height = psg.getPageHeight ();
        page_width = psg.getPageWidth ();

	font = psg.getFont ();
	if (null == font)
	    font = new Font("Courier", Font.PLAIN, 14);

        points = font.getSize ();

/* Start at top of empty page */

	pages = 0;
        clear ();
    }

/* margins provided by PSGr so do not set them again here. */

    public void clear () {
	lines = 0;
	px = 0;
	py = 0;
	psg.setFont (font);
    }

/** Set working Font,
 * can change at any time. */

    public void setFont (Font font) {
	psg.setFont (font);
	points = font.getSize ();
    }

/** Set working FG Color,
 * can change at any time. */

    public void setForeground (Color fg) {
	this.fg = fg;
    }

/** Set working BG Color,
 * can change at any time. */

    public void setBackground (Color bg) {
	this.bg = bg;
    }

/** Set striping on or off,
 * on to alternate brighter and darker BG fills.
 * Can change at any time.
 ** WE COULD INSTEAD OF BOOLEAN
 * take a number of rows here,
 * zero default means no striping,
 * one means alternate by single lines,
 * N means alternate groups of N. */

    public void setStriping (boolean striping) {
	this.striping = striping;
    }

/** Set leading (extra height) between rows,
 * default is zero,
 * can change at any time. */

    public void setLeading (int leading) {
	this.leading = leading;
    }

/** Print lines from a Stream until done,
 * and flush final page.
 * Caller still must this.dispose () when done. */

    public void print (DataInputStream fis) throws IOException {
        String line;
        while (null != (line = fis.readLine ()))
	    print (line);

        if (0 < lines)
	    psg.showpage ();
    }

/** Add a line to the current page,
 * advance down the page by current point size,
 * or if it is now full,
 * flush the page and ready a new one.
 * If striping is on,
 * alternate brighter and darker BG fills. */

    public void print (String line) {
	lines++;

/* Remember that fillRect (x, y, w, h) from top,
 * but drawString (line, px, py) from bottom!
 * bg.darker () and bg.brighter () are a bit too much so,
 * but I don't know how to moderate them. */

        if (striping) {
	    if (0 == (lines & 1))
                psg.setColor (bg.darker ());
	    else
                psg.setColor (bg.brighter ());
	}

	else
            psg.setColor (bg);

	psg.fillRect (px, py, 999, points);

        psg.setColor (fg);
	psg.drawString (line, px, py+points);

//System.out.println (line+" at "+px+","+py);

	py += points;

        py += leading;

/* If not enough room for another line and the bottom margin, */

	if (py > page_height - 2 * page_margin) {
	    psg.showpage ();
	    clear ();
	    pages++;
	}
    }

/** Flush the current page and be done. */

    public void dispose () {
        if (0 < lines)
	    psg.showpage ();
	psg.dispose ();
	psg = null;
    }

}
/* <IMG SRC="/cgi-bin/counter">*/
