import java.awt.*;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Event;
import java.io.StreamTokenizer;
import java.io.InputStream;
import java.io.IOException;
import java.net.URL;
 

/** The drawing area for the parametric surface **/
class ImageCanvas extends Canvas
{
 int dvert[], num;
 int dcon[], numcon;
 float axes[];
 int max[],min[];
 Matrix3D amat = new Matrix3D();
 Matrix3D tmat = new Matrix3D();
 
 // Contructor for the drawing canvas. It sets the background color to black.
 public ImageCanvas() {
 super();
 setBackground(new Color(0,0,0));
}
 
 
 public Dimension preferredSize()
 {
  return minimumSize();
 }
 
 /* Sets the vertices list and face list for the surface. It also sets the coordinate axes for surface */
 public void draw(int vert[], int numvert, int con[],int ncon)
 {
  Dimension d = size();
 
  dvert = new int[numvert*3];
  System.arraycopy(vert, 0, dvert, 0, vert.length);
  dcon = new int[ncon];
  System.arraycopy(con, 0, dcon, 0, ncon);
  num = numvert;
  numcon = ncon;
 
  // Initialize the coordinate axes
  axes = new float[12];
  max = new int[3];
  min = new int[3];

  axes[0] = 40.0f;
  axes[1] = 300.0f;
  axes[2] = 50.0f;
  axes[3] = 40.0f;
  axes[4] = 300.0f;
  axes[5] = 10.0f;
  axes[6] = 40.0f;
  axes[7] = 260.0f;
  axes[8] = 50.0f;
  axes[9] = 80.0f;
  axes[10] = 300.0f;
  axes[11] = 50.0f;

  for (int i = 0; i < 3 ; i++)
  {
   max[i] = (int)axes[i];
   min[i] = (int)axes[i];
  }
 
  // Determine the bounding box of the axes.
  for (int i = 0; i < 3 ; i++)
  {
   for (int j = i ; j < 12; j+=3)
   {
    if (axes[j] > max[i])
     max[i] = (int)axes[j];
    if ( axes[j] < min[i])
     min[i] = (int)axes[j];
   }
  }
 
  // Transform the axes to the required positoin on the canvas.
  tmat.unit();
  tmat.translate(-(max[0] + min[0])/2, -(max[1] + min[1])/2, -(max[2] + min[2])/2);
  tmat.mult(amat);
  tmat.translate((int)axes[0],(int)axes[1],(int)axes[2]);
 }

 /* Sets the coordinate axes transformation matrix to interpret the axes rotation
 with the mouse*/
 public void setRotate(Matrix3D mat)
 {
  amat.mult(mat);
 }
 
 /** Paint this model to a graphics context.  It uses the matrix associated
    with this model to map from model space to screen space. */
 public void paint (Graphics g)
 {
  Dimension d = size();
 
  if ( dvert == null || num <=0 || dcon == null)
   return;
  g.setColor(new Color(255,0,0));
 
  int lim = numcon;
  int c[] = dcon;
  int v[] = dvert;
 
  if (lim <= 0 || num <= 0)
   return;
 
  // Draw the parametric surface
  for (int i = 0; i < lim; i++)
  {
   int T = c[i];
   int p1 = ((T >> 16) & 0xFFFF) * 3;
   int p2 = (T & 0xFFFF) * 3;
 
   g.drawLine(v[p1], v[p1 + 1], v[p2], v[p2 + 1]);
  }

  int taxes[] = new int[12];
  tmat.transform(axes,taxes,4);

  // Draw the coordinate axes
  g.setColor(new Color(255,255,0));
  g.drawLine(taxes[0], taxes[1],taxes[3],taxes[4]);
  g.drawString("Z", taxes[3]+5,taxes[4]);
  g.setColor(new Color(0,255,0));
  g.drawLine(taxes[0], taxes[1],taxes[6],taxes[7]);
  g.drawString("Y", taxes[6]+5,taxes[7]);
  g.setColor(new Color(255,0,0));
  g.drawLine(taxes[0], taxes[1],taxes[9],taxes[10]);
  g.drawString("X", taxes[9],taxes[10]+5);
 
 }
}