import java.applet.*;
import java.awt.*;
import java.awt.image.*;
import java.util.*;

public class FadeImage2 extends Applet implements Runnable 
{
 Image[] image;
 Image upd_image;
 MediaTracker tracker;
 int[] image_pixels, work_pixels; 
 int image_w, image_h, pixel;
 PixelGrabber grabber;
 Color bgcolor;
 MemoryImageSource mis;
 Thread th;
 Graphics g, gr;
 int index = 0, speed, sleep;
 

 int FRAMES = 7;
 int TOTAL_FRAMES = 8;
 int MULTIPLIER = 0x5D1E2F;
 int random[][] = null;
 int pixels_per_frame = 0;
 int frame;
 
 int random_count[];
 boolean b = false;

 public void init()
 {
  sleep = Integer.parseInt(getParameter("sleep"));
  speed = Integer.parseInt(getParameter("speed"));

  StringTokenizer st = new StringTokenizer(getParameter("bgcolor"), ",");
  bgcolor = new Color(Integer.parseInt(st.nextToken()), 
                      Integer.parseInt(st.nextToken()), 
                      Integer.parseInt(st.nextToken()));

 
  setBackground(bgcolor);

  tracker = new MediaTracker(this);

  for (int i = 1; (getParameter("image"+i)) != null; i++)
  {
   image = new Image[i];
  }


  for(int i = 0; i < image.length; i++) 
  {
   image[i] = getImage(getDocumentBase(), getParameter("image"+(i+1)));
   tracker.addImage(image[i], i);
   
   try { tracker.waitForID(i); } catch (InterruptedException e) {} 
  }

  image_w = getSize().width+1;
  image_h = getSize().height;
  
  pixel = image_w*image_h;
    
  image_pixels = new int[pixel];
  work_pixels  = new int[pixel];

 
  pixels_per_frame = pixel / TOTAL_FRAMES;

  random = new int[TOTAL_FRAMES][pixels_per_frame];

  random_count = new int[TOTAL_FRAMES];



 upd_image = createImage(getSize().width, getSize().height);
 gr = upd_image.getGraphics();
 g = getGraphics();

 }



  public void start()
  {
   if (th == null) { th = new Thread(this); th.start(); }
  }

  public void stop()
  {
   if (th != null) { th.stop(); th = null; } 
  }



  public void run() 
  {
   Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
 
   while(true) 
        {


   for(int s = 0; s < TOTAL_FRAMES; s++) 
   {
      random_count[s] = 0;
   }
            int seed = (int) System.currentTimeMillis();
            int denominator = 10;

   while((pixels_per_frame % denominator > 0 ||
           image_h % denominator == 0) && denominator > 1) {
      --denominator;
    }

    int new_randoms_per_frame = pixels_per_frame / denominator;
    int new_randoms = pixel / denominator;


    seed += 0x5050;

    for(int p = 0; p < new_randoms; p++) {
          
      seed *= MULTIPLIER;
      frame = (seed >>> 29);

      random[frame][random_count[frame]++] = p;

      while(random_count[frame] >= new_randoms_per_frame) {
      if(++frame >= TOTAL_FRAMES) {
        frame = 0;
                                  }
                                                           }
      
    }



    
       
    for(int s = 0; s < FRAMES; s++) {

      for(int ps = 0; ps < pixels_per_frame;ps += new_randoms_per_frame) {


        for(int p = 0; p < new_randoms_per_frame; p++) {
         
          random[s][ps + p] = random[s][p] + ps * TOTAL_FRAMES;
        }

      


      }
     
    }


            for(int i = 0; i < TOTAL_FRAMES+1; i++)

            {
             
             
             if(!b)
             {
             image[index] = getImage(getDocumentBase(), getParameter("image"+(index+1)));

             grabber = new PixelGrabber(image[index],0,0,image_w,image_h, image_pixels,0,image_w);

             try{ grabber.grabPixels(); } catch(InterruptedException e){}
             }
             b = true;
            
if(i >= TOTAL_FRAMES-1)
{ 
              System.arraycopy((Object) image_pixels, 0, (Object)work_pixels, 0, pixel);
 

}


else {  
            for(int p = 0; p < pixels_per_frame; p++) 
            {
            work_pixels[random[i][p]] = image_pixels[random[i][p]];


            }
   }

      image[index] = createImage(new MemoryImageSource(image_w, image_h,
                  work_pixels, 0, image_w));

      prepareImage(image[index], this);

      gr.drawImage(image[index], 0, 0, this);

     try { Thread.sleep(speed); } catch (InterruptedException e) {}

     }

    
     index++; 
     b = false; 

     if (index >= image.length) index = 0;
           
     try { Thread.sleep(sleep); } catch (InterruptedException e) {}     
    

  
  }
   
}

    
  

  public void update(Graphics g) 
{
  
 g.drawImage(upd_image, 0, 0, getSize().width, getSize().height, this); 
 
}
  

}


