/**  @# ImageSetViewer.java 1.0 99/10/20
 * */
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.util.*;

public class ImageSetViewer extends Frame {
    static int MAX_IMAGES = 24;
    static int viewerWid = 400;
    static int viewerHt = 300;
    protected String[] fileList;
    protected int numImages=0;
    protected Image currentImage;
    protected int currentIndex =0;
    protected Image[] imageSet;
    protected Image offScrImage;
    protected Graphics offScrGc;

    public ImageSetViewer(){
       setTitle("Image Set Viewer");
       setSize(viewerWid, viewerHt);
       init();
    }

    public void init() {
       enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK |
                          AWTEvent.MOUSE_EVENT_MASK);
       addWindowListener(
          new WindowAdapter() {
            public void windowClosing(WindowEvent w) {
               dispose();
               System.exit(0);
            }
          }
       );
    }

    //Create off screen image only after peer is created
    public void addNotify(){
       super.addNotify();
       createOffScreenImage();
    }

    //Creates an off screen image
    public void createOffScreenImage(){
       Rectangle rect = getBounds();
       viewerWid = rect.width;
       viewerHt = rect.height;
       offScrImage = this.createImage(rect.width, rect.height);
       offScrGc = offScrImage.getGraphics();
       offScrGc.setColor(Color.black);
       offScrGc.fillRect(0,0,rect.width, rect.height);
    }

    //Loads images from given path. First reads the image file names. Then
    //calls readImages to load images.
    public void loadImages(String path, String filter){
       File imgDir= new File(path);
       fileList = readImageFiles(imgDir, filter);
       if(fileList == null) return;
       imageSet = readImages(path, fileList);
       if(imageSet != null) numImages = imageSet.length;
   }

    public String[] readImageFiles(File dir, String filter){
       ExtensionFilter efilter = new ExtensionFilter(filter);
       String files[] = dir.list(efilter);
       return files;
    }

    //Loads a single image
    public Image readImage(String path,String imageName){
       Image image = Toolkit.getDefaultToolkit().getImage(path+imageName);
       MediaTracker imageTracker = new MediaTracker(this);
       imageTracker.addImage(image, 0);
       try{
         imageTracker.waitForID(0);
       }catch(InterruptedException e){ return null;}
       return image;
    }

    //Loading multiple images at a time
    public Image[] readImages(String path, String[] imList) {
       Vector imv = new Vector();
       for(int i=0;(i<imList.length) && (i< MAX_IMAGES);i++){
           Image image = Toolkit.getDefaultToolkit().getImage(path+ imList[i]);
           MediaTracker imageTracker = new MediaTracker(this);
           imageTracker.addImage(image, i);
           try{
             imageTracker.waitForID(i);
           } catch(InterruptedException e){break;}
           if(image != null) imv.addElement(image);
       }
       int sz = imv.size();
       Image[] imarray= new Image[sz];
       imv.copyInto(imarray);
       return imarray;
    }

    //Displays images. It first draws the current image on an off screen image and then
    //calls repaint() which triggers the update() method.
    public void displayImage(){
       currentImage = imageSet[currentIndex++ %  numImages];
       if(offScrGc != null) {
          Rectangle rect = getBounds();
          if((viewerWid != rect.width) || (viewerHt != rect.height)) createOffScreenImage();
          offScrGc.setColor(Color.black);
          offScrGc.fillRect(0,0,rect.width, rect.height);
          offScrGc.drawImage(currentImage, 0,0,rect.width, rect.height, this);
       }
       repaint();
    }

    public void paint(Graphics gc){
       if(gc == null) return;
       Rectangle rect = getBounds();
       if(offScrImage != null)
          gc.drawImage(offScrImage, 0,0, rect.width, rect.height, this);
    }

    public void update(Graphics gc){
       if(gc == null) return;
       Rectangle rect = getBounds();
       if(offScrImage != null)
          gc.drawImage(offScrImage, 0,0, rect.width, rect.height, this);
    }

    public void quit(){ dispose();}

    public void  processMouseEvent(MouseEvent e){
       switch(e.getID()){
          case MouseEvent.MOUSE_PRESSED:
             setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
             displayImage();
             break;
          case MouseEvent.MOUSE_CLICKED:
             break;
          case MouseEvent.MOUSE_RELEASED:
             setCursor(Cursor.getDefaultCursor());
             break;
       }
    }


    class  ExtensionFilter implements FilenameFilter{
      private String extString;
      public ExtensionFilter(String ext){
         extString = ext;
      }
      public boolean accept(File dir, String name){
  	 StringTokenizer st = new StringTokenizer(extString, ",");
         while(st.hasMoreTokens()){
             if(name.endsWith(st.nextToken())){
                return true;
             }
         }
         return false;
      }
    }

    public static void main(String argv[]){
       ImageSetViewer viewer = new ImageSetViewer();
       viewer.show();
       String path = new String("images/");
       String filterString = ".gif,.jpeg,.jpg";
       viewer.loadImages(path, filterString);
       viewer.displayImage();
    }
}
