import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.swing.*;

/**
    Displays a Picture in a JFrame.

    @version 1.0 01/25/09
    @author Ed Parrish
*/
public class PictureDisplay {
    private static final int DEFAULT_LOCATION = 100;
    private static final int DEFAULT_OFFSET = 35;
    private static final int DEFAULT_SIZE = 512;
    private static int frameX = DEFAULT_LOCATION;
    private static int frameY = DEFAULT_LOCATION;
    private int width  = DEFAULT_SIZE;
    private int height = DEFAULT_SIZE;
    private BufferedImage canvas; // drawing surface
    private JFrame frame; // frame for drawing surface

    /**
        Default constructor.
    */
    public PictureDisplay() {
        frame = new JFrame("Display Image");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        canvas = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        ImageIcon icon = new ImageIcon(canvas);
        JLabel panel = new JLabel(icon);
        frame.add(panel, BorderLayout.CENTER);

        frame.pack();
        frameX += DEFAULT_OFFSET;
        frameY += DEFAULT_OFFSET;
        frame.setLocation(frameX, frameY);
        frame.setVisible(true);
    }

    /**
        Displays a Picture at the uper left-hand coordinates (0, 0) of the
        frame.

        @param pic The Picture to display. This method does nothing if pic
        is null.
    */
    public void showPicture(Picture pic) {
        showPicture(pic, 0, 0);
    }

    /**
        Displays a Picture at the specified x and y coordinates of the frame.

        @param pic The Picture to display. This method does nothing if pic
        is null.
        @param x The x coordinate.
        @param y The y coordinate.
    */
    public void showPicture(Picture pic, int x, int y) {
        if (pic == null) return;
        final int ALPHA = 0xff;
        final int ALPHA_SHIFT = 24;
        final int RED_SHIFT = 16;
        final int GREEN_SHIFT = 8;
        int w = pic.getWidth();
        int h = pic.getHeight();
        BufferedImage im = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
        Color[] colors = pic.getColors();
        for (int row = 0; row < h; row++) {
            for (int col = 0; col < w; col++) {
                int i = row * w + col; // row-major order
                int r = colors[i].getRed();
                int g = colors[i].getGreen();
                int b = colors[i].getBlue();
                int argb = (ALPHA << ALPHA_SHIFT) | (r << RED_SHIFT)
                    | (g << GREEN_SHIFT) | b;
                im.setRGB(col, row, argb);
            }
        }
        Graphics g2 = canvas.getGraphics();
        g2.drawImage(im, x, y, null);
        frame.repaint(); // refresh the canvas
    }

    /**
     * The main method used to test the class. Requires rose.ppm to run.
     *
     * @param args not used
     */
    public static void main(String[] args) {
        PictureDisplay display = new PictureDisplay();
        Picture p = new Picture();
        try {
            p.loadPPM("rose.ppm");
            display.showPicture(p);
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

}

