package scone.examples.rueckspiegel;


import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Rectangle2D;
import java.net.URL;
import java.util.Enumeration;
import java.util.Vector;

import javax.swing.JPanel;

import scone.netobjects.HtmlNode;
import scone.thumbnailgenerator.ThumbnailGenerator;


/**
 * The visualization
 *
 *
 * @author Frank Wollenweber
 */



class DrawingArea extends JPanel implements MouseListener {
    
    private Vector nodes; // All nodes of this visualisation
    private int height; // height of the drawingArea
    private int width; // width of the drawingArea
    private static final int nodeWidth = 150; // Width of one node in the visualization
    private static final int nodeHeight = 113; // Height of one node in the visualization

    /**
     * constructor
     */
    DrawingArea() {
        addMouseListener(this);
        setBackground(Color.white);
        setOpaque(true);
        nodes = new Vector();
    }

    /**
     * Add a new node to the visualization
     * @param hn add this node
     */
    void newNode(HtmlNode hn) {
        TreeNode node;
        Rectangle2D.Double r;
        URL u = null;

        try {
            u = new URL(hn.getUri());
        } catch (Exception e) {}
        
        node = new TreeNode();
        node.setHtmlNode(hn);
        synchronized (nodes) {
            nodes.add(node);
        }
        ThumbnailGenerator tg = new ThumbnailGenerator();

        tg.generateThumbnail(u);
        node.setThumbnail(tg.getThumbnail());
        tg.flush();
        setCoordinates();
        repaint();
    }

    /**
     * Recalculates the coordinates for all nodes in the visualization
     */
    private void setCoordinates() {
        synchronized (nodes) {
            TreeNode n;
            Enumeration en = nodes.elements();
            double x = 10;
            double y = 10;
            int ydim;

            while (en.hasMoreElements()) {
                n = (TreeNode) en.nextElement();
                n.setRect(new Rectangle2D.Double(x, y, nodeWidth, nodeHeight));
                y = y + nodeHeight + 25;
            }
            if (getParent().getHeight() > y) {
                ydim = getParent().getHeight();
            } else {
                ydim = (int) y;
            }
            setPreferredSize(new Dimension(getParent().getWidth(), ydim));
            revalidate();
        }
    }

    /**
     * Repaint the visualization
     * @param g paint on this graphics object
     */
    public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;

        g2.clearRect(0, 0, (int) this.getSize().getWidth(), (int) this.getSize().getHeight());
        g2.setStroke(new BasicStroke(1));
        Font f = new Font("Arial", Font.PLAIN, 10);

        g2.setFont(f);
        Enumeration en = nodes.elements();
        TreeNode n;

        synchronized (nodes) {
            while (en.hasMoreElements()) {
                n = (TreeNode) en.nextElement();
                if ((n.getThumbnail() != null) && (n.getRect() != null)) {
                    g2.drawImage(n.getThumbnail(), (int) n.getRect().getX() + 2, (int) n.getRect().getY() + 2, Color.white, this);
                }
                g2.setPaint(Color.lightGray);
                if (n.getRect() != null) {
                    g2.draw(n.getRect());
                    g2.setPaint(Color.black);
                    g2.drawString(n.getHtmlNode().getTitle(), (float) n.getRect().getX(), (float) (n.getRect().getY() + n.getRect().getHeight() + 12));
                }
            }
        }
    }

    /**
     * Clean the visualization
     */
    void clean() {
        synchronized (nodes) {
            nodes.removeAllElements();
        }
        setPreferredSize(new Dimension(getParent().getWidth(), getParent().getWidth()));
        revalidate();
        repaint();
    }

    public void mouseClicked(MouseEvent e) {}

    /**
     * If the user clicks a thumbnail, the selected document is loaded in the browser
     */
    public void mousePressed(MouseEvent e) {
        TreeNode n;

        synchronized (nodes) {
            if (nodes != null) {
                Enumeration en = nodes.elements();

                while (en.hasMoreElements()) {
                    n = (TreeNode) en.nextElement();
                    if ((n.getRect() != null)
                            && (n.getRect().contains(e.getPoint()))) {
                        BrowserControl.displayURL(n.getHtmlNode().getUri());
                        break;
                    }
                }
            }
        }
    }

    /**
     * Method of the interface MouseListener
     */
    public void mouseReleased(MouseEvent e) {}

    /**
     * Method of the interface MouseListener
     */
    public void mouseEntered(MouseEvent e) {}

    /**
     * Method of the interface MouseListener
     */
    public void mouseExited(MouseEvent e) {}
}
