package de.axxeed.animosy.gui;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Iterator;
import java.util.TreeSet;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.Spring;
import javax.swing.SpringLayout;
import org.apache.log4j.Logger;
import de.axxeed.animosy.model.BoardModel;
import de.axxeed.animosy.model.Constants;
import de.axxeed.animosy.model.Detective;
import de.axxeed.animosy.model.Game;
import de.axxeed.animosy.model.GameBoard;
import de.axxeed.animosy.model.Manager;
import de.axxeed.animosy.model.Move;
import de.axxeed.animosy.model.Options;
/**
* @author Markus J. Luzius
* Created 25.04.2006 18:14:09
*
*/
public class StatusPanel extends JPanel implements MouseListener, Constants {
private static final long serialVersionUID = 8668121086774435472L;
private static final Logger log = Logger.getLogger(StatusPanel.class);
private static final int MINIMAP_X = 140;
private static final int MINIMAP_Y = 108;
JPopupMenu detectiveMenu = new JPopupMenu();
JButton startGameButton;
private static final int detYOffset = 100;
private static final int pixPerDetective = 50;
// TODO show MrX moves
// TODO additional context menu on detectives (finder, possible moves)
// TODO detective finder: highlight a selected detective
public StatusPanel() {
init();
}
public void init() {
// this.setBackground(new Color(200,200,50));
// this.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1));
this.setLayout( new FlowLayout() );
startGameButton = new JButton("Start Game");
startGameButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
log.debug("Start game button pressed");
Manager.getGame().startGame();
}
});
SpringLayout sl = new SpringLayout();
this.setLayout(sl);
Spring top = Spring.constant(20);
Spring left = Spring.constant(10);
log.debug("w:"+this.getWidth());
Spring width = Spring.constant(110);
Spring height = Spring.constant(40);
this.add(startGameButton, new SpringLayout.Constraints(top,left,width,height));
this.addMouseListener(this);
this.addKeyListener(GUIEventListener.getInstance());
}
public void paintComponent ( Graphics g )
{
// log.debug(".paint()");
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
Game game = Manager.getGame();
GameBoard b = game.getBoard();
Options opt = Manager.getOptions();
int maxMoves = opt.getNumberOfMoves();
int mrXPos = detYOffset+pixPerDetective*opt.getNumberOfDetectives()+10;
int y = 0;
if(b.getDetectives()!=null && game.getState() != Game.NO_GAME) {
if(startGameButton!=null && startGameButton.isVisible()) startGameButton.setVisible(false);
g2d.drawString("Current turn: "+game.getCurrentMove()+" of "+maxMoves, 10, 20);
g2d.drawString(""+game.getStateText(), 10, 40);
g2d.drawString("Detective positions:", 10, detYOffset-20);
g2d.drawLine(10, detYOffset-18, 120, detYOffset-18);
int activeDet = game.getActiveDetectiveIndex();
for(int i=0;i<opt.getNumberOfDetectives();i++) {
if(i==activeDet) {
g2d.setColor(Color.CYAN);
g2d.fillRect(18, detYOffset-12+pixPerDetective*i, 100, 15);
}
Detective d = b.getDetectives()[i];
g2d.setColor(Color.BLACK);
if(d.isStranded()) {
g2d.setColor(Color.RED);
}
g2d.drawString("Detective "+(i+1)+": "+d.getPosition().getPosition(), 20, detYOffset+pixPerDetective*i);
g2d.setColor(Detective.getColor(i));
g2d.fillOval(5, detYOffset-9+pixPerDetective*i, 10, 10);
g2d.setColor(Move.getColor(TAXI));
g2d.drawString(""+d.getTaxiTickets()+"x T", 20, detYOffset+pixPerDetective*i+20);
g2d.setColor(Move.getColor(BUS));
g2d.drawString(""+d.getBusTickets()+"x B", 60, detYOffset+pixPerDetective*i+20);
g2d.setColor(Move.getColor(UG));
g2d.drawString(""+d.getUndergroundTickets()+"x U", 100, detYOffset+pixPerDetective*i+20);
}
if(Manager.getOptions().isCheat() || game.isCheckPoint()) {
g2d.setColor(Color.BLACK);
g2d.drawString("MrX: "+b.getMrX().getPosition().getPosition(), 20, mrXPos);
g2d.fillOval(5, mrXPos-9, 10, 10);
}
// here goes the movement history of MrX
y = mrXPos + 20;
int maxY = y;
int x = 10;
Move[] mrXmoves = b.getMrX().getPrevPos();
for(int i=0;i<=maxMoves;i++) {
g2d.setColor(Color.BLACK);
if(i>=game.getCurrentMove()) {
g2d.setColor(Color.GRAY);
g2d.drawRect(x, y, 30, 15);
}
if(game.isCheckPoint(i+1)) {
g2d.setColor(new Color(120,200,255));
g2d.fillRect(x, y, 30, 15);
}
if(i==game.getCurrentMove()-1 && game.getState() == Game.MOVE_MRX) {
g2d.setColor(Color.RED);
g2d.drawRect(x, y, 30, 15);
}
if((i+1)<mrXmoves.length) {
g2d.setColor(Move.getColor(mrXmoves[i+1].getType()));
if(opt.isCheat() || game.isCheckPoint()) {
g2d.drawString(""+mrXmoves[i+1].getNode(), x+3, y+12);
}
else {
g2d.drawString(""+mrXmoves[i+1].toStringTicket(), x+3, y+12);
}
}
else if((i+1)==mrXmoves.length && game.getState() == Game.MOVE_MRX) {
g2d.drawString("???", x+3, y+12);
}
else {
g2d.drawString(""+(i+1), x+3, y+12);
}
y += 18;
if(i%((maxMoves/3)+1)==((maxMoves/3))) {
x += 35;
y = mrXPos + 20;
}
if(y>maxY) maxY = y;
}
y = maxY;
}
else {
if(startGameButton!=null && !startGameButton.isVisible()) startGameButton.setVisible(true);
startGameButton.repaint();
g2d.drawString("no game yet", 10, 75);
}
// Minimap
if(y==0) {
y = this.getHeight()-MINIMAP_Y-55;
}
else {
y+=30;
}
MapPanel mp = (MapPanel)PanelRepository.get(PanelRepository.MAP_PANEL);
g2d.drawImage(mp.getMiniImage(MINIMAP_X, MINIMAP_Y), 3, y, null);
int x = 3+Math.min(MINIMAP_X-1, (int) (mp.getOffset().x*mp.getMiniImageZoom(MINIMAP_X, MINIMAP_Y)));
int y2 = y+Math.min(MINIMAP_Y-1, (int) (mp.getOffset().y*mp.getMiniImageZoom(MINIMAP_X, MINIMAP_Y)));
int w = Math.min(MINIMAP_X, (int)(mp.getWidth()*mp.getMiniImageZoom(MINIMAP_X, MINIMAP_Y)*(1.0/mp.getZoom())));
int h = Math.min(MINIMAP_Y, (int)(mp.getHeight()*mp.getMiniImageZoom(MINIMAP_X, MINIMAP_Y)*(1.0/mp.getZoom())));
g2d.drawRect(x, y2, w, h);
g2d.drawString("Time: "+game.getGameTime(), 10, this.getHeight()-40);
g2d.drawString("Zoom: "+mp.getZoomInfo(), 10, this.getHeight()-25);
g2d.drawString("mem: "+Runtime.getRuntime().totalMemory()/1024+"k", 10, this.getHeight()-10);
g2d.dispose();
}
// ==============================================================
public void mouseClicked(MouseEvent e) {
// XXX Auto-generated method stub
}
public void mouseEntered(MouseEvent e) {
// XXX Auto-generated method stub
}
public void mouseExited(MouseEvent e) {
// XXX Auto-generated method stub
}
public void mousePressed(MouseEvent e) {
// XXX Auto-generated method stub
}
public void mouseReleased(MouseEvent me) {
if ( me.isPopupTrigger() ) {
GameBoard b = Manager.getGame().getBoard();
if(b.getDetectives()!=null) {
int activeDet = Manager.getGame().getActiveDetectiveIndex();
// don't show the menu, if the user clicked anywhere else except the current detective
if(me.getY()<detYOffset-12+pixPerDetective*activeDet || me.getY()>detYOffset+2+pixPerDetective*activeDet) {
return;
}
detectiveMenu.removeAll();
JMenuItem menu1 = new JMenuItem( "Find me");
menu1.setEnabled(false);
detectiveMenu.add( menu1 );
detectiveMenu.addSeparator();
TreeSet<Move> possibleMoves = b.getDetectives()[activeDet].getPossibleMoves();
if(possibleMoves==null) {
AbstractAction action = new AbstractAction("Skip turn")
{
private static final long serialVersionUID = 0L;
public void actionPerformed( ActionEvent e ) {
Manager.getGame().nextDetective();
((MapPanel)PanelRepository.get(PanelRepository.MAP_PANEL)).updatePositions();
PanelRepository.get(PanelRepository.STATUS_PANEL).repaint();
}
};
detectiveMenu.add( action );
}
else {
log.debug("Possible moves: "+possibleMoves.size()+" - "+possibleMoves);
Iterator<Move> i = possibleMoves.iterator();
while(i.hasNext()) {
Move m = (Move) i.next();
StringBuilder linkText = new StringBuilder();
linkText.append(m.getNode()).append(" (");
switch(m.getType()) {
case BoardModel.TAXI: linkText.append("TAXI").append(")"); break;
case BoardModel.BUS: linkText.append("BUS").append(")"); break;
case BoardModel.UG: linkText.append("UG").append(")"); break;
case BoardModel.BLACK: linkText.append("XXX").append(")"); break;
case BoardModel.INF: linkText.append("INF").append(")"); break;
default: linkText.append("???").append(")"); break;
}
// detectiveMenu.add( new JMenuItem(linkText.toString()) );
AbstractAction action = new AbstractAction(linkText.toString())
{
private static final long serialVersionUID = -4379938472159497577L;
public void actionPerformed( ActionEvent e ) {
log.debug("Selected move: "+((Move)this.getValue(e.getActionCommand())));
Manager.getGame().moveDetective((Move)this.getValue(e.getActionCommand()));
// Move selectedMove = (Move)this.getValue(e.getActionCommand());
// Detective d = (Detective)this.getValue("Detective");
// d.changePosition(BoardModel.getInstance().getNode(selectedMove.getNode()), selectedMove.getType());
// Manager.getGame().nextDetective();
// ((MapPanel)PanelRepository.get(PanelRepository.MAP_PANEL)).updatePositions();
PanelRepository.get(PanelRepository.STATUS_PANEL).repaint();
}
};
action.putValue(linkText.toString(), m);
action.putValue("Detective", b.getDetectives()[activeDet]);
detectiveMenu.add( action );
}
detectiveMenu.addSeparator();
JMenuItem options = new JMenuItem( "Help");
options.setEnabled(false);
detectiveMenu.add( options );
}
detectiveMenu.show( me.getComponent(), me.getX(), me.getY() );
}
}
}
}