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

public class BlobWarsPanel extends JPanel
{
    private BlobWarsWorld m_world;
    private BlobWars m_gui;

    public BlobWarsPanel(BlobWars gui, BlobWarsWorld world)
    {
        Dimension sz = new Dimension(500, 500);
        setMinimumSize(sz);
        setPreferredSize(sz);
        setMaximumSize(sz);
        m_world = world;
        m_gui = gui;
    }

    public void paint(Graphics g)
    {
        Graphics2D g2d = (Graphics2D) g;

        /* draw background */
        g2d.setColor(Color.BLACK);
        g2d.fillRect(0, 0, getWidth(), getHeight());

        /* draw players */
        for (Player p : m_world.getPlayers().values())
        {
            if (p.health > 0.0)
                drawPlayer(p, g);
        }

        for (Shot s : m_world.getShots().values())
        {
            drawShot(s, g);
        }
    }

    private void drawPlayer(Player p, Graphics g)
    {
        double xscl = p.x * getWidth();
        double yscl = p.y * getHeight();
        double rxscl = p.radius * getWidth();
        double ryscl = p.radius * getHeight();

        /* draw the blob circle */
        g.setColor(p.name.equals(m_gui.getPlayerName())
                   ? new Color(0.8f, 1.0f, 1.0f)
                   : Color.CYAN);
        g.fillOval((int) (xscl - rxscl),
                   (int) (getHeight() - (yscl + ryscl)),
                   (int) (2 * rxscl),
                   (int) (2 * ryscl));
        g.setColor(Color.BLUE);
        g.drawOval((int) (xscl - rxscl),
                   (int) (getHeight() - (yscl + ryscl)),
                   (int) (2 * rxscl),
                   (int) (2 * ryscl));

        /* draw the health bar */
        Color hcol;
        if (p.health >= 0.9)
            hcol = Color.GREEN;
        else if (p.health >= 0.5)
            hcol = new Color((float) ((0.9 - p.health) / 0.4), 1.0f, 0.0f);
        else if (p.health >= 0.1)
            hcol = new Color(1.0f, (float) ((p.health - 0.1) / 0.4), 0.0f);
        else
            hcol = Color.RED;
        int hbarwidth = (int) (rxscl * 1.4);
        int hbarheight = (int) (ryscl * 0.2);
        int hbarx = (int) (xscl - hbarwidth/2);
        int hbary = (int) (getHeight() - (p.r < Math.PI
                                          ? (yscl - 3*hbarheight/2)
                                          : (yscl + 5*hbarheight/2)));
        g.setColor(hcol);
        g.fillRect(hbarx, hbary, (int) (hbarwidth * p.health), hbarheight);
        g.setColor(Color.BLUE);
        g.drawRect(hbarx, hbary, hbarwidth, hbarheight);

        /* draw the shooter triangle */
        int[] s_pointsx = new int[3];
        int[] s_pointsy = new int[3];
        s_pointsx[0] = (int) (xscl + rxscl * Math.cos(p.r));
        s_pointsy[0] = getHeight() -
                       (int) (yscl + ryscl * Math.sin(p.r));
        s_pointsx[1] = (int) (xscl + rxscl * 0.3 * Math.cos(p.r + Math.PI / 2));
        s_pointsy[1] = getHeight() -
                       (int) (yscl + ryscl * 0.3 * Math.sin(p.r + Math.PI / 2));
        s_pointsx[2] = (int) (xscl + rxscl * 0.3 * Math.cos(p.r - Math.PI / 2));
        s_pointsy[2] = getHeight() -
                       (int) (yscl + ryscl * 0.3 * Math.sin(p.r - Math.PI / 2));
        g.setColor(Color.WHITE);
        g.fillPolygon(s_pointsx, s_pointsy, 3);
        g.setColor(Color.BLACK);
        g.drawPolygon(s_pointsx, s_pointsy, 3);

        /* draw the player's name */
        char[] chars = new char[p.name.length()];
        p.name.getChars(0, p.name.length(), chars, 0);
        int width = g.getFontMetrics().charsWidth(chars, 0, p.name.length());
        int height = g.getFontMetrics().getHeight();
        g.setColor(Color.WHITE);
        g.drawString(p.name,
                     (int) (xscl - width/2),
                     getHeight() - 4 - (p.y >= 0.5
                                        ? ((int) (yscl - ryscl - height))
                                        : ((int) (yscl + ryscl)) ));
    }

    private void drawShot(Shot s, Graphics g)
    {
        double xscl = s.x * getWidth();
        double yscl = s.y * getHeight();
        double rxscl = s.radius * getWidth();
        double ryscl = s.radius * getHeight();

        /* draw the shot as a circle */
        g.setColor(Color.ORANGE);
        g.fillOval((int) (xscl - rxscl),
                   (int) (getHeight() - (yscl + ryscl)),
                   (int) (2 * rxscl),
                   (int) (2 * ryscl));
        g.setColor(Color.RED);
        g.drawOval((int) (xscl - rxscl),
                   (int) (getHeight() - (yscl + ryscl)),
                   (int) (2 * rxscl),
                   (int) (2 * ryscl));
    }
}
