package org.lucci.madhoc.gui.aircraft;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.Vector;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.lucci.config.ConfigurationException;
import org.lucci.madhoc.env.NetworkEnvironment;
import org.lucci.madhoc.gui.MonitorView;
import org.lucci.madhoc.network.Connection;
import org.lucci.madhoc.network.Network;
import org.lucci.madhoc.network.Station;
import org.lucci.madhoc.network.net.Location;
import org.lucci.madhoc.simulation.Monitor;
import org.lucci.text.TextUtilities;
import org.lucci.up.FilePlotter;
import org.lucci.up.InteractiveSwingPlotterListener;
import org.lucci.up.SwingPlotter;
import org.lucci.up.data.Figure;
import org.lucci.up.data.Point;
import org.lucci.up.data.rendering.DataElementRenderer;
import org.lucci.up.data.rendering.figure.FigureRenderer;
import org.lucci.up.data.rendering.point.PointRenderer;
import org.lucci.up.data.rendering.point.PolygoneRenderer;
public class AircraftView extends MonitorView implements ChangeListener
{
class UpRendererRenderer extends DefaultListCellRenderer
{
public Component getListCellRendererComponent(JList arg0, Object renderer, int arg2, boolean arg3, boolean arg4)
{
JLabel l = (JLabel) super.getListCellRendererComponent(arg0, renderer, arg2, arg3, arg4);
String s = ((DataElementRenderer) renderer).getPublicName();
s = TextUtilities.capitalize(s);
l.setText(s);
return l;
}
}
private Collection<PointRenderer> availableStationRenderers = new Vector<PointRenderer>();
private Collection<PointRenderer> availableCoverageRenderers = new Vector<PointRenderer>();
private Collection<FigureRenderer> availableConnectionRenderers = new Vector<FigureRenderer>();
private Collection<PointRenderer> activeStationRenderers = new Vector<PointRenderer>();
private Collection<PointRenderer> activeCoverageRenderers = new Vector<PointRenderer>();
private Collection<FigureRenderer> activeConnectionRenderers = new Vector<FigureRenderer>();
private OutOfProjectionComputerRenderer outOfProjectionComputerRenderer = new OutOfProjectionComputerRenderer ();
private OutOfProjectionConnectionRenderer outOfProjectionConnectionRenderer = new OutOfProjectionConnectionRenderer();
private File imageDirectory;
private AirCraftViewPlotter plotter;
private JTabbedPane tabbedPane = new JTabbedPane();
private JCheckBox drawGridCheckbox = new JCheckBox("Draw grid", true);
private JCheckBox drawEnvCheckbox = new JCheckBox("Draw environment", false);
private JCheckBox drawOutOfProjectionStations = new JCheckBox("Draw out of projection computers", false);
private JCheckBox drawOutOfProjectionConnections = new JCheckBox("Draw out of projection connections", false);
private JCheckBox drawConnectionsIfUsedCheckbox = new JCheckBox("Show only connections in use", false);
private JComboBox computersRendererCombobox = new JComboBox();
private JComboBox coverageRendereCombobox = new JComboBox();
private JComboBox connectionRendererCombobox;
private JLabel descriptionLabel;
private Collection<StationDescriptionPane> stationDescriptionPanes;
private String fileExtension;
public void setMonitor(Monitor application)
{
super.setMonitor(application);
setPreferredHeight(2);
getAvailableStationRenderers().add(new BlackStationRenderer());
getAvailableStationRenderers().add(new BlackPointStationRenderer());
getAvailableStationRenderers().add(new GrayStationRenderer());
getAvailableStationRenderers().add(new ImageStationRenderer());
getAvailableStationRenderers().add(new NoComputerRendering());
getAvailableStationRenderers().add(new PolygoneRenderer());
getAvailableConnectionRenderers().add(new GreyAndBlackIfUsedConnectionRenderer());
getAvailableConnectionRenderers().add(new BlackConnectionRenderer());
getAvailableConnectionRenderers().add(new AutomaticConnectionRenderer());
getAvailableConnectionRenderers().add(new ConnectionTypeRenderer());
getAvailableConnectionRenderers().add(new ConnectionQualityRenderer());
getAvailableConnectionRenderers().add(new ConnectionLoadRatioRenderer());
getAvailableConnectionRenderers().add(new NoConnectionRenderering());
getAvailableCoverageRenderers().add(new NoComputerRendering());
getAvailableCoverageRenderers().add(new CircleSignalRenderer());
getAvailableCoverageRenderers().add(new FilledCircleSignalRenderer());
setLayout(new BorderLayout());
{
JPanel p = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
plotter = new AirCraftViewPlotter(this);
p.add(plotter, c);
add(p, BorderLayout.CENTER);
}
{
JPanel p = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
tabbedPane.addTab("Control", createControlPane());
descriptionLabel = new JLabel();
try
{
this.stationDescriptionPanes = (Collection<StationDescriptionPane>) application.getNetwork().getSimulation().getConfiguration().getInstantiatedClasses("aircraft_view_description_panes");
for (StationDescriptionPane label : this.stationDescriptionPanes)
{
tabbedPane.addTab(label.getPublicName(), new JScrollPane(label.getLabel()));
}
}
catch (ConfigurationException e)
{
e.printStackTrace();
}
p.add(tabbedPane, c);
add(p, BorderLayout.EAST);
}
plotter.getListeners().add(new SwingPlotterHandler());
connectionRendererCombobox.setSelectedIndex(0);
computersRendererCombobox.setSelectedIndex(0);
}
private JPanel createControlPane()
{
JPanel controlPanel = new JPanel(new GridBagLayout());
controlPanel.setBorder(new TitledBorder("Draw..."));
{
drawGridCheckbox.addChangeListener(this);
GridBagConstraints c = new GridBagConstraints();
c.gridy = 0;
c.insets = new Insets(30, 0, 0, 0);
c.anchor = GridBagConstraints.WEST;
controlPanel.add(drawGridCheckbox, c);
}
{
drawEnvCheckbox.addChangeListener(this);
GridBagConstraints c = new GridBagConstraints();
c.gridy = 1;
c.insets = new Insets(0, 0, 0, 0);
c.anchor = GridBagConstraints.WEST;
controlPanel.add(drawEnvCheckbox, c);
}
{
drawOutOfProjectionStations.addChangeListener(this);
GridBagConstraints c = new GridBagConstraints();
c.gridy = 2;
c.insets = new Insets(0, 0, 0, 0);
c.anchor = GridBagConstraints.WEST;
controlPanel.add(drawOutOfProjectionStations, c);
}
{
drawOutOfProjectionConnections.addChangeListener(this);
GridBagConstraints c = new GridBagConstraints();
c.gridy = 3;
c.insets = new Insets(0, 0, 15, 0);
c.anchor = GridBagConstraints.WEST;
controlPanel.add(drawOutOfProjectionConnections, c);
}
{
GridBagConstraints c = new GridBagConstraints();
c.gridy = 4;
c.insets = new Insets(15, 0, 0, 0);
c.anchor = GridBagConstraints.WEST;
controlPanel.add(new JLabel("Render nodes using:"), c);
}
{
GridBagConstraints c = new GridBagConstraints();
c.gridy = 5;
c.insets = new Insets(0, 0, 15, 0);
c.anchor = GridBagConstraints.EAST;
computersRendererCombobox = new JComboBox();
computersRendererCombobox.setRenderer(new UpRendererRenderer());
for (PointRenderer renderer : getAvailableStationRenderers())
{
computersRendererCombobox.addItem(renderer);
}
computersRendererCombobox.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
updateViewContent();
}
});
controlPanel.add(computersRendererCombobox, c);
}
{
GridBagConstraints c = new GridBagConstraints();
c.gridy = 6;
c.insets = new Insets(15, 0, 0, 0);
c.anchor = GridBagConstraints.WEST;
controlPanel.add(new JLabel("Render connections using:"), c);
}
{
GridBagConstraints c = new GridBagConstraints();
c.gridy = 7;
c.anchor = GridBagConstraints.EAST;
connectionRendererCombobox = new JComboBox();
computersRendererCombobox.setRenderer(new UpRendererRenderer());
for (FigureRenderer renderer : getAvailableConnectionRenderers())
{
connectionRendererCombobox.addItem(renderer);
}
connectionRendererCombobox.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
updateViewContent();
}
});
controlPanel.add(connectionRendererCombobox, c);
}
{
drawConnectionsIfUsedCheckbox.addChangeListener(this);
GridBagConstraints c = new GridBagConstraints();
c.gridy = 8;
c.anchor = GridBagConstraints.WEST;
c.insets = new Insets(0, 10, 15, 0);
controlPanel.add(drawConnectionsIfUsedCheckbox, c);
}
{
GridBagConstraints c = new GridBagConstraints();
c.gridy = 9;
c.insets = new Insets(15, 0, 0, 0);
c.anchor = GridBagConstraints.WEST;
controlPanel.add(new JLabel("Render radio signal using:"), c);
}
{
GridBagConstraints c = new GridBagConstraints();
c.gridy = 10;
c.insets = new Insets(0, 0, 15, 0);
c.anchor = GridBagConstraints.EAST;
coverageRendereCombobox = new JComboBox();
computersRendererCombobox.setRenderer(new UpRendererRenderer());
Iterator iterator = getAvailableCoverageRenderers().iterator();
while (iterator.hasNext())
{
coverageRendereCombobox.addItem(iterator.next());
}
coverageRendereCombobox.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
updateViewContent();
}
});
controlPanel.add(coverageRendereCombobox, c);
}
return controlPanel;
}
public AirCraftViewPlotter getPlotter()
{
return plotter;
}
public String getName()
{
return "Aircraft view";
}
public void updateViewContent()
{
getActiveStationRenderers().clear();
getActiveStationRenderers().addAll(new Vector(Arrays.asList(computersRendererCombobox.getSelectedObjects())));
getActiveConnectionRenderers().clear();
getActiveConnectionRenderers().addAll(new Vector(Arrays.asList(connectionRendererCombobox.getSelectedObjects())));
getActiveCoverageRenderers().clear();
getActiveCoverageRenderers().addAll(new Vector(Arrays.asList(coverageRendereCombobox.getSelectedObjects())));
plotter.setUpdateNeeded(true);
plotter.repaint(0);
if (fileExtension != null)
{
int imageNumber = getMonitor().getNetwork().getSimulation().getIteration();
String imageNumberString = TextUtilities.flushRight("" + imageNumber, 4, '0');
String filename = this.imageDirectory + File.separator + imageNumberString + "." + fileExtension;
File file = new File(filename);
System.out.println("Writing " + filename);
FilePlotter filePlotter = new FilePlotter();
filePlotter.setGraphics2DPlotter(plotter.getGraphics2DPlotter());
Dimension dimension = plotter.getSize();
if (dimension.width > 0 && dimension.height > 0)
{
try
{
filePlotter.plotFile(file, dimension.width, dimension.height);
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
public Figure createNetworkFigure(Network network)
{
Figure figure = new Figure();
if (drawEnvCheckbox.isSelected())
{
figure.addFigure(createEnvFigure(network));
}
for (Station computer : network.getStations())
{
Location p = computer.getLocation();
p.removeAllRenderers();
}
figure.addFigure(createCoverageFigure(network));
figure.addFigure(createConnectionFigure(network));
figure.addFigure(createComputersFigure(network));
return figure;
}
private Figure createEnvFigure(Network network)
{
NetworkEnvironment env = network.getNetworkEnvironment();
return env.createFigure(getPlotter().getGraphics2DPlotter().getSpace());
}
private Figure createConnectionFigure(Network network)
{
Figure allConnectionsFigure = new Figure();
Iterator connectionIterator = network.findConnections().iterator();
while (connectionIterator.hasNext())
{
Connection connection = (Connection) connectionIterator.next();
if (connection.getUsedBandwith() > 0 || !drawConnectionsIfUsedCheckbox.isSelected())
{
ConnectionFigure figure = new ConnectionFigure();
figure.setConnection(connection);
figure.addPoint(connection.getNetworkInterface1().getNetworkingUnit().getStation().getLocation());
figure.addPoint(connection.getNetworkInterface2().getNetworkingUnit().getStation().getLocation());
if (getProjectionComponent().getProjection().acceptConnection(connection))
{
Iterator rendererIterator = getActiveConnectionRenderers().iterator();
while (rendererIterator.hasNext())
{
figure.addRenderer((DataElementRenderer) rendererIterator.next());
}
}
else
{
if (drawOutOfProjectionConnections.isSelected())
{
figure.addRenderer(outOfProjectionConnectionRenderer);
}
}
allConnectionsFigure.addFigure(figure);
}
}
return allConnectionsFigure;
}
private Figure createComputersFigure(Network network)
{
Figure vehiclesFigure = new Figure();
Iterator stationIterator = network.getStations().iterator();
while (stationIterator.hasNext())
{
Station computer = (Station) stationIterator.next();
Location p = computer.getLocation();
vehiclesFigure.addPoint(p);
Iterator rendererIterator = getActiveStationRenderers().iterator();
if (getProjectionComponent().getProjection().acceptComputer(computer))
{
while (rendererIterator.hasNext())
{
p.addRenderer((PointRenderer) rendererIterator.next());
}
}
else
{
if (drawOutOfProjectionStations.isSelected())
{
p.addRenderer(outOfProjectionComputerRenderer);
}
}
}
return vehiclesFigure;
}
private Figure createCoverageFigure(Network network)
{
Figure coverageFigure = new Figure();
Iterator networkNodeIterator = network.getStations().iterator();
while (networkNodeIterator.hasNext())
{
Station station = (Station) networkNodeIterator.next();
Location p = station.getLocation();
coverageFigure.addPoint(p);
if (getProjectionComponent().getProjection().acceptComputer(station))
{
Iterator rendererIterator = getActiveCoverageRenderers().iterator();
while (rendererIterator.hasNext())
{
p.addRenderer((PointRenderer) rendererIterator.next());
}
}
}
return coverageFigure;
}
private class SwingPlotterHandler implements InteractiveSwingPlotterListener
{
public void pointsSelected(SwingPlotter sp, Collection points)
{
if (points.size() == 1)
{
Point p = (Point) points.iterator().next();
if (p instanceof Location)
{
Location point = (Location) p;
Station computer = point.getComputer();
for (StationDescriptionPane sdp : AircraftView.this.stationDescriptionPanes)
{
sdp.getLabel().setText(sdp.getDescriptionForStation(computer));
}
}
}
}
public void paintStarting(SwingPlotter sp)
{
}
public void paintFinished(SwingPlotter sp)
{
}
}
public void iterationScopedValuesReinitializationRequired()
{
}
public Collection<PointRenderer> getActiveStationRenderers()
{
return activeStationRenderers;
}
public Collection<FigureRenderer> getAvailableConnectionRenderers()
{
return availableConnectionRenderers;
}
public Collection<FigureRenderer> getActiveConnectionRenderers()
{
return activeConnectionRenderers;
}
public Collection<PointRenderer> getActiveCoverageRenderers()
{
return activeCoverageRenderers;
}
public void setActiveStationRenderers(Collection<PointRenderer> activeStationRenderers)
{
this.activeStationRenderers = activeStationRenderers;
}
public Collection<PointRenderer> getAvailableCoverageRenderers()
{
return availableCoverageRenderers;
}
public Collection<PointRenderer> getAvailableStationRenderers()
{
return availableStationRenderers;
}
public void stateChanged(ChangeEvent arg0)
{
getPlotter().getGraphics2DPlotter().getSpace().setVisible(drawGridCheckbox.isSelected());
updateViewContent();
}
public void configure() throws Throwable
{
if (getMonitor().getNetwork().getSimulation().getConfiguration().getBoolean("write_aircraft_views_files"))
{
this.fileExtension = getMonitor().getNetwork().getSimulation().getConfiguration().getString("aircraft_views_file_extension");
this.imageDirectory = new File(getMonitor().getNetwork().getSimulation().getConfiguration().getString("aircraft_views_image_directory"));
if (this.imageDirectory.isFile())
{
throw new ConfigurationException("aircraft_views_image_directory", this.imageDirectory.getAbsolutePath() + " is not a directory, it is a regular file");
}
else
{
if (!this.imageDirectory.exists())
{
this.imageDirectory.mkdirs();
}
}
}
else
{
this.fileExtension = null;
}
}
}