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

/**
 * A class that represents a GUI for a square of a Snakes & Ladders board.
 * @author Derek Bridge 666 d.bridge@cs.ucc.ie
 */
public class SLSquareGUI
   extends JPanel
{
/* =======================================================================
       CONSTRUCTORS
   =======================================================================
*/
    /**
     * Allocates a new JPanel onto which the square's contents are drawn.
     * @param theSquare the square to which this panel correpsonds
     */
    public SLSquareGUI(Square theSquare)
    {   square = theSquare;
        setFont(FONT);
        fm = getFontMetrics(FONT);
        textHeight = fm.getHeight();
        setMinimumSize(
           new Dimension(textHeight * 4, textHeight * 4));
        setPreferredSize(
           new Dimension(textHeight * 4, textHeight * 4));
    }

/* =======================================================================
       PUBLIC INTERFACE
   =======================================================================
*/
    /**
     * Overrides the standard paintComponent() in order to render this
     * square.
     * @param g the Graphics context
     */
    public void paintComponent(Graphics g)
    {   super.paintComponent(g);
        /* The width and height available for painting is the panel
           width/height less the border width/heights.
         */
        int panelWidth = getSize().width;
        int panelHeight = getSize().height;
        Insets insets = getInsets(); // borders
        int availWidth = panelWidth - insets.left - insets.right;
        int availHeight = panelHeight - insets.top - insets.bottom;
        String txt = null;
        // Put the square number in the middle
        if (square.getPlayers().isEmpty())
        {   txt = "" + square.getSquareNumber();
            g.setColor(Color.black);
            g.drawString(txt,
                (panelWidth / 2) - (fm.stringWidth(txt) / 2), 
                (panelHeight / 2) + (textHeight / 2));
        }
        // Put the destination of any snake in bottom middle
        if (square.containsSnakeHead())
        {   txt = "" + square.getSnakeDestination().getSquareNumber();
            g.setColor(Color.red);
            g.drawString(txt,
                (panelWidth / 2) - (fm.stringWidth(txt) / 2), 
                panelHeight - insets.bottom - textHeight + fm.getAscent());
            Polygon downArrow = new Polygon();
            downArrow.addPoint(panelWidth / 2, panelHeight - insets.bottom);
            downArrow.addPoint(
               panelWidth / 2 - fm.stringWidth(txt) * 2, 
               panelHeight - insets.bottom - textHeight);
            downArrow.addPoint(
               panelWidth / 2 + fm.stringWidth(txt) * 2, 
               panelHeight - insets.bottom - textHeight);
            g.drawPolygon(downArrow);
        }
        // Put the destination of any ladder in top middle
        if (square.containsLadderFoot())
        {   txt = "" + square.getLadderDestination().getSquareNumber();
            g.setColor(Color.green);
            g.drawString(txt,
                (panelWidth / 2) - (fm.stringWidth(txt) / 2), 
                insets.top + textHeight); 
            Polygon upArrow = new Polygon();
            upArrow.addPoint(panelWidth / 2, insets.top);
            upArrow.addPoint(
               panelWidth / 2 - fm.stringWidth(txt) * 2, 
               insets.top + textHeight);
            upArrow.addPoint(
               panelWidth / 2 + fm.stringWidth(txt) * 2, 
               insets.top + textHeight);
            g.drawPolygon(upArrow);
        }
        // Put the player names over the square number
        Iterator iter = square.getPlayers().iterator();
        String names = "";
        while (iter.hasNext())
        {  names += ((Player) iter.next()).getName();
        }
        g.setColor(Color.blue);
        g.drawString(names,
            (panelWidth / 2) - (fm.stringWidth(names) / 2), 
            (panelHeight / 2) + (textHeight / 2));
    }

/* =======================================================================
       INSTANCE VARIABLES & CLASS VARIABLES
   =======================================================================
*/
    /**
     * The square that we are rendering.
     */
    private Square square;

    /**
     * The font we will use.
     */
    private static final Font FONT = new Font("Serif", Font.PLAIN, 10);

    /**
     * The font metrics for this component and this font.
     */
    private FontMetrics fm;

    /**
     * Something like the maximum height of text in this font.
     */
    private int textHeight;
}
