/* Auteur: Nicolas JANEY          */
/* nicolas.janey@univ-fcomte.fr   */
/* Fevrier 2005                   */

import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.print.*;
import javax.print.attribute.*;
import java.awt.font.*;
import java.awt.geom.*;

public class CanvasConsole extends Canvas
                           implements Printable {
  public static boolean open = false;
  public Vector<String> lignes;
  public int maxl;
  public int lc;
  private CurseurCanvasConsole ccc;
  public boolean curseur = true;
  private FrameConsole fc;
  private boolean top = true;
  private int size;
  private Font font;
  private int width;
  private int height;
  private String defaultFont = "Courier new";
  private int defaultSize = 18;
  private int defaultStyle = Font.BOLD;
  private boolean c = false;
  private int cpxi;
  private int cpxf;
  private int cpy;
  private int oldDeb = 0;

  public CanvasConsole(FrameConsole fc,int maxl) {
    lignes = new Vector<String>();
    this.maxl = maxl;
    this.fc = fc;
    size = defaultSize;
    font = new Font(defaultFont,defaultStyle,defaultSize);
    lc = 0;
    lignes.add("");
    ccc = new CurseurCanvasConsole(this,700);
    ccc.start();
  }

  public void effacer() {
    lc = 0;
    lignes = new Vector<String>();
    lignes.add("");
  }

  public void sauve(PrintWriter dis) {
    for ( int i = 0 ; i <= lc ; i++ )
      dis.println((String) lignes.elementAt(i));
  }

  public void print(String s) {
    StringTokenizer st = new StringTokenizer(s,"\n",true);
    while ( st.hasMoreTokens() ) {
      String tk = st.nextToken();
      if ( ( tk.length() == 1 ) && ( tk.charAt(0) == '\n' ) ) {
        tk = new String("");
        lignes.add(tk);
        lc++; }
        else {
        String str = format((String) lignes.elementAt(lc));
        str = str.concat(tk);
        lignes.setElementAt(str,lc); } }
    top = true;
    repaint();
  }

  public String format(String s) {
    return(s);
  }

  public void update(Graphics g) {
    paint(g);
  }

  public void paint(Graphics g) {
    Insets insFc = fc.getInsets();
    Insets insSp = fc.sp.getInsets();
    int vsize = g.getFontMetrics().getHeight()+6;
    vsize = defaultSize+4;
    setSize(fc.sp.getViewportSize().width,maxl*vsize+5);
    fc.validate();
    Graphics2D g2 =(Graphics2D) g;
    g2.setFont(font);
    int deb = ( lc+1 > maxl ) ? lc-maxl+1 : 0;
    if ( deb != oldDeb ) {
      g2.setColor(Color.white);
      g2.fillRect(0,0,fc.sp.getViewportSize().width,maxl*vsize+5);
      oldDeb = deb; }
    g2.setColor(Color.black);
    for ( int i = deb ; i <= lc ; i++ )
      g2.drawString(format((String) lignes.elementAt(i)),4,13+(i-deb)*vsize);
    String str = format((String) lignes.elementAt(lc));
    int l = 0;
    if ( Console.line != null ) {
      g2.setColor(Color.white);
      g2.fillRect(4+g.getFontMetrics().stringWidth(str),
                  13+(lc-deb)*vsize-vsize,
                  getWidth(),
                  vsize);
      g2.setColor(Color.black);
      g2.drawString(Console.line,4+g.getFontMetrics().stringWidth(str),13+(lc-deb)*vsize);
      l = Console.line.length(); }
    int posx = 4+g.getFontMetrics().stringWidth(str)+
               (( Console.line != null ) ? g.getFontMetrics().stringWidth(Console.line) : 0);
    if ( curseur ) {
      if ( c ) {
        g2.setColor(Color.white);
        g2.drawLine(cpxi,cpy,cpxf,cpy); }
      g2.setColor(Color.black);
      c = true;
      g2.drawLine(cpxi = posx,
                  cpy = 13+(lc-deb)*vsize,
                  cpxf = posx+(size/2+1),
                  13+(lc-deb)*vsize); }
      else {
      if ( c ) {
        g2.setColor(Color.white);
        g2.drawLine(cpxi,cpy,cpxf,cpy); }
      g2.setColor(Color.white);
      c = false;
      g2.drawLine(cpxi = posx,
                  cpy = 13+(lc-deb)*vsize,
                  cpxf = posx+(size/2+1),
                  13+(lc-deb)*vsize); }
    g2.setColor(Color.black);
    if ( top == true ) {
      if ( lc < fc.sp.getViewportSize().height/vsize-1 )
        fc.sp.setScrollPosition(0,0);
        else
        fc.sp.setScrollPosition(0,(lc+1-fc.sp.getViewportSize().height/vsize)*vsize);
      top = false; }
  }

  public int print(Graphics g,PageFormat pageFormat,int page) {
    Graphics2D g2 =(Graphics2D) g;
    Font f = new Font("Courier",Font.PLAIN,size);
    g2.setFont(f);
    { FontRenderContext frc = new FontRenderContext(g2.getTransform(),false,false);
      Rectangle2D r = f.getStringBounds("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",frc);
      width =(int) (pageFormat.getImageableWidth()/r.getWidth()*100);
      height =(int) (pageFormat.getImageableHeight()/size); }
    if ( page*height > lc+1 )
      return(Printable.NO_SUCH_PAGE);
    int cx =(int) pageFormat.getImageableX();
    int cy =(int) pageFormat.getImageableY();
    int pg = 0;
    int li = page*height;
    int lf = (page+1)*height-1;
    if ( lf > lc )
      lf = lc;
    for ( int i = li ; i <= lf ; i++ ) {
      g2.drawString(format((String) lignes.elementAt(i)),cx,cy+(i-li+1)*size); }
    return(Printable.PAGE_EXISTS);
  }
}