import java.awt.*;
import java.awt.image.*;
import java.io.DataInputStream;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.net.MalformedURLException;
import java.util.StringTokenizer;

public class displayrand extends java.applet.Applet implements Runnable {

  URL theURL;
  Thread runner;
  TextArea ta = new TextArea("Getting text...",30,20);
      int maxcol = 160;
    int ncolr = 30;
    byte redm[] = new byte[maxcol];
    byte greenm[] = new byte[maxcol];
    byte bluem[] = new byte[maxcol];
    byte b255 = (byte)255;
    Image img;
    IndexColorModel icm;
    int hh=50;
    int height=100;
    int width=50;
      byte data[] ;
 int nsel[]=new int[2];
 int isel[][]=new int [2][50];
 double c[][]=new double [2][50];
 double x0,y0;
  boolean debug = false;


  public byte interp(int a,int b,double f) {
                return (byte)(a*(1-f)+b*f);
       }
  
public synchronized void drawimage() {
   int Xscreen =hh ,Yscreen=width;
 int Nxpixel=hh,Nypixel=width;
 double Left= -4.,Right= 4.,Bottom= -4.,Top= 4.;
 int numcol = maxcol;
 int maxiter = 160;
 double x,y,x0,y0,xd,yd,Deltax,Deltay;
 int i,j,ib,iter,ic,l,j1;
 double stack[]=new double[50];
 int iexe[][]=new int[2][50];
 double p[]=new double[2];
 double p0[] = new double[2];
 int istack,k,numpull;
 if (debug) System.out.println("Computing iexe");
 /* This is to speed up formula computation */
 for(i=0; i < 2; i++)
    for(j=0; j < nsel[i]; j++) iexe[i][j] = 1;
                   for (j=0; j < 2; j++) {
                        for (i=0; i < nsel[j]; i++) {
                  if(isel[j][i] > 15 && isel[j][i] < 19) {
                 numpull = 0;
                 if((i+1) < nsel[j]) {
                        for(k = i+1; k < nsel[j]; k++) {
                   if(isel[j][k] > 15 && isel[j][k] < 19)
                    numpull = numpull - 1;
                   if(isel[j][k] > 18 && isel[j][k] < 23)
               numpull = numpull + 1;
                   if(numpull == 1) break;
                   }
                 }
                 if(numpull != 1) iexe[j][i] = 0;
                 }
                  }
                 }
/* Main loop on image pixels */
      Deltax = (Right - Left) / Xscreen;
      Deltay = (Top - Bottom) / Yscreen;
      for (j=0; j < Yscreen; j++) {
    try { Thread.sleep(1000);}
    catch (InterruptedException e) { }
         for (l=0;l < Xscreen; l++) {
            x0 = (l-1)*Deltax + Left;
            y0 = (j-1)*Deltay + Bottom;
            x = x0 ;
            y = y0;
            iter = 1;
           while(iter <= maxiter){

/* Iteration start here */
            p0[0] = x0;
            p0[1] = y0;
            for(i=0; i< 2; i++) {
            istack = 0;
            p[i] = p0[i];
            for (k=0; k < nsel[i]; k++) {
                switch (isel[i][k]) {
                        case  1: p[i] = p[i] + x0;break;
                    case  2: p[i] = p[i] + y0;break;
                    case  3: p[i] = p[i] + c[i][k];break;
                    case  4: p[i] = p[i] - x0;break;
                    case  5: p[i] = p[i] - y0;break;
                    case  6: p[i] = p[i] - c[i][k];break;
                    case  7: p[i] = p[i] * x0;break;
                    case  8: p[i] = p[i] * y0;break;
                    case  9: p[i] = p[i] * c[i][k];break;
                    case 10: if(x0 == 0.) p[i] = 0.;
                               else  p[i] = p[i] / x0;break;
                    case 11: if(y0 == 0.) p[i] = 0.;
                       else  p[i] = p[i] / y0;break;
                    case 12: if(c[i][k] == 0.) p[i] = 0.;
                       else  p[i] = p[i] / c[i][k];break;
                    case 13: if(k == 0)p[i] = x0;break;
                    case 14: if(k == 0)p[i] = y0;break;
                    case 15: if(k == 0)p[i] = c[i][k];break;
                    case 16: if(iexe[i][k] == 1){
                         istack = istack + 1; stack[istack] = p[i];
                         p[i] = x0; }break;
                    case 17: if(iexe[i][k] == 1){
                         istack = istack + 1; stack[istack] = p[i];
                         p[i] = y0; }break;
                    case 18: if(iexe[i][k] == 1){
                         istack = istack + 1; stack[istack] = p[i];
                         p[i] = c[i][k]; }break;
                    case 19: if(istack > 0) {p[i] = p[i] + stack[istack];
                             istack = istack - 1;}break;
                    case 20: if(istack > 0) {p[i] = p[i] - stack[istack];
                             istack = istack - 1;}break;
                    case 21: if(istack > 0) {p[i] = p[i] * stack[istack];
                             istack = istack - 1;}break;
                    case 22: if(istack > 0) {
                       if(stack[istack] == 0.)  p[i] = 0.;
                       else {
                        p[i] = p[i] / stack[istack];
                             istack = istack - 1;}}break;
                }
                }
                }
            x = p[0];
            y = p[1];
/* end of iteration */
            if(Math.abs(x) > 10000f || Math.abs(y) > 10000f)break;
            iter = iter + 1;
            x0 = x;
            y0 = y;
            }
            ic = (iter % numcol) + 1;
            if(debug) System.out.println("pixel "+l+" "+j+" has color "+ic);
            data[l+j*width] = (byte)ic;
           }
           img.flush();
           img = null;
           img = createImage( new MemoryImageSource(width,hh,icm,data,0,width));
                        repaint();
          }
}

