import java.util.*;

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;

/**
 * A panel that displays a game.
 *
 * @author Jim Glenn
 * @version 0.1 from LiberationPanel of 1/8/2009
 */

public class GameView extends JPanel implements Observer
{
    /**
     * The game this view displays.
     */

    private GameModel model;

    /**
     * Creates a new view that displays the given game.
     *
     * @param g the game to display in the new view
     */

    public GameView(GameModel m)
    {
	model = m;
	model.addObserver(this);
	
	// get this panel the focus so its KeyListeners will get events

	setFocusable(true);
	addMouseListener(new MouseAdapter() {
		public void mouseClicked(MouseEvent e)
		{
		    requestFocusInWindow();
		}
	    }
			 );
    }

    /**
     * Automatically invoked when the model invokes its notifyObservers
     * method.
     */

    public void update(Observable m, Object args)
    {
	repaint();
    }

    /**
     * Draws this view.
     *
     * @param g the graphics context to draw on.
     */

    public void paint(Graphics g)
    {
	g.clearRect(0, 0, getWidth(), getHeight());

	// we will draw the whole playable area in this panel

	// determine the scale factor to translate from game coordinates
	// to view coordinates

	double scale = Math.min(getWidth() / model.getWidth(),
				getHeight() / model.getHeight());

	for (Sprite s : model.getSprites())
	    {
		drawSprite(g, s, scale);
	    }
    }    

    /**
     * Draws the given sprite in this view.
     *
     * @param g the graphics context to draw in
     * @param s the sprite to draw
     * @param scale the scaling factor that defines the transformation
     * from game coordinates to pixel coordinates
     */
    
    private void drawSprite(Graphics g, Sprite s, double scale)
    {
	// translate the outline of the sprite from a GeneralPath in
	// game coordinates to a Polygon in pixel coordinates

	Polygon p = new Polygon();

	GeneralPath outline = s.getOutline();
	PathIterator i = outline.getPathIterator(new AffineTransform());
	double[] coords = new double[6];
	while (!i.isDone())
	    {
		if (i.currentSegment(coords) != PathIterator.SEG_CLOSE)
		    {
			p.addPoint((int)(coords[0] * scale),
				   (int)(coords[1] * scale));
		    }
		i.next();
	    }

	// draw the polygon

	g.setColor(s.getColor());
	g.fillPolygon(p);
    }
}

