//
// Perhaps:  try making a raster have a graphics object as well!

import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import GfxLib.*;

public class Ps4 extends Applet implements Runnable { 


  private boolean DEBUG  = false;
  private boolean GOURAD = false;

  /*
   * Constants
   */ 
  private static final long GC_INTERVAL    = 10000;  // Millis between each System.gc()
  private static final int  framerate      = 8;      // Desired FPS
  private static final long millisPerFrame = 1000 / framerate;   

  /*
   * Member variables
   */
  private Pipeline3D mp;
  private Raster r;
  private Image m_imgBuffer;
  private Thread animator;
  private long rTime;
  private long[] bData;
  
  /*
   * Initializes the Applet, and draws the first frame of the
   * animation.
   */
  public void init()
  {
    r = new Raster(size().width, size().height);

    mp = new Pipeline3D(r);
    bData = new long[7];

    String filename = getParameter("datafile");
    showStatus("Reading "+filename);
    InputStream is = null;

    try
      {
	is = new URL(getDocumentBase(), filename).openStream();
	mp.ReadInput(is);
	is.close();
      } 
    catch (IOException e) 
      {
	showStatus("Error reading "+filename);
      }

    DrawObject();
    repaint();
  }

  /*
   * Starts the execution of the Applet by creating a Thread
   * to continually repaint the display
   */
  public void start()
  {        
    animator = new Thread(this);
    animator.start();
  }


  /**
   * This method is called by the thread that was created in
   * the start method. It does the main animation.
   */
  public void run() 
  {
    long tm;
    
    int tz[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
		 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
		 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
		 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
		 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };

    //mp.rotateObject(0, 1, 1, 1, 1.5f);
    while (Thread.currentThread() == animator)
      {
	System.gc();
	for (int i = 0; i < 30; i++)
	  {
	    mp.rotateObject(0, 1, 1, 1, .15f);
	    //mp.translateObject(0, 0, 0, tz[i]*.2f);

	    DrawObject();
	    repaint();
	    try
	      {
		Thread.sleep(200);
	      }
	    catch (InterruptedException e) {} 
	  }
	
	System.gc();
	for (int i = 0; i < 60; i++)
	  {
	    mp.rotateObject(0, 1, 1, 1, .15f);
	    //mp.translateObject(0, 0, 0, tz[i]*.2f);
	      
	    DrawObject();
	    repaint();
	    try
	      {
		Thread.sleep(200);
	      }
	    catch (InterruptedException e) {} 
	  }

      }
  }

  public void DrawObject()
  {
    r.fill(Color.black);    
    r.resetZBuffer();
    if (DEBUG) {
      if (GOURAD) {
	bData = mp.debugRenderGourad(r);
      }
      else {
	bData = mp.debugRender(r);
      }
    }
    else  {
      if (GOURAD) {
	mp.renderGourad(r);
      }
      else {
	mp.render(r);
      }
    }

    m_imgBuffer = r.toImage();
    repaint();
  }

  public boolean keyDown(Event evt, int key)
  {
    System.out.println(key);
    if (key == 100)  // 'd'
      {
	DEBUG = !DEBUG;
	return true;
      }
    else if (key == 103) // 'g'
      {
	GOURAD = !GOURAD;
	return true;
      }
    return super.keyDown(evt, key);
  }

  /*
   * Repaints the Applet
   */
  public void paint(Graphics g)
  {
    update(g);
  }
  
  /*
   * Draws our offscreen buffer to the Applet's 
   * Graphics context
   */
  public void update(Graphics g)
  {
    g.drawImage(m_imgBuffer, 0, 0, this);
    g.setColor(Color.white);
    if (DEBUG) {
      if (GOURAD) {
	g.drawString("Modeling time: " + bData[0], 20, 35);
	g.drawString("Culling time: " + bData[1], 20, 50);
	g.drawString("Illumination time: " + bData[2], 20, 65);
	g.drawString("Viewing time: " + bData[3], 20, 80);
	g.drawString("Drawing time: " + bData[4], 20, 95);
      }
      else {
	g.drawString("Modeling time: " + bData[0], 20, 35);
	g.drawString("Culling time: " + bData[1], 20, 50);
	g.drawString("Illumination time: " + bData[2], 20, 65);
	g.drawString("Viewing time: " + bData[3], 20, 80);
	g.drawString("Clipping time: " + bData[4], 20, 95);
	g.drawString("Drawing time: " + bData[5], 20, 110);
      }
    }
  }
}