  public void init() {
     int i; 
       data = new byte[hh*width];
      UserParameters();
     if (debug) System.out.println ("initing...");

   redm[0] = 0; greenm[0] = 0; bluem[0] = 0;
   redm[1] = b255; greenm[1] = b255; bluem[1] = b255;
   redm[2] = b255; greenm[2] = 0; bluem[2] = 0;
   redm[3] = 0; greenm[3] = b255; bluem[3] = 0;
   redm[4] = 0; greenm[4] = 0; bluem[4] = b255;
   redm[5] = b255; greenm[5] = b255; bluem[5] = 0;
   redm[6] = b255; greenm[6] = 0; bluem[6] = b255;
   redm[7] = 0; greenm[7] = b255; bluem[7] = b255;
   redm[8] = 0; greenm[8] = (byte)254; bluem[8] = (byte)254;
   redm[9] = 0; greenm[9] = (byte)253; bluem[9] = (byte)253;
            for (i=0;i<ncolr;i++) {
                    redm[i+10] = interp(255,255,i/(double)(ncolr-1.));
                    greenm[i+10] = interp(0,255,i/(double)(ncolr-1.));
                    bluem[i+10] = interp(0,0,i/(double)(ncolr-1.));
            }
            for (i=0;i<ncolr;i++) {
                    redm[i+ncolr+10] = interp(255,0,i/(double)(ncolr-1.));
                    greenm[i+ncolr+10] = interp(255,255,i/(double)(ncolr-1.));
                    bluem[i+ncolr+10] = interp(0,0,i/(double)(ncolr-1.));
            }
            for (i=0;i<ncolr;i++) {
                    redm[i+2*ncolr+10] = interp(0,0,i/(double)(ncolr-1.));
                    greenm[i+2*ncolr+10] = interp(255,255,i/(double)(ncolr-1.));
                    bluem[i+2*ncolr+10] = interp(0,255,i/(double)(ncolr-1.));
            }
            for (i=0;i<ncolr;i++) {
                    redm[i+3*ncolr+10] = interp(0,0,i/(double)(ncolr-1.));
                    greenm[i+3*ncolr+10] = interp(255,0,i/(double)(ncolr-1.));
                    bluem[i+3*ncolr+10] = interp(255,255,i/(double)(ncolr-1.));
            }
            for (i=0;i<ncolr;i++) {
                    redm[i+4*ncolr+10] = interp(0,255,i/(double)(ncolr-1.));
                    greenm[i+4*ncolr+10] = interp(0,0,i/(double)(ncolr-1.));
                    bluem[i+4*ncolr+10] = interp(255,255,i/(double)(ncolr-1.));
            }



              icm = new IndexColorModel(8,maxcol,redm,greenm,bluem);
              img = createImage(new  MemoryImageSource(width,hh,icm,data,0,width));

    String url = "http://www.ba.infn.it/zitobin/nph-rformula";
    try { this.theURL = new URL(url); }
    catch ( MalformedURLException e) {
      System.out.println("Bad URL: " + theURL);
    }
     setLayout(new BorderLayout());

    add("East",ta);
   if (debug) System.out.println ("Exiting init...");
  }
private void UserParameters () {
            String parameter;

            // Get user parameters
            parameter = getParameter ("debug");
            if (parameter != null) debug = parameter.equals("true");
    }
  public Insets insets() {
    return new Insets(10,10,10,10);
  }
  public void start() {
    if (runner == null) {
      runner = new Thread(this);
      runner.start();
    }
  }
  
