import java.awt.image.*;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Event;
import java.awt.Image;
import java.awt.Font;
import java.util.Vector;  //  http://java.sun.com/products/jdk/1.1/docs/api/java.util.Vector.html




//---- MAIN CLASS ------------------------------------------------------------//

public class Site3D extends tinyptc
{
  //---- DATA
  
  //- Output buffer

  int size;

  int[] buf;
  int[] tex;

  int mouse_x = 0, mouse_y = 0;
  boolean mouse_click = false;



  //---- rand
  
  //  Lewpen's random number algorithm - Creates random real numbers within a given range

  int rand_1 = 0x87361872, rand_2 = 0x12487, rand_3 = 0x8129743;

  public double rand(double min, double max)
  {
    rand_1 += rand_2^rand_3;  //  Lewpen's algo
    rand_2 ^= rand_3*rand_1;
    rand_3 *= rand_1+rand_2;
    
    rand_1 = (rand_1 << 2) | (rand_1 >> 30);  //  Rotate seeds by different ammounts
    rand_2 = (rand_2 << 7) | (rand_2 >> 25);
    rand_3 = (rand_3 << 9) | (rand_3 >> 23);

    rand_1 += 0x15214391;  //  Randomize the bits somewhat
    rand_2 += 0xF2248365;
    rand_3 += 0x42C427AA;

    //  Create random number 0..1234566;
    
    int r = ((rand_1+rand_2+rand_3)/3) % 1234567;

    //  Scale to the range [min..max)

    return min + (max-min)*(r+0.0) / 1234567.0;
  }



  //---- makeNoise
  
  public int[] makeNoise()
  {
    int[] tex = new int[256*256];
    
    int i, j;
    
    for(j=0; j<256; j++)
      for(i=0; i<256; i++)
        tex[j*256+i] = ((i^j)>>7)*51;

    return tex;
  }



  //---- main
  
  //  Main loop

  public void main(int width, int height)
  {
    size = width * height;
    buf = new int[size];

    int i, j, k;

    //- Make smoke texture
    
    tex = makeNoise();

    double px=0, py=0, pz=0;

    double x, y, z, scale, oscale;

    int ox, oy;
        
    //- Anim loop

    while(true)
    {
      //- Move
      
      if(mouse_click)
      {
        pz += 0.1;
        pz -= (int)pz;
      }
      
      //- Render
      
      for(i=0; i<size; i++) buf[i] = 0;

      for(k=0; k<=4; k++)
      {
        z = 2.0 + 0.2*(k-pz);

        scale = 1.0 / z;

        oscale = 1.0 / scale;

        ox = -mouse_x;//(int)(-0.125*width*oscale);
        oy = -mouse_y;//(int)(-0.125*height*oscale);

        for(j=0; j<height; j++)
        {
          for(i=0; i<width; i++)
          {
            int c = tex[(((int)(oscale*(double)(oy+j)))&255)*256+(((int)(oscale*(double)(ox+i)))&255)];
            
            buf[j*width+i] += c*0x01010101;
          }
        }
      
      }

      update(buf);
    }
  }


  //---- mouseMove

  public boolean mouseMove(Event e, int x, int y)
  {
    mouse_x = x;
    mouse_y = y;
    return true;
  }



  //---- mouseDrag

  public boolean mouseDrag(Event e, int x, int y)
  {
    mouse_x = x;
    mouse_y = y;
    return true;
  }



  //---- mouseDown

  public boolean mouseDown(Event e, int x, int y)
  {
    mouse_click = true;
    return true;
  }



  //---- mouseUp

  public boolean mouseUp(Event e, int x, int y)
  {
    mouse_click = false;
    return true;
  }


}



//---- end of code -----------------------------------------------------------//


