import java.applet.*;
import java.net.*;
import java.util.*;
import java.io.*;
import java.awt.*;

/**
 * ImageSampler is a small applet that displays a library
 * of (typically tiling) images.  It can also display text
 * over the images, to allow the user to explore contrast
 * and appearance issues.
 *
 * This applet accepts the following parameters:
 *
 *  Name        Value
 * ------      -------
 *  url		base URL for the images
 * image{n}	name or pathname of image no. n (0<n, consecutive)
 * desc{n}	description of image no. n
 *
 */

public class ImageSampler extends Applet
{
    Vector imageNames = null;
    Vector imageDescriptions;
    Hashtable images;

    Image	currentImage;
    String	currentImageName;
    String	currentImageDesc;
    URL		currentImageURL = null;

    ImagerCanvas canvas = null;
    Panel	controlPane;
    Label	messageBar;
    List	imageList;
    Button	optionsButton;
    Checkbox	tileCheckbox;
    Button	loadButton;
    Label	imageCountLabel;
    Button	nextButton, prevButton;
    Color	bgColor;

    URL		codeURL;
    URL		imageBaseURL;
    
    OptFrame	optionsFrame;
    
    /**
     * Initialize the applet.
     */
    public void init() 
    {
	currentImage = null;
	String colorstr = getParameter("background");
	if (colorstr == null) colorstr = getParameter("bgcolor");

	Color neutralColor = new Color(0xCCCCCC);
	if (colorstr != null) try {
	    bgColor = new Color(Integer.parseInt(colorstr,16));
	}
	catch (Exception e) { bgColor = neutralColor; }

	// create GUI
	if (canvas == null) {
	    setBackground(bgColor);
	    setLayout(new BorderLayout());
	    canvas = new ImagerCanvas(this, Color.white);
	    add("Center", canvas);
	    controlPane = new Panel();
	    add("North", controlPane);
	    controlPane.setLayout(new BorderLayout());
	    controlPane.setBackground(bgColor);
	    messageBar = new Label("Please select an image from the list.");
	    Panel lpane = new Panel();
	    lpane.setLayout(new BorderLayout());
	    imageList = new List(8,false);
	    imageList.setBackground(neutralColor);
	    lpane.add("Center", imageList);
	    Panel rpane = new Panel();
	    GridBagLayout bag = new GridBagLayout();
	    rpane.setLayout(bag);
	    GridBagConstraints gbc = new GridBagConstraints();
	    gbc.fill = GridBagConstraints.HORIZONTAL;
	    gbc.insets = new Insets(3,4,3,4);
	    tileCheckbox = new Checkbox("tile image", null, true);
	    canvas.setTile(true);
	    gbc.gridy = 0;
	    bag.setConstraints(tileCheckbox, gbc);
	    rpane.add(tileCheckbox);
	    optionsButton = new Button("Set Text");
	    gbc.gridy = 1;
	    bag.setConstraints(optionsButton, gbc);
	    rpane.add(optionsButton);
	    loadButton = new Button("Download image");
	    gbc.gridy = 2;
	    bag.setConstraints(loadButton, gbc);
	    rpane.add(loadButton);
	    nextButton = new Button(" >> ");
	    prevButton = new Button(" << ");
	    Panel nppane = new Panel();
	    nppane.add(prevButton); nppane.add(nextButton);
	    gbc.gridy = 3;
	    bag.setConstraints(nppane, gbc);
	    rpane.add(nppane);
	    lpane.add("East", rpane);
	    controlPane.add("Center", lpane);
	    controlPane.add("South", messageBar);
	    optionsFrame = new OptFrame(this, bgColor);
	}
	canvas.setImage(currentImage, false);

	// read parameters
	if (imageNames == null) {
	    imageNames = new Vector();
	    imageDescriptions = new Vector();
	    images = new Hashtable();

	    codeURL = getCodeBase();
	    imageBaseURL = getDocumentBase();
	    String ibu = getParameter("url");
	    if (ibu != null) try {
		imageBaseURL = new URL(imageBaseURL, ibu);
	    } catch (MalformedURLException mue) {
		System.err.println("Bad url parameter: " + ibu);
	    }

	    int imageno;
	    String pval, dval;
	    for(imageno = 1; true; imageno++) {
		pval = getParameter("image" + imageno);
		if (pval == null) break;
		imageNames.addElement(pval);
		dval = getParameter("desc" + imageno);
		if (dval == null) dval = getParameter("description" + imageno);
		if (dval == null)
		    imageDescriptions.addElement("");
		else imageDescriptions.addElement(dval);
	    }

	    Enumeration ei, ed;
	    int ex;
	    for(ex = 1, ei = imageNames.elements(), ed = imageDescriptions.elements();
		ei.hasMoreElements(); ex++)
		{
		    imageList.addItem(ex + ". " + ei.nextElement().toString() +
				      " - " +
				      ed.nextElement().toString());
		}
	}
	// we now have the main gui and the list set up

	// debug
	/* Toolkit tk = Toolkit.getDefaultToolkit();
	   String [] fontnames = tk.getFontList();
	   for(int ix = 0; ix < fontnames.length; ix++) {
	   System.out.println("Font " + ix + " is " + fontnames[ix]);
	   }
	*/
    }

