/*
 * Author: Paul Koshevoy
 * TV.java  Sat 17 Jan 1998, 13:15:00 1998
 */

import java.awt.*;
import java.awt.image.*;


//----------------------------------------------------------------
// TVtest
// 
public class TVtest extends Canvas implements Runnable
{
  // delay between the redraws of the canvas in milliseconds:
  private int delay = 0;
  
  // canvas dimensions:
  private int width;
  private int height;
  
  // double buffering buffers:
  private Image offImage;
  private Graphics offGraphics;
  private Thread animatorThread;
  
  // this tracker will look out for the progress on the image load:
  private MediaTracker tracker;
  
  private int picture[];
  
  private volatile double x;
  private volatile double y;
  private int sx;
  private int sy;
  
  private Parameters params;
  private volatile double TwoPI;
  
  public volatile double alpha1;
  public volatile double alpha2;
  public volatile double da1;
  public volatile double da2;
  
  private int use_prev;
  private int prev_x;
  private int prev_y;
  
  //----------------------------------------------------------------
  // TVtest
  // 
  public TVtest(int W, int H, Image img, Parameters prms) // constructor
  {
    use_prev = 0;
    
    tracker = new MediaTracker(this);
    tracker.addImage(img, 0);
    try
    {
      tracker.waitForID(0);
    }
    catch(InterruptedException e)
    {
      System.out.println("exception during image load");
    }
    
    x = 0;
    y = 0;
    sx = img.getWidth(this);
    sy = img.getHeight(this);
    
    System.out.println(sx);
    System.out.println(sy);
    
    int size = (int)(sx * sy);
    picture = new int[size];
    PixelGrabber PG = new PixelGrabber(img,
				       0,
				       0,
				       (int)sx,
				       (int)sy,
				       picture,
				       0,
				       (int)sx);
    try
    {
      PG.grabPixels();
    }
    catch(InterruptedException e)
    {
      System.out.println("pixel grab failed");
    }
    
    params = prms;
    
    width  = W;
    height = H;
    setSize(width, height);
    
    // delta-alpha angles (step size for angle increments):
    // da1 = params.dP/(sx * 3);
    // da2 = params.dG/(sy * 4);
    da1 = params.dP/150;
    da2 = params.dG/100;
    alpha1 = 0;
    alpha2 = params.G1;
    TwoPI = 2 * params.PI;
    start();
  }

  //----------------------------------------------------------------
  // start
  // 
  public void start()
  {
    if (animatorThread == null)
    {
      // create a new thread for double buffering:
      animatorThread = new Thread(this);
    }
    
    // start the new thread:
    animatorThread.start();
  }

  //----------------------------------------------------------------
  // stop
  // 
  public void stop()
  {
    // stop the double buffer thread:
    if (animatorThread != null) animatorThread.interrupt();
    
    // destroy the double buffer thread:
    animatorThread = null;
  }
  
  //----------------------------------------------------------------
  // run
  // 
  public void run()
  {
    // maximize the priority of the thread:
    Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
    
    // start time
    long startTime = System.currentTimeMillis();
    
    // double buffer thread:
    while (Thread.currentThread() == animatorThread)
    {
      /*
      try
      {
	startTime += delay;
	Thread.sleep(Math.max(0, startTime - System.currentTimeMillis()));
      }
      catch(InterruptedException e)
      {
	break;
      }
      */
      repaint();
    }
  }
  
  //----------------------------------------------------------------
  // update
  // 
  public void update(Graphics g)
  {
    paint(g);
  }
  
  //----------------------------------------------------------------
  // paint
  // 
  public synchronized void paint(Graphics g)
  {
    if (offGraphics == null)
    {
      offImage = createImage(width, height);
      offGraphics = offImage.getGraphics();
      offGraphics.setColor(Color.black);
      offGraphics.fillRect(0, 0, width, height);
    }
    
    if (alpha1 >= TwoPI)
    {
      alpha1 = 0;
      alpha2 += da2;
      if (alpha2 >= TwoPI)
      {
	alpha2 = 0;
	System.out.println("done with a frame");
      }
    }
    
    alpha1 += da1;
    
    if ((alpha2 >= params.G1) && (alpha2 <= params.G2))
    {
      if((alpha1 >= params.P2) && (alpha1 <= params.P1))
      {
	x = params.get_x(alpha1, alpha2, sx);
	if ((x >= 0) && (x <= params.WD))
	{
	  y = params.get_y(alpha2, sy);
	  int i_x = (int)((x / params.WD) * sx);
	  int i_y = (int)((y / params.HT) * sy);
	  
	  int index = i_x + i_y * sx;
	  double D = params.C / (Math.cos(params.PIo2 - alpha2));
	  int color = picture[index];
	  Color COLOR = new Color(color);
	  offGraphics.setColor(COLOR);
	  
	  if (use_prev == 1)
	  {
	    offGraphics.drawLine(prev_x, prev_y,
				 (int)(x), (int)(y));
	  }
	  else
	  {
	    offGraphics.drawLine((int)(x), (int)(y),
				 (int)(x), (int)(y));
	  }
	  
	  use_prev = 1;
	  prev_x = (int)(x);
	  prev_y = (int)(y);
	}
	else
	{
	  use_prev = 0;
	}
      }
      else
      {
	use_prev = 0;
      }
    }
    else
    {
      use_prev = 0;
    }
    
    g.drawImage(offImage, 0, 0, this);
  }
}

