/*
 * PENDING: list of possible things to do to this program
 *
 * turn into application
 * provide an "overview" view where you can see small thumbnail
 *    versions of each picture which you can click on to choose one.
 * background loading of images?
 * should probably use a scroll bar for the image thingy
 * Create a "photoalbumcreator" application that lets the user
 *    type in photonames and captions and writes out the properties
 *    files/applettags, and use that along-side the "photoalbumviewer"
 *    which then just views the pictures....
 */

import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.AbstractButton;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
import javax.swing.BorderFactory;

import java.awt.*;
import java.net.URL;
import java.util.Vector;
import java.util.StringTokenizer;

public class IconDemoApplet extends JApplet 
			implements java.awt.event.ActionListener {

    Vector pictures;

    JButton previous;
    JButton next;
    JLabel iconLabel;
    JLabel captionLabel;
    JLabel numberLabel;

    int current = 0;
    int widthOfWidest = 0;
    int heightOfTallest = 0;

    boolean DEBUG = true;

    String imagedir = null;

    //Hack to avoid annoying error message.
    public IconDemoApplet() {
        getRootPane().putClientProperty("defeatSystemEventQueueCheck",
                                        Boolean.TRUE);
    }

    public void init() {
	imagedir = getParameter("IMAGEDIR");
	if (imagedir != null)
	    imagedir = imagedir + "/";
	
	//parse the applet parameters that
	//list the images, their captions, and their sizes
	pictures = parseParameters();

	//if the applet tag didn't provide an "IMAGE0"
	//put up an error message
	if (pictures.size() == 0) {
	    captionLabel = new JLabel("No Images to View");
	    captionLabel.setHorizontalAlignment(JLabel.CENTER);
	    getContentPane().add(captionLabel);
	    return;
	}

	//get the first image now so it can start loading
	Photo first = (Photo)pictures.firstElement();
	ImageIcon icon = new ImageIcon(getURL(imagedir + first.filename));
	first.setIcon(icon);

	//NOW CREATE THE GUI COMPONENTS

	//a label to identify XX of XX
	numberLabel = new JLabel("Picture " + (current+1) + " of " + pictures.size());
	numberLabel.setHorizontalAlignment(JLabel.LEFT);
	numberLabel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 5));

	//a label for the caption
        captionLabel = new JLabel(first.caption);
	captionLabel.setHorizontalAlignment(JLabel.CENTER);
	captionLabel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0));

	//the picture
        iconLabel = new JLabel(icon);
	iconLabel.setHorizontalAlignment(JLabel.CENTER);
	iconLabel.setVerticalAlignment(JLabel.CENTER);
	iconLabel.setBorder(BorderFactory.createCompoundBorder(
			BorderFactory.createLoweredBevelBorder(),
			BorderFactory.createEmptyBorder(5, 5, 5, 5)
	));
	iconLabel.setBorder(BorderFactory.createCompoundBorder(
			BorderFactory.createEmptyBorder(0, 0, 10, 0),
			iconLabel.getBorder()
	));
	iconLabel.setToolTipText(first.filename + ": " + icon.getIconWidth() +
				 " X " + icon.getIconHeight());

	//set the preferred size for the picture.
	//add room for the borders.
	Insets i = iconLabel.getBorder().getBorderInsets(iconLabel);
	iconLabel.setPreferredSize(new Dimension(widthOfWidest+i.left+i.right,
						 heightOfTallest+i.bottom+i.top));

	//next and previous buttons
        ImageIcon nextIcon = new ImageIcon(getURL(imagedir + "right.gif"));
        ImageIcon previousIcon = new ImageIcon(getURL(imagedir + "left.gif"));

        //XXX: In 1.0.2 only, must use FixedJButton instead of JButton
	//XXX: if you want mnemonics to work.
        //XXX: See ui/swing/workaround.html for details.
        previous = new JButton("Previous Picture", previousIcon);
        previous.setVerticalTextPosition(AbstractButton.CENTER);
        previous.setHorizontalTextPosition(AbstractButton.RIGHT);
        previous.setMnemonic('p');
        previous.setActionCommand("previous");
	previous.addActionListener(this);
	previous.setEnabled(false);

        next = new JButton("Next Picture", nextIcon);
        next.setVerticalTextPosition(AbstractButton.CENTER);
        next.setHorizontalTextPosition(AbstractButton.LEFT);
        next.setMnemonic('n');
        next.setActionCommand("next");
	next.addActionListener(this);

	//LAYOUT THE GUI
	GridBagLayout layout = new GridBagLayout();
        GridBagConstraints c = new GridBagConstraints();

	Container contentPane = getContentPane();
	contentPane.setLayout(layout);

        c.gridwidth = GridBagConstraints.REMAINDER;
        c.fill = GridBagConstraints.HORIZONTAL;
        layout.setConstraints(numberLabel, c);
        contentPane.add(numberLabel);

        layout.setConstraints(captionLabel, c);
        contentPane.add(captionLabel);

        c.gridwidth = GridBagConstraints.REMAINDER;
        c.fill = GridBagConstraints.BOTH;
        layout.setConstraints(iconLabel, c);
        contentPane.add(iconLabel);

        c.gridwidth = GridBagConstraints.RELATIVE;
        c.fill = GridBagConstraints.HORIZONTAL;
        layout.setConstraints(previous, c);
        contentPane.add(previous);

        c.gridwidth = GridBagConstraints.REMAINDER;
        layout.setConstraints(next, c);
        contentPane.add(next);
    }

    protected Vector parseParameters() {
	Vector pix = new Vector(10);	//start with 10, grows if necessary
	int i = 0;			//parameters index must start at 0
	String paramName = "IMAGE" + i;
	String paramValue;

	while ((paramValue = getParameter(paramName)) != null) {
	    Photo pic = new Photo(paramValue, getCaption(i),
				  getWidth(i), getHeight(i));
	    pix.addElement(pic);
	    i++;
	    paramName = "IMAGE" + i;
	}
	return pix;
    }

    protected String getCaption(int i) {
	return getParameter("CAPTION"+i);
    }

    protected int getWidth(int i) {
	int width = 0;
	String widthString = getParameter("WIDTH"+i);
	if (widthString != null) {
	    try {
		width = Integer.parseInt(widthString);
	    } catch (NumberFormatException e) {
		width = 0;
	    }
	} else {
	    width = 0;
	}
	if (width > widthOfWidest)
	    widthOfWidest = width;
	return width;
    }

    protected int getHeight(int i) {
	int height = 0;
	String heightString = getParameter("HEIGHT"+i);
	if (heightString != null) {
	    try {
		height = Integer.parseInt(heightString);
	    } catch (NumberFormatException e) {
		height = 0;
	    }
	} else {
	    height = 0;
	}
	if (height > heightOfTallest)
	    heightOfTallest = height;
	return height;
    }

    public String[][] getParameterInfo() {
	String[][] info = {
	    {"IMAGEDIR", "string", "directory containing image files" },
	    {"IMAGEN", "string", "filename" },
	    {"CAPTIONN", "string", "caption" },
	    {"WIDTHN", "integer", "width of image" },
	    {"HEIGHTN", "integer", "height of image" },
	};
	return info;
    }

    public void actionPerformed(java.awt.event.ActionEvent e) {
	ImageIcon icon = null;

	iconLabel.setIcon(null);
	iconLabel.setText("... Loading ...");
        if (e.getActionCommand().equals("next")) {
	    current += 1;
	    if (!previous.isEnabled())
		previous.setEnabled(true);
	    if (current == pictures.size() - 1)
		next.setEnabled(false);
        } else {
	    current -= 1;
	    if (!next.isEnabled())
		next.setEnabled(true);
	    if (current == 0)
		previous.setEnabled(false);
        }
	Photo pic = (Photo)pictures.elementAt(current);
	icon = pic.getIcon();
	if (icon == null) {
            icon = new ImageIcon(getURL(imagedir + pic.filename));
	    pic.setIcon(icon);
	}
	iconLabel.setText("");
	iconLabel.setIcon(icon);
	iconLabel.setToolTipText(pic.filename + ": " + icon.getIconWidth() +
				 " X " + icon.getIconHeight());
	captionLabel.setText(pic.caption);
	numberLabel.setText("Picture " + (current+1) + " of " + pictures.size());
    }    

    /*
     * XXX: This method should be made obsolete by a new ImageIcon
     * XXX: constructor: ImageIcon(URL, String, String).
     */
    protected URL getURL(String filename) {
        URL codeBase = this.getCodeBase();
        URL url = null;

        try {
            url = new URL(codeBase, filename);
        } catch (java.net.MalformedURLException e) {
            System.out.println("Couldn't create image: badly specified URL");
            return null;
        }

        return url;
    }

}