    public void message(Object o) {
	String str = o.toString();
	messageBar.setText(str);
    }

    public void start()
    {
	currentImage = null;
	currentImageURL = null;
	canvas.setImage(currentImage, false);
	int sx = imageList.getSelectedIndex();
	if (sx >= 0) imageList.deselect(sx);
	message("Please select an image from the list.");
    }

    public void stop()
    {
	optionsFrame.hide();
    }

    public boolean handleEvent(Event evt) 
    {
	if (evt.id == Event.LIST_SELECT &&
	    evt.target == imageList) 
	    {
		int selx = imageList.getSelectedIndex();
		if (selx >= 0) {
		    return action(evt, new Integer(selx));
		}
	    }
	return super.handleEvent(evt);
    }

    public boolean action(Event evt, Object obj) {
	boolean ret = false;

	if (evt.target == optionsButton) {
	    optionsFrame.show();
	    ret = true;
	}
	else if (evt.target == tileCheckbox) {
	    boolean tile = tileCheckbox.getState();
	    canvas.setTile(tile);
	    ret = true;
	}
	else if (evt.target == nextButton) {
	    int seln = imageList.getSelectedIndex();
	    seln = (seln + 1) % imageList.countItems();
	    obj = new Integer(seln);
	    imageList.select(seln);
	    evt.target = imageList;
	}
	else if (evt.target == prevButton) {
	    int seln = (imageList.getSelectedIndex() - 1);
	    if (seln < 0) seln = (imageList.countItems() - 1);
	    obj = new Integer(seln);
	    imageList.select(seln);
	    evt.target = imageList;
	}
	else if (evt.target == loadButton) {
	    if (currentImageURL != null && currentImage != null) {
		AppletContext ac = getAppletContext();
		ac.showDocument(currentImageURL, "image1");
	    }
	    ret = true;
	}

	if (evt.target == imageList) {
	    if (obj instanceof Integer) {
		String imgname;
		int selx = ((Integer)obj).intValue();
		imgname = (String)(imageNames.elementAt(selx));
		if (imgname != null) {
		    currentImageURL = null;
		    try {
			currentImageURL = new URL(imageBaseURL, imgname);
		    } catch (MalformedURLException mue) {
			System.err.println("Bad URL for image: " + mue);
		    }
		    if (currentImageURL != null) {
			currentImageName = imgname;
			currentImageDesc = (String)(imageDescriptions.elementAt(selx));
			Image tmp;
			tmp = (Image)(images.get(currentImageURL));
			if (tmp != null) {
			    currentImage = tmp;
			    canvas.setImage(currentImage, true);
			}
			else {
			    message("Loading " + currentImageURL + " - please wait..");
			    currentImage = getImage(currentImageURL);
			    images.put(currentImageURL, currentImage);
			    canvas.setImage(currentImage, false);
			}
		    }
		}
	    }
	    ret = true;
	}
	
	if (!ret) ret = super.action(evt,obj);
	return ret;
    }

    public void ditchImage(Image img) {
	if (img == currentImage) {
	    currentImage = null;
	    currentImageName = null;
	    images.remove(currentImageURL);
	}
	else images.clear();
    }


}
