/* video01.java   last mod 15 JUN 2001 by Ed James */

import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import java.util.Date;
import java.awt.image.MemoryImageSource;

public class video01 extends java.applet.Applet
      implements ActionListener, Runnable {
   Thread runner;

   GridLayout gl  = new GridLayout(2,1,5,5);

   Button redButton    = new Button ("Red");
   Button greenButton  = new Button ("Green");
   Button yellowButton = new Button ("Yellow");

   int imageWidth  = 256;
   int imageHeight = 256;
   int[] pixels     = new int[imageWidth*imageHeight];
   videoCanvas can  = new videoCanvas(imageWidth, imageHeight, pixels);

   int plotWidth          = 256;
   int plotHeight         = 100;
   int[] plotPixels       = new int[plotWidth*plotHeight];
   int[] byteCount        = new int[plotWidth];
   videoCanvas plotCanvas = new videoCanvas(plotWidth, plotHeight, plotPixels);

   int red, green, blue;

   long startTime;
   long endTime;
   long timeSpan;

   Random myRandom = new Random ();

   public void init() {
      setLayout (gl);

   // redButton.addActionListener (this);
   // add ("East", redButton);
   // add(redButton);

   // greenButton.addActionListener (this);
   // add ("North", greenButton);
   // add(greenButton);

   // yellowButton.addActionListener (this);
   // add ("West", yellowButton);
   // add(yellowButton);

      add(can);
      can.init();
      createRandomImage();

      add(plotCanvas);
      plotCanvas.init();
      }

   public void start () {
      if (runner == null) {
         runner = new Thread (this);
         runner.start ();
         }
      }

   public void stop () { runner = null; }

   public void run () {
      Thread thisThread = Thread.currentThread ();

      while (runner == thisThread) {
//         startTime = System.currentTimeMillis();

         shiftImageRight();
         can.updateImage();

//       updatePlot();
//       plotCanvas.updateImage();

//         endTime = System.currentTimeMillis();
//         timeSpan = endTime - startTime;
//         System.out.println ("timeSpan = " + timeSpan + " ms.");

         try { Thread.sleep(500); }  // 100 is safe
         catch (InterruptedException e) { }
         }
      }

   void updatePlot() {
      updatePlotData();
      sortPlotData();
      drawPlot();
      }

   void createRandomImage() {
      for (int x = 0 ; x < imageWidth ; x++) {
         red   = (int) (myRandom.nextDouble() * 256);
         green = (int) (myRandom.nextDouble() * 256);
         blue  = (int) (myRandom.nextDouble() * 256);
         for (int y = 0 ; y < imageHeight ; y++) {
            pixels[y*imageWidth+x] = (0xff000000) | red << 16 | green << 8 | blue;
            }
         }
      }

   public void shiftImageRight() {
      int iTemp[] = new int[imageHeight];

   // "save" the first column:
      for (int y = 0 ; y < imageHeight ; y++)
         iTemp[y] = pixels[y*imageWidth];

   // shift each column left:
      for (int x = 0 ; x < imageWidth-1 ; x++)
         for (int y = 0 ; y < imageHeight ; y++)
            pixels[y*imageWidth + x] = pixels[y*imageWidth + x + 1];

   // move the "saved" first column to the last column:
      for (int y = 0 ; y < imageHeight ; y++)
         pixels [y*imageWidth + imageWidth - 1] = iTemp[y];
      }


   void updatePlotData() {
      byte tempByte;

      for (int i = 0 ; i < 256 ; i++)
         byteCount[i] = 0;

   // bogus graphing for now:
      int numOfPixels = plotWidth * plotHeight; 
      for (int i = 0 ; i < numOfPixels ; i++) {
         tempByte = (byte)  plotPixels[i]       ;  byteCount[((int) tempByte)+128] += 1;
         tempByte = (byte) (plotPixels[i] >>  8);  byteCount[((int) tempByte)+128] += 1;
         tempByte = (byte) (plotPixels[i] >> 16);  byteCount[((int) tempByte)+128] += 1;
         }
      }

   void sortPlotData () {
      int iTemp;

      boolean notDone = true;
      while (notDone) {
         notDone = false;
         for (int i = 0 ; i < plotWidth-1 ; i++)
            if (byteCount[i] < byteCount[i+1]) {
               iTemp = byteCount[i];
               byteCount[i] = byteCount[i+1];
               byteCount[i+1] = iTemp;
              }
         }
      }

   void drawPlot () {
      for (int y = 0 ; y < plotHeight ; y++)
         for (int x = 0 ; x < plotWidth ; x++) {
            plotPixels[y*plotWidth+x] = (0xff000000) | (int) 256;
            }
      }
      
   public void actionPerformed (ActionEvent e) {
      Object source = e.getSource();

      if      (source == redButton   ) doRed();
      else if (source == greenButton ) doGreen();
      else if (source == yellowButton) doYellow();
      }

   public void doRed    () { can.setBackground (Color.red)    ; repaint (); }
   public void doGreen  () { can.setBackground (Color.green)  ; repaint (); }
   public void doYellow () { can.setBackground (Color.yellow) ; repaint (); }
   }