package eu.hgross.blaubot.blaubotcam.server.ui;
import java.awt.Dimension;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import eu.hgross.blaubot.blaubotcam.server.model.ImageMessage;
import eu.hgross.blaubot.core.State;
import eu.hgross.blaubot.admin.AbstractAdminMessage;
import eu.hgross.blaubot.admin.CensusMessage;
import eu.hgross.blaubot.messaging.BlaubotMessage;
import eu.hgross.blaubot.messaging.IBlaubotAdminMessageListener;
import eu.hgross.blaubot.messaging.IBlaubotMessageListener;
/**
* Displays ImageMessages.
* Attach it to the channel from where you receive the ImageMessages.
*/
public class VideoViewerPanel extends JScrollPane implements IBlaubotAdminMessageListener, IBlaubotMessageListener {
private static final String LOG_TAG = "VideoViewerPanel";
private final JPanel mMainPanel;
private final JLabel mNoCamsLabel;
/**
* Maps the unique device id to the last received image messages for that device
*/
private ConcurrentHashMap<String, ImageMessage> mLastImageMessages;
/**
* Maps the unique device id to the view, displaying the last image
*/
private ConcurrentHashMap<String, VideoViewerItemPane> mViews;
/**
* The last census message. May be null.
*/
private CensusMessage mLastCensusMessage;
public VideoViewerPanel() {
mViews = new ConcurrentHashMap<>();
mLastImageMessages = new ConcurrentHashMap<>();
mNoCamsLabel = new JLabel("<html>" +
"<h1>Not receiving data</h1>" +
"<p>A kingdom is connected to the server but no device is sending pictures.<br> Click the \"<i>Toggle camera</i>\" button on the devices to start the transmission of camera data.<p>" +
"</html>");
mMainPanel = new JPanel();
mMainPanel.setLayout(new WrapLayout());
mMainPanel.add(mNoCamsLabel);
setHorizontalScrollBarPolicy(HORIZONTAL_SCROLLBAR_NEVER);
setViewportView(mMainPanel);
addComponentListener(new ComponentListener() {
@Override
public void componentResized(ComponentEvent e) {
final Dimension size = e.getComponent().getSize();
// mMainPanel.setSize(size);
// mMainPanel.setPreferredSize(size);
// mMainPanel.setMaximumSize(size);
// mMainPanel.setMinimumSize(size);
}
@Override
public void componentMoved(ComponentEvent e) {
}
@Override
public void componentShown(ComponentEvent e) {
}
@Override
public void componentHidden(ComponentEvent e) {
}
});
}
/**
* updates the ui
*/
private void updateViews() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
final Collection<ImageMessage> values = mLastImageMessages.values();
mNoCamsLabel.setVisible(values.isEmpty());
for (ImageMessage message : values) {
final String uniqueDeviceId = message.getUniqueDeviceId();
boolean added = mViews.putIfAbsent(uniqueDeviceId, new VideoViewerItemPane()) == null;
final VideoViewerItemPane videoViewerItemPane = mViews.get(uniqueDeviceId);
State lastKnownState = null;
if (mLastCensusMessage != null) {
lastKnownState = mLastCensusMessage.getDeviceStates().get(uniqueDeviceId);
}
videoViewerItemPane.setImageMessage(message, lastKnownState);
if (added) {
mMainPanel.add(videoViewerItemPane);
}
}
}
});
}
@Override
public void onMessage(BlaubotMessage blaubotMessage) {
final ImageMessage imageMessage = new ImageMessage(blaubotMessage.getPayload());
mLastImageMessages.put(imageMessage.getUniqueDeviceId(), imageMessage);
updateViews();
}
@Override
public void onAdminMessage(AbstractAdminMessage adminMessage) {
if (adminMessage instanceof CensusMessage) {
mLastCensusMessage = (CensusMessage) adminMessage;
}
}
}