import java.awt.*;
import java.applet.*;



public class Mandel2 extends tinyptc
{
  //- Data

  int size;
  int[] buf;
  int[] buf2;
  int[] buf3;

  int[][] newx, newy;

  int mouse_x = 128, mouse_y = 128;
  int mouse_oldx = 128, mouse_oldy = 128;
  boolean mouse_drag = true;



  //- render
  
  public void render(int frame)
  {
    int i, j;
    
    int frame2 = frame;
    
    double dd = 40 + 20 * Math.sin(frame2*3.14159/30.283);
    int d = (int)(dd*dd);

    d = 30;

    int cx = 128;//(int)(128 + 30 * Math.sin(frame2*3.14159/25.7262));
    int cy = 128;//(int)(128 + 30 * Math.sin(frame2*3.14159/35.1827));

    for(frame=0; frame<4; frame++)
    {
      if(frame == 0)
      {
        for(i=0; i<size; i++) buf2[i] = 0;
        for(i=0; i<size; i++) buf3[i] = 0;
    
        for(j=cy-d; j<cy+d; j++) for(i=cx-d; i<cx+d; i++)
        {
          buf3[j*256+i] = (((i-cx+d)^(j-cy+d)))*0x01010101;
        }
      }

      {
        for(j=0; j<256; j++) for(i=0; i<256; i++)
        {
          int x = newx[j][i] + i - mouse_x;
          int y = newy[j][i] + j - mouse_y;
          
          if(x >= 0 && x < 256 && y >= 0 && y < 256)
          {
            buf2[j*256+i] = buf3[y*256+x];
          }
        }
  
        if(frame > 0)
        {
          for(i=0; i<size; i++)
          {
            buf[i] += buf2[i];
            buf3[i] = buf2[i];
          }
        }
        else
        {
          for(i=0; i<size; i++)
          {
            buf[i] = buf2[i];
            buf3[i] = buf2[i];
          }
        }
      }
    }
  }

  //- Main code

  public void main(int width, int height)
  {
    size = width * height;
    buf = new int[size];
    buf2 = new int[size];
    buf3 = new int[size];

    int i, j;
    
    //  Create lookup tables

    newx = new int[256][256];
    newy = new int[256][256];
    
    for(j=0; j<256; j++) for(i=0; i<256; i++)
    {
      double x = (i-128)/64.0;
      double y = (j-128)/64.0;
      double nx = x*x-y*y;
      double ny = 2*x*y;

      newx[j][i] = (int)(nx*64 + 128);
      newy[j][i] = (int)(ny*64 + 128);
    }

    //  Animate

    int frame = 0;

    while(true)
    {
      render(frame++);
      update(buf);
    }
  }




  //- Mouse code



  public boolean mouseDown(Event evt, int x, int y)
  {
    mouse_oldx = x;
    mouse_oldy = y;
    mouse_x = x;
    mouse_y = y;
    mouse_drag = true;

    return true;
  }


  
  public boolean mouseMove(Event e, int x, int y)
  {
    mouse_x = x;
    mouse_y = y;

    return true;
  }


  public boolean mouseDrag(Event e, int x, int y)
  {
    mouse_x = x;
    mouse_y = y;

    return true;
  }



  public boolean mouseUp(Event evt, int x, int y)
  {
    mouse_drag = false;

    return true;
  }
  

}

