/*************************
 * Duncan Bryce          *
 * 6.837 Project #2      *
 * TA Jacob Schwartz     *
 ************************/

import java.awt.*;
import java.net.URL;
import java.applet.Applet;
import java.io.*;
import java.util.StringTokenizer;
import java.util.Vector;
import GfxLib.*;

/*******************************************************
 * 
 * The Ps2 class is a simple Applet designed to test
 * my scan-converter.  It reads in a Triangle file, and
 * outputs the specified image to the screen
 *
 ******************************************************/

public class Ps2 extends Applet
{
  private Color    background;
  private Raster   display;
  private Image    imgBuffer;
  private int      triangles;
  private Drawable triList[];

  public void init()
  {
    background = Color.white;
    display    = new Raster(460, 175);
    triangles  = 0;
    triList    = new Drawable[100];

    try 
      {
	InputStream is = new URL(getDocumentBase(), 
				 getParameter("datafile")).openStream();
	ReadInput(is);
	is.close();
      } 
    catch (IOException e) 
      {
	showStatus("Error reading "+getParameter("datafile"));
      }
    
    render();
    repaint();
  }

  public void paint(Graphics g)
  {
    g.drawImage(imgBuffer, 0, 0, this);
  }

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

  // define legal characters for our parser
  // The remainder of a line after a '#' is ignored
  // you might find this helpful for debugging
  private void configureParser(StreamTokenizer st) 
  {
    st.ordinaryChars(0, 255);
    st.wordChars('a', 'f');
    st.wordChars('A', 'F');
    st.wordChars('0', '9');
    st.wordChars('-', '-');
    st.wordChars('.', '.');
    st.wordChars('x', 'x');
    st.wordChars('X', 'X');
    st.whitespaceChars(' ', ' ');
    st.whitespaceChars('\t', '\t');
    st.whitespaceChars('\n', '\n');
    st.whitespaceChars('\r', '\r');
    st.eolIsSignificant(false);
    st.commentChar('#');
  }

  // parse a floting point number
  private float getNumber(StreamTokenizer st) throws IOException 
  {
    st.nextToken();
    return (Float.valueOf(st.sval).floatValue());
  }

  // parse a packed integer in hex, octal, or decimal
  private int getColor(StreamTokenizer st) throws IOException 
  {
    st.nextToken();
    int pix;
    if (st.sval.startsWith("0x") || st.sval.startsWith("0X")) 
      {
	pix = (int) Long.parseLong(st.sval.substring(2), 16);
      } 
    else if (st.sval.startsWith("0") || st.sval.length() > 1) 
      {
	pix = (int) Long.parseLong(st.sval.substring(1), 8);
      } 
    else
      {
	pix = Integer.parseInt(st.sval);
      }
    return pix;
  }
  
  // extend the triangle array if needed
  private void growList() 
  {
    Drawable newList[] = new Drawable[triList.length*2];
    System.arraycopy(triList, 0, newList, 0, triList.length);
    triList = newList;
  }

  
  // Scan the triangle file
  public void ReadInput(InputStream is) throws IOException 
  {
    Vertex2D v1, v2, v3;
    int currentvert = 0;
    float x, y;
    int pix;
    
    StreamTokenizer st = new StreamTokenizer(is);
    configureParser(st);
    while (st.nextToken() != StreamTokenizer.TT_EOF) 
      {
	st.pushBack();
	x = getNumber(st);
	y = getNumber(st);
	pix = getColor(st);
	v1 = new Vertex2D(x, y, pix);
	x = getNumber(st);
	y = getNumber(st);
	pix = getColor(st);
	v2 = new Vertex2D(x, y, pix);
	x = getNumber(st);
	y = getNumber(st);
	pix = getColor(st);
	v3 = new Vertex2D(x, y, pix);
	if (triangles == triList.length) growList();
	triList[triangles++] = new Triangle(v1, v2, v3);
      }
  }
	
  private void render()
  {
    display.fill(background);
    for (int i = 0; i < triangles; i++)
      {
	triList[i].Draw(display);
      }
    imgBuffer = display.toImage( );
  }
}
  


