/* dIntProg Browser. A webbrowser written in Java.
 * Copyright (C) 2001 Martin Geisler <gimpster@gimpster.com>
 *  
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the
 * 
 * Free Software Foundation, Inc.,
 * 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

import javax.swing.*;
import java.awt.*;
import java.net.*;

/** The class responsible for the painting. <code>DocumentView</code>
 *  extends {@link JComponent} so that it can be inserted into other
 *  containers, like a {@link JScrollPane}. */
public class DocumentView extends JComponent {

    private DocumentModel model;
    private BrowserModel b_model;
    private Graphics pen;
    private int width;

    /** This works around a stupid bug in Java. You have to change the
     *  /size/ of the font to make sure that your change in style is
     *  noticed... */
    private Font switch_font = new Font(null, Font.PLAIN, 4);

    private int margin = 8;

    /** Makes a new <code>DocumentView</code>. 
     *  @param dm the {@link DocumentModel}.
     *  @param bm the {@link BrowserModel}. */
    public DocumentView(DocumentModel dm, BrowserModel bm) {
        model = dm;
        b_model = bm;
        width = getWidth();
    }

    /** Returns the title of the {@link DocumentModel}.
     *  @return the title of the document. */
    public String getTitle() {
        return model.title;
    }

    
    private Color findLinkColor(HyperLink link) {
        if (b_model.seenLink(link)) {
            return Color.red;
        } else {
            return Color.blue;
        }
    }

    /** Redraws the component
     *  @param g the Graphics context. */
    public void paintComponent(Graphics g) {
        if (width != getWidth()) {
            model.box.doLayout(g, this, getWidth() - 2*margin);
            width = getWidth();
            setPreferredSize(new Dimension(model.box.getMinimumWidth()+2*margin,
                                           model.box.getHeight()));
        }
        pen = g; // will be used when the model calls our drawing-functions.

        /* Antialiasing! */
        if (Browser.antialias) {
            ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                                             RenderingHints.VALUE_ANTIALIAS_ON);
        }

        model.box.drawAt(margin, margin, this);
        revalidate();
    }

    /** Draws a string.
     *  @param x the x coordinate.
     *  @param y the y coordinate.
     *  @param s the string to be drawn.
     *  @param f the font to be used.
     *  @param link a link, or <code>null</code> if there's no link. */
    public void drawString(int x, int y, String s, Font f, HyperLink link) {
        pen.setFont(f);
        this.drawString(x, y, pen.getFontMetrics().getHeight(),
                        s, f, link);
    }


    /** Draws a string.
     *  @param x the x coordinate.
     *  @param y the y coordinate.
     *  @param h the height of the string.
     *  @param s the string to be drawn.
     *  @param f the font to be used.
     *  @param link a link, or <code>null</code> if there's no link. */
    public void drawString(int x, int y, int h, String s, Font f, 
                           HyperLink link) {
        pen.setFont(switch_font);
        pen.drawString("", x, y);
        pen.setFont(f);
        if (link != null) {
            b_model.registreLink(link);
            pen.setColor(findLinkColor(link));
        } else {
            pen.setColor(Color.black);
        }
        pen.drawString(s, x, y+h);
    }

    /** Draws an image.
     *  @param x the x coordinate.
     *  @param y the y coordinate.
     *  @param img the image.
     *  @param link a link, or <code>null</code> if there's no link. */
    public void drawImage(int x, int y, Image img, HyperLink link) {
        if (link != null) {
            b_model.registreLink(link);
        }
	pen.drawImage(img, x, y, this);
    }

    /** Draws a rectangle.
     *  @param x the x coordinate.
     *  @param y the y coordinate.
     *  @param w the width.
     *  @param h the height.
     *  @param c the color. */
    public void drawRect(int x, int y, int w, int h, Color c) {
        pen.setColor(c);
        pen.drawRect(x, y, w, h);
    }

    /** Draws and fills a rectangle.
     *  @param x the x coordinate.
     *  @param y the y coordinate.
     *  @param w the width.
     *  @param h the height.
     *  @param c the color. */
    public void fillRect(int x, int y, int w, int h, Color c) {
        pen.setColor(c);
        pen.fillRect(x, y, w, h);
    }

    /** Draws an oval.
     *  @param x the x coordinate.
     *  @param y the y coordinate.
     *  @param w the width.
     *  @param h the height.
     *  @param c the color. */
    public void fillOval(int x, int y, int w, int h, Color c) {
        pen.setColor(c);
        pen.fillOval(x, y, w, h);
    }

    /** Draws and fills an oval.
     *  @param x the x coordinate.
     *  @param y the y coordinate.
     *  @param w the width.
     *  @param h the height.
     *  @param c the color. */
    public void drawOval(int x, int y, int w, int h, Color c) {
        pen.setColor(c);
        pen.drawOval(x, y, w, h);
    }

}