  public void stop() {
    if (runner != null) {
      runner.stop();
      runner = null;
    }
  }
 public 
void paint(Graphics g) {
                            g.drawImage(img,0,10,this);
  }
public  
 void update(Graphics g) {
  paint (g);
 }

  public void run() {
   readformula();
   drawimage();
}

private synchronized void readformula() {
    URLConnection conn;
    DataInputStream data;
    String line;
    StringBuffer buf = new StringBuffer();
    int numlin,j;

    try { 
      conn = this.theURL.openConnection();
      conn.connect();


      data = new DataInputStream(new BufferedInputStream(
                     conn.getInputStream()));

      numlin=0;
      line = data.readLine();
      line = data.readLine();
      while ((line = data.readLine()) != null) {
        buf.append(line + "\n");
        numlin = numlin + 1;
        if (debug) System.out.println(numlin+" "+line);
        StringTokenizer st = new StringTokenizer(line);
                          if(numlin == 1) {
                            st.nextToken();
                            nsel[0] = Integer.valueOf(st.nextToken()).intValue();
                            if(debug)System.out.println("nsel[0] ="+nsel[0]);
                          nsel[1] = Integer.valueOf(st.nextToken()).intValue();
                            if(debug)System.out.println("nsel[1] ="+nsel[1]); 
                          }   
                          if(numlin > 1 && numlin < 7){
                           j = (numlin-2)*10;
                           for(int i =0;i<10;i++){isel[0][j]=Integer.valueOf(st.nextToken()).intValue();
                             if(debug)System.out.println("isel ="+isel[0][j]);j++;}
                                   }
                           if(numlin > 6 && numlin < 12){
                           j = (numlin-7)*10;
                           for(int i =0;i<10;i++){isel[1][j]=Integer.valueOf(st.nextToken()).intValue();
                             if(debug)System.out.println("isel ="+isel[1][j]);j++;}
                                   }
                          if(numlin > 11 && numlin < 17){
                           j = (numlin-12)*10;
                           for(int i =0;i<10;i++){c[0][j]=Double.valueOf(st.nextToken()).doubleValue();
                             if(debug)System.out.println("c ="+c[0][j]);j++;}
                                   }
                           if(numlin > 16 && numlin < 22){
                           j = (numlin-17)*10;
                           for(int i =0;i<10;i++){c[1][j]=Double.valueOf(st.nextToken()).doubleValue();
                             if(debug)System.out.println("c ="+c[1][j]);j++;}
                                   }
                           if(numlin == 22){
                              x0 = Double.valueOf(st.nextToken()).doubleValue();
                              y0 = Double.valueOf(st.nextToken()).doubleValue();
                             if(debug)System.out.println("x0,y0= "+x0+y0);
                          }
                 }
      ta.setText(buf.toString());
    }
    catch (IOException e) {
      System.out.println("IO Error:" + e.getMessage());
    }
  }
}

