/*
 * ImageMarker.java
 *
 * Benutzt die Klassen JComponentBounds und ComponentsContainer:
 * http://wiki.byte-welt.net/wiki/JComponentBounds
 * http://wiki.byte-welt.net/wiki/ComponentsContainer
 *
 * Hier wird ein "mainpanel" mit OverlayLayout benutzt.
 * Darin sind ein "imagePanel" und ein überlagertes "markerPanel".
 * Die Methode "addMarker(markerPanel)" fügt einen neuen Marker hinzu.
 */
import container.JComponentBounds;
import container.ComponentsContainer;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.beans.*;
import java.io.*;
import javax.imageio.*;
import javax.swing.*;
public class ImageMarker extends JFrame {
    private final static String FILENAME = "Picture1.jpg";
    private JPanel mainpanel;
    private Rectangle marker;
    private JButton btAddRect, btAddOval;
    private final ComponentsContainer markerPanel;
    private String filenameXml = "ImageMarker.xml";
    private final JPanel controls;
    public ImageMarker() {
        super("ImageMarker");
        setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
        setSize(800, 600);
        setLocationRelativeTo(null);
        controls = new JPanel();
        mainpanel = new JPanel() {
            @Override
            public boolean isOptimizedDrawingEnabled() {
                return false;
            }
        };
        mainpanel.setLayout(new OverlayLayout(mainpanel));
        markerPanel = new ComponentsContainer();
        load(null);
        markerPanel.setOpaque(false);
        Picture imagePanel = new Picture(FILENAME);
        mainpanel.add(markerPanel);//zuerst den Marker Panel (vorne)
        mainpanel.add(imagePanel);//dann die Bildkomponente (hinten)
        add(new JScrollPane(mainpanel));
        btAddRect = new JButton("Add Rectangle");
        btAddRect.setPreferredSize(new Dimension(130, 25));
        btAddRect.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e) {
                addMarker(markerPanel, MarkerComponent.RECT);
            }
        });
        controls.add(btAddRect);
        btAddOval = new JButton("Add Oval");
        btAddOval.setPreferredSize(new Dimension(130, 25));
        btAddOval.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e) {
                addMarker(markerPanel, MarkerComponent.OVAL);
            }
        });
        controls.add(btAddOval);
        add(controls, BorderLayout.SOUTH);
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(final WindowEvent e) {
                save(null);
                System.exit(0);
            }
        });
    }
    private void addMarker(final JPanel markerPanel, final int type) {
        marker = new Rectangle(0, 0, 100, 100);
        int m = JComponentBounds.MARGIN;
        final MarkerComponent markerComponent = new MarkerComponent(
                type, Color.RED, 1);
        markerComponent.setSize(marker.width + m * 2, marker.height
                + m * 2);
        markerComponent.setLocation(-m, -m);
        markerPanel.add(markerComponent);
        markerPanel.revalidate();
        displayMarkers();
    }
    private void displayMarkers() {
        System.out.println("Current Markers:");
        int componentCount = markerPanel.getComponentCount();
        for (int i = 0; i < componentCount; i++) {
            MarkerComponent component = (MarkerComponent) markerPanel.getComponent(i);
            int shape = component.getShape();
            String shapeS = null;
            if (shape == MarkerComponent.RECT) {
                shapeS = "RECT";
            } else if (shape == MarkerComponent.OVAL) {
                shapeS = "OVAL";
            }
            Rectangle componentRect = component.getComponentRect();
            System.out.println(shapeS + ": " + componentRect);
        }
    }
    private String save(final String filenameXml) {
        String returnValue = filenameXml;
        try {
            FileOutputStream fos = new FileOutputStream(
                    filenameXml == null ? this.filenameXml
                    : filenameXml);
            XMLEncoder o = new XMLEncoder(new BufferedOutputStream(fos));
            Component[] comps = markerPanel.getComponents();
            for (int i = 0; i < comps.length; i++) {
                o.writeObject(comps[i]);
            }
            o.close();
        } catch (IOException e) {
            JOptionPane.showMessageDialog(this, e.getMessage());
            returnValue = null;
        }
        return returnValue;
    }
    private String load(final String filenameXml) {
        String returnValue = filenameXml;
        XMLDecoder d = null;
        Object component = null;
        try {
            returnValue = filenameXml == null ? this.filenameXml
                    : filenameXml;
            FileInputStream fis = new FileInputStream(returnValue);
            d = new XMLDecoder(new BufferedInputStream(fis));
            returnValue = new File(returnValue).getAbsolutePath();
            try {
                component = d.readObject();
                markerPanel.removeAll();
                while (component != null) {
                    markerPanel.add((Component) component);
                    component = d.readObject();
                }
            } catch (ArrayIndexOutOfBoundsException e) {
            }
            d.close();
        } catch (FileNotFoundException ex) {
        }
        return returnValue;
    }
    public static void main(final String[] args) {
        Runnable gui = new Runnable() {
            public void run() {
                new ImageMarker().setVisible(true);
            }
        };
        //GUI must start on EventDispatchThread:
        SwingUtilities.invokeLater(gui);
    }
}
class Picture extends JComponent {
    private BufferedImage image;
    private String filename;
    public Picture(String filename) {
        this.filename = filename;
    }
    @Override
    public void paintComponent(final Graphics g) {
        super.paintComponent(g);
        if (image == null) {
            try {
                image =
                        ImageIO.read(getClass().getResource(filename));
                setPreferredSize(new Dimension(
                        image.getWidth(), image.getHeight()));
                revalidate();
            } catch (Exception ex) {
                image = new BufferedImage(
                        800, 600, BufferedImage.TYPE_INT_ARGB);
                Graphics graphics = image.getGraphics();
                graphics.setColor(Color.red);
                graphics.drawString("Bild nicht gefunden: "
                        + filename, 300, 500);
            }
        }
        Rectangle r = g.getClipBounds();
        g.drawImage(image, r.x, r.y, r.width + r.x, r.height + r.y,
                r.x, r.y, r.width + r.x, r.height + r.y, null);
    }
    public void setFilename(final String filename) {
        this.filename = filename;
        image = null;
        repaint();
    }
}