package nbtool.gui.utilitypanes;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import nbtool.data.NBitesTeamBroadcast;
import nbtool.data.log.Log;
import nbtool.gui.field.Field;
import nbtool.gui.field.FieldConstants;
import nbtool.gui.field.NaoRobot;
import nbtool.io.BroadcastIO;
import nbtool.io.BroadcastIO.TeamBroadcastInstance;
import nbtool.io.BroadcastIO.TeamBroadcastListener;
import nbtool.io.CommonIO.IOInstance;
import nbtool.util.Debug;
public class WorldViewUtility extends UtilityParent {
private class WorldView extends JFrame implements TeamBroadcastListener, ActionListener, ComponentListener
{
private TeamBroadcastInstance broadcastListener = null;
@Override
public void componentResized(ComponentEvent e) { }
@Override
public void componentMoved(ComponentEvent e) { }
@Override
public void componentShown(ComponentEvent e) { }
@Override
public void componentHidden(ComponentEvent e) {
if (broadcastListener == null) {
return;
} else {
Debug.plain("WorldView stopping broadcast listener...");
broadcastListener.kill();
broadcastListener = null;
}
}
protected WorldView() {
super();
addComponentListener(this);
this.setTitle("WorldView");
//default, usually overridden later.
this.setSize((int) FieldConstants.FIELD_WIDTH + 150, (int) FieldConstants.FIELD_HEIGHT + 50);
this.getContentPane().setLayout(new BorderLayout());
initiateTools();
initiateFieldAndPlayers();
}
@Override
public void ioFinished(IOInstance instance) {
// listener died for some reason.
}
@Override //TBI should be smart enough to use acceptTeamBroadcast() instead.
public void ioReceived(IOInstance inst, int ret, Log... out) {
Debug.error("??? recvd...");
}
@Override
public boolean ioMayRespondOnCenterThread(IOInstance inst) {
return false;
}
@Override
public void acceptTeamBroadcast(NBitesTeamBroadcast tb) {
//use tb
Debug.print("got from {%s:%s}", tb.robotName, tb.robotIp);
//Logger.printf("header: %s", tb.message.header);
Debug.print("Team: %s, Player: %s",tb.dataTeamPacket.getTeamNumber(), tb.dataTeamPacket.getPlayerNumber());
for (String s : tb.message.errors) {
Debug.print("\t%s", s);
}
if(runWorldview) {
if(tb.dataTeamPacket.getTeamNumber() == teamNumber) {
int index = tb.dataTeamPacket.getPlayerNumber() - 1;
if (index >= 0 && index < robots.length) {
if(tb.dataWorldModel.getActive()) {
robots[tb.dataTeamPacket.getPlayerNumber()-1] = new NaoRobot();
robots[tb.dataTeamPacket.getPlayerNumber()-1].wvNao(tb);
} else {
robots[tb.dataTeamPacket.getPlayerNumber()-1] = null;
}
// shared ball
if(index == 3 || index == 4) {
robots[tb.dataTeamPacket.getPlayerNumber()-1].wvSharedBall(tb);
}
updateTeamInfo(tb);
fieldDisplay.repaint();
} else {
Debug.warn("WorldView got packet from correct team with OOB player: %d",
tb.dataTeamPacket.getPlayerNumber());
}
}
}
}
private void initiateFieldAndPlayers() {
fieldDisplay = new JPanel() {
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
f.drawField(g2, shouldFlip,lineColors);
for(int i=0; i<robots.length; i++) {
if(robots[i] != null) {
robots[i].drawNaoWV(g2, shouldFlip);
}
}
}
};
this.getContentPane().add(fieldDisplay, BorderLayout.CENTER);
}
private void initiateTools() {
accessories = new JPanel();
accessories.setLayout(new BoxLayout(accessories, BoxLayout.PAGE_AXIS));
flip = new JButton("flip");
flip.addActionListener(this);
flip.setAlignmentX(Component.LEFT_ALIGNMENT);
flip.setEnabled(true);
accessories.add(flip);
teamNumberInput = new JTextField("0",2);
teamNumberInput.setMaximumSize(new Dimension(Short.MAX_VALUE, teamNumberInput.getPreferredSize().height));
teamNumberInput.setAlignmentX(Component.LEFT_ALIGNMENT);
accessories.add(teamNumberInput);
startWorldView = new JButton("Start WorldView");
startWorldView.addActionListener(this);
startWorldView.setAlignmentX(Component.LEFT_ALIGNMENT);
accessories.add(startWorldView);
JLabel robotStates = new JLabel("Robot States");
robotStates.setFont(new Font("Verdana", Font.BOLD, 16));
robotStates.setAlignmentX(Component.LEFT_ALIGNMENT);
accessories.add(robotStates);
for(int i=0; i<5; i++) {
if(playerRoles[i] == null) { playerRoles[i] = "Inactive";}
teamInfo[i] = new JLabel("Player "+(i+1)+": "+playerRoles[i]);
teamInfo[i].setAlignmentX(Component.LEFT_ALIGNMENT);
accessories.add(teamInfo[i]);
}
//accessories.add(Box.createHorizontalStrut(200));
accessories.add(Box.createVerticalGlue());
this.getContentPane().add(accessories, BorderLayout.EAST);
}
private void updateTeamInfo(NBitesTeamBroadcast tb) {
int role = tb.dataWorldModel.getRole();
int playerNum = tb.dataTeamPacket.getPlayerNumber();
if(!tb.dataWorldModel.getActive()) {
teamInfo[playerNum-1].setText("Player "+(playerNum)+": Penalized");
} else {
switch (role) {
case 1:playerRoles[playerNum-1] = "Goalie";
break;
case 2:playerRoles[playerNum-1] = "Defender #1";
break;
case 3:playerRoles[playerNum-1] = "Defender #2";
break;
case 4:playerRoles[playerNum-1] = "Chaser #1";
break;
case 5:playerRoles[playerNum-1] = "Chaser #2";
break;
}
teamInfo[playerNum-1].setText("Player "+(playerNum)+": "+playerRoles[playerNum-1]);
}
}
JPanel fieldDisplay;
Field f = new Field();
NaoRobot robots[] = new NaoRobot[5];
JPanel accessories;
private JButton flip;
private JButton startWorldView;
private JTextField teamNumberInput;
private JLabel teamInfo[] = new JLabel[5];
private String playerRoles[] = new String[5];
private boolean shouldFlip = false;
private boolean lineColors = false;
private boolean runWorldview = false;
private int teamNumber;
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == flip) {
if(shouldFlip) {
shouldFlip = false;
flip.setText("flip");
} else {
shouldFlip = true;
flip.setText("unflip");
}
}
if(e.getActionCommand() == "Start WorldView") {
runWorldview = true;
if(teamNumberInput.getText() != null) {
try {
teamNumber = Integer.parseInt(teamNumberInput.getText());
startWorldView.setText("Stop");
Debug.info("Now listening to team %s", teamNumber);
} catch(NumberFormatException E) {
E.printStackTrace();
return;
}
Debug.plain("WorldView creating broadcast listener...");
broadcastListener = BroadcastIO.createTBI(this,
BroadcastIO.teamPort(teamNumber));
}
} else if(e.getActionCommand() == "Stop") {
runWorldview = false;
startWorldView.setText("Start WorldView");
Debug.info("Stopped Listening to team %s", teamNumber);
for(int i=0; i<robots.length; i++) {
robots[i] = null;
teamInfo[i].setText("Player "+(i+1)+": Inactive");
}
}
}
}
private WorldView display = null;
@Override
public JFrame supplyDisplay() {
return (display != null) ? display : (display = new WorldView());
}
@Override
public String purpose() {
return "Listen to and display broadcast messages.";
}
@Override
public char preferredMemnonic() {
return 'w';
}
}