//
// spread.java
// example AFSR applet
// Neil Gershenfeld  (c) 10/26/96
//

import java.awt.*;
import java.awt.event.*;
import java.io.*;

class Plot extends Canvas implements KeyListener {
   int i,numpts;
   Image I;
   spread theApplet;
   Graphics G;
   double x[],y[],err[];
   public void init(int npts, spread myapp) {
      I = this.createImage(5*npts,5*npts);
      theApplet = myapp;
      addKeyListener(this);
      if(I == null)
	System.out.println("I is null: "+npts);
      G = I.getGraphics();
      x = new double[npts];
      y = new double[npts];
      err = new double[npts];
      numpts = npts;
      }

  public void keyPressed(KeyEvent ke){
    if(ke.getKeyChar() == 'a')
      theApplet.randomize();
    else if ((ke.getKeyChar()) == '\n')
      System.exit(0);
  }
  public void keyReleased(KeyEvent ke){}
  public void keyTyped(KeyEvent ke){}


   public void paint(Graphics g) {
      G.setColor(Color.white);
      G.fill3DRect(0,0,5*numpts,5*numpts,true);
      G.setColor(Color.black);
      for (i = 0; i < (numpts-1); ++i) {
         G.drawLine(5*i,((int) (50+100*x[i])),5*(i+1),((int) (50+100*x[i+1])));
         G.drawLine(5*i,((int) (200+100*y[i])),5*(i+1),((int) (200+100*y[i+1])));
         G.drawLine(5*i,((int) (400+50*err[i])),5*(i+1),((int) (400+50*err[i+1])));
         }
      g.drawImage(I,0,0,this);
      }
   public void update(Graphics g) {
      paint(g);
      }
   }

public class spread extends java.applet.Applet implements Runnable {
   Thread T;
   static final int NPTS = 100;
   static final int NREG = 12;
   Plot P = new Plot();
   double xreg[] = new double[1+NREG];
   double yreg[] = new double[1+NREG];
   int i,j,step;
   double pi,eps;
   
   public static void main(String args[]) {
      //
      // open a window and start the applet running
      // if run as an application
      //
      Frame f = new Frame("Spread");
      spread spreadapplet = new spread();
      f.add("Center",spreadapplet);
      f.setBounds(0, 0, 500,500);
      f.show();
      f.doLayout();
      spreadapplet.init();
      spreadapplet.start();
      }

   public void init() {
      P.setBounds(0,0,5*NPTS,5*NPTS);
      setLayout(new FlowLayout());
      add(P);
      P.doLayout();
      P.init(NPTS, this);
      for (i = 0; i <= 12; ++i)
         xreg[i] = 1;
      for (i = 0; i <= 12; ++i)
         yreg[i] = 1;
      pi = 4.0*Math.atan(1.0);
      eps = 0.45;
      }

   public void start() {
      if (T == null) {
         T = new Thread(this);
         T.start();
         }
      }
   public void stop() {
      if (T != null) {
         T.stop();
         T = null;
         }
      }
   
   public void run() {
      while (true) {
         shift(xreg);
         shift(yreg);
         xreg[0] = 0.5 * (1 -
            Math.cos(pi*(xreg[1]+xreg[4]+xreg[6]+xreg[12])));
         yreg[0] = eps * xreg[0] + (1 - eps) * 0.5 * (1 -
            Math.cos(pi*(yreg[1]+yreg[4]+yreg[6]+yreg[12])));
         shift(P.x);
         shift(P.y);
         shift(P.err);
         P.x[0] = xreg[0];
         P.y[0] = yreg[0];
         P.err[0] = 2*(xreg[0]-yreg[0]);
         P.repaint();
         try {Thread.sleep(50);}
         catch (InterruptedException e) { }
         }
      }

   void shift(double[] a) {
      for (i = (a.length-1); i > 0; --i) {
         a[i] = a[i-1];
         }
      }

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

  public void randomize() {
    for (int i = 0; i <= 12; ++i)
      yreg[i] = Math.random();
  }
  

}
 


