/*
 * 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;
    }

}
