/*
* To change this template, choose Tools | Templates and open the template in
* the editor.
*/
/*
* EmergencyMonitorPanel.java
*
* Created on Apr 28, 2011, 10:43:44 PM
*/
package com.wordpress.salaboy.emergencyservice.monitor;
import com.wordpress.salaboy.context.tracking.ContextTrackingProvider;
import com.wordpress.salaboy.context.tracking.ContextTrackingService;
import com.wordpress.salaboy.emergencyservice.util.AlertsIconListRenderer;
import com.wordpress.salaboy.messaging.MessageConsumerWorker;
import com.wordpress.salaboy.messaging.MessageConsumerWorkerHandler;
import com.wordpress.salaboy.messaging.MessageFactory;
import com.wordpress.salaboy.model.messages.*;
import com.wordpress.salaboy.model.messages.patient.HeartBeatMessage;
import com.wordpress.salaboy.model.messages.patient.PatientMonitorAlertMessage;
import com.wordpress.salaboy.model.persistence.PersistenceService;
import com.wordpress.salaboy.model.persistence.PersistenceServiceProvider;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.UIManager;
import org.hornetq.api.core.HornetQException;
/**
*
* @author esteban
* @author salaboy
*/
public class EmergencyMonitorPanel extends javax.swing.JPanel {
private ImageIcon map;
private MessageConsumerWorker gpsWorker;
private MessageConsumerWorker heartBeatWorker;
private MessageConsumerWorker patientMonitorAlertWorker;
private MessageConsumerWorker vehicleHitsEmergencyWorker;
private MessageConsumerWorker vehicleHitsHospitalWorker;
private MessageConsumerWorker waterTankDecreaseWorker;
private MessageConsumerWorker waterTankIncreaseWorker;
private MessageConsumerWorker waterPumpTiltWorker;
private MessageConsumerWorker outOfWaterWorker;
private MessageConsumerWorker waterRefillWorker;
private String callId;
private List<String> alerts = new ArrayList<String>();
private Map<String, Boolean> vehicleHitEmergency = new HashMap<String, Boolean>();
private Map<String, Boolean> vehicleHitHospital = new HashMap<String, Boolean>();
private final PersistenceService persistenceService;
private final ContextTrackingService trackingService;
private Map<String, FireTruckStatusJPanel> fireTruckPanels = new HashMap<String, FireTruckStatusJPanel>();
private String emergencyId;
/** Creates new form EmergencyMonitorPanel */
public EmergencyMonitorPanel(String callId) throws IOException {
this.callId = callId;
persistenceService = PersistenceServiceProvider.getPersistenceService();
trackingService = ContextTrackingProvider.getTrackingService();
emergencyId = trackingService.getEmergencyAttachedToCall(callId);
initComponents();
loadMapImage();
startQueueListeners();
startPulseEmulator();
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
jPanel2 = new javax.swing.JPanel();
jScrollPane3 = new javax.swing.JScrollPane();
lstAlerts = new javax.swing.JList();
btnClear1 = new javax.swing.JButton();
jEmergencyTabbedPane = new javax.swing.JTabbedPane();
jPanel1 = new javax.swing.JPanel();
lblMap = new javax.swing.JLabel();
btnClear = new javax.swing.JButton();
jPanel3 = new javax.swing.JPanel();
jScrollPane1 = new javax.swing.JScrollPane();
auditLogjTextArea = new javax.swing.JTextArea();
jButton1 = new javax.swing.JButton();
jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Alerts"));
lstAlerts.setPreferredSize(new java.awt.Dimension(200, 0));
jScrollPane3.setViewportView(lstAlerts);
lstAlerts.setCellRenderer(new AlertsIconListRenderer());
btnClear1.setText("Clear");
btnClear1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnClear1ActionPerformed(evt);
}
});
javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
jPanel2.setLayout(jPanel2Layout);
jPanel2Layout.setHorizontalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel2Layout.createSequentialGroup()
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(btnClear1)
.addComponent(jScrollPane3))
.addContainerGap())
);
jPanel2Layout.setVerticalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
.addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 92, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnClear1))
);
jPanel1.setName("GPS"); // NOI18N
jPanel1.setPreferredSize(new java.awt.Dimension(200, 200));
lblMap.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
lblMap.setPreferredSize(new java.awt.Dimension(305, 208));
btnClear.setText("Clear");
btnClear.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnClearActionPerformed(evt);
}
});
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addGap(51, 51, 51)
.addComponent(lblMap, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(jPanel1Layout.createSequentialGroup()
.addGap(161, 161, 161)
.addComponent(btnClear)))
.addContainerGap(108, Short.MAX_VALUE))
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addComponent(lblMap, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnClear)
.addContainerGap())
);
jEmergencyTabbedPane.addTab("GPS", jPanel1);
auditLogjTextArea.setColumns(20);
auditLogjTextArea.setRows(5);
jScrollPane1.setViewportView(auditLogjTextArea);
auditLogjTextArea.setText(persistenceService.loadReport(this.callId).getReportString());
jButton1.setText("Refresh");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
jPanel3.setLayout(jPanel3Layout);
jPanel3Layout.setHorizontalGroup(
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 464, Short.MAX_VALUE)
.addGroup(jPanel3Layout.createSequentialGroup()
.addComponent(jButton1)
.addContainerGap())
);
jPanel3Layout.setVerticalGroup(
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel3Layout.createSequentialGroup()
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 214, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jButton1)
.addContainerGap())
);
jEmergencyTabbedPane.addTab("Live Report", jPanel3);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jEmergencyTabbedPane)
.addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jEmergencyTabbedPane, javax.swing.GroupLayout.PREFERRED_SIZE, 291, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
);
}// </editor-fold>//GEN-END:initComponents
private void btnClear1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnClear1ActionPerformed
this.alerts.clear();
DefaultListModel emptyModel = new DefaultListModel();
this.lstAlerts.setModel(emptyModel);
}//GEN-LAST:event_btnClear1ActionPerformed
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
System.out.println("Get REPORT FOR CALL ID="+this.callId);
auditLogjTextArea.setText(persistenceService.loadReport(this.callId).getReportString());
}//GEN-LAST:event_jButton1ActionPerformed
private void btnClearActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnClearActionPerformed
this.loadMapImage(); }//GEN-LAST:event_btnClearActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JTextArea auditLogjTextArea;
private javax.swing.JButton btnClear;
private javax.swing.JButton btnClear1;
private javax.swing.JButton jButton1;
private javax.swing.JTabbedPane jEmergencyTabbedPane;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2;
private javax.swing.JPanel jPanel3;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane3;
private javax.swing.JLabel lblMap;
private javax.swing.JList lstAlerts;
// End of variables declaration//GEN-END:variables
private void startQueueListeners() {
gpsWorker = new MessageConsumerWorker("vehicleGPS" + callId, new MessageConsumerWorkerHandler<VehicleHitsCornerMessage>() {
@Override
public void handleMessage(VehicleHitsCornerMessage message) {
System.out.println("CallId = "+callId +" -> Vehicle Id= "+message.getVehicleId());
if (message.getEmergencyId().equals(callId)) {
paintVehiclePosition(message.getVehicleId(), message.getCornerX(), message.getCornerY());
}
}
});
heartBeatWorker = new MessageConsumerWorker("vehicleHeartBeat" + callId, new MessageConsumerWorkerHandler<HeartBeatMessage>() {
@Override
public void handleMessage(HeartBeatMessage message) {
if (message.getEmergencyId().equals(emergencyId)) {
processHeartBeat(message.getVehicleId(), message.getHeartBeatValue(), message.getTime());
}
}
});
patientMonitorAlertWorker = new MessageConsumerWorker("patientMonitorAlerts" + callId, new MessageConsumerWorkerHandler<PatientMonitorAlertMessage>() {
@Override
public void handleMessage(PatientMonitorAlertMessage message) {
if (message.getEmergencyId().equals(emergencyId)) {
addAlert(message.getVehicleId(), message.getTime(), message.getMessage());
}
}
});
//Vehicle Hits an Emergency Selected Worker
vehicleHitsEmergencyWorker = new MessageConsumerWorker("vehicleHitsEmergencyMonitorPanel" + callId, new MessageConsumerWorkerHandler<VehicleHitsEmergencyMessage>() {
@Override
public void handleMessage(VehicleHitsEmergencyMessage vehicleHitsEmergencyMessage) {
vehicleHitEmergency.put(vehicleHitsEmergencyMessage.getVehicleId(), Boolean.TRUE);
//ProceduresMGMTService.getInstance().patientPickUpNotification(new PatientPickUpEvent(vehicleHitsEmergencyMessage.getCallId(), vehicleHitsEmergencyMessage.getVehicleId(), vehicleHitsEmergencyMessage.getTime()));
}
});
//Vehicle Hits an Hospital Selected Worker
vehicleHitsHospitalWorker = new MessageConsumerWorker("vehicleHitsHospitalMonitorPanel" + callId, new MessageConsumerWorkerHandler<VehicleHitsHospitalMessage>() {
@Override
public void handleMessage(VehicleHitsHospitalMessage vehicleHitsHospitalMessage) {
vehicleHitHospital.put(vehicleHitsHospitalMessage.getVehicleId(), Boolean.TRUE);
cleanupPanel();
}
});
waterTankDecreaseWorker = new MessageConsumerWorker("FTwaterDecreaseMonitor"+callId, new MessageConsumerWorkerHandler<FireTruckDecreaseWaterLevelMessage>() {
@Override
public void handleMessage(FireTruckDecreaseWaterLevelMessage message) {
if (message.getEmergencyId().equals(emergencyId)) {
getFireTruckPanel(message.getVehicleId()).decreaseWaterLevel();
}
}
});
outOfWaterWorker = new MessageConsumerWorker("FTOutOfWaterMonitor"+callId, new MessageConsumerWorkerHandler<FireTruckOutOfWaterMessage>() {
@Override
public void handleMessage(FireTruckOutOfWaterMessage message) {
if (message.getEmergencyId().equals(emergencyId)) {
getFireTruckPanel(message.getVehicleId()).fireTruckOutOfWater();
}
}
});
waterPumpTiltWorker = new MessageConsumerWorker("FTTiltMonitor"+callId, new MessageConsumerWorkerHandler<FireTruckWaterPumpTiltMessage>() {
@Override
public void handleMessage(FireTruckWaterPumpTiltMessage message) {
if (message.getEmergencyId().equals(emergencyId)) {
getFireTruckPanel(message.getVehicleId()).waterPumpOverHeat();
}
}
});
waterRefillWorker = new MessageConsumerWorker("FTWaterRefillMonitor"+callId, new MessageConsumerWorkerHandler<FireTruckWaterRefilledMessage>() {
@Override
public void handleMessage(FireTruckWaterRefilledMessage message) {
if (message.getEmergencyId().equals(emergencyId)) {
getFireTruckPanel(message.getVehicleId()).waterRefilled();
}
}
});
waterRefillWorker.start();
waterPumpTiltWorker.start();
outOfWaterWorker.start();
waterTankDecreaseWorker.start();
vehicleHitsEmergencyWorker.start();
vehicleHitsHospitalWorker.start();
patientMonitorAlertWorker.start();
gpsWorker.start();
heartBeatWorker.start();
}
private Map<String, Point> lastVehiclePosition = new HashMap<String, Point>();
private Map<String, Color> vehicleColors = new HashMap<String, Color>();
private Color[] colors = {Color.BLUE, Color.YELLOW, Color.RED, Color.GREEN, Color.ORANGE, Color.PINK};
private void paintVehiclePosition(String vehicleId, int x, int y) {
x = x / 2;
y = y / 2;
if (!lastVehiclePosition.containsKey(vehicleId)) {
lastVehiclePosition.put(vehicleId, new Point(x, y));
vehicleColors.put(vehicleId, colors[vehicleColors.size()]);
return;
}
Point lastPoint = lastVehiclePosition.get(vehicleId);
Graphics graphics = lblMap.getGraphics();
graphics.setColor(vehicleColors.get(vehicleId));
graphics.drawLine(lastPoint.x, lastPoint.y, x, y);
lastVehiclePosition.put(vehicleId, new Point(x, y));
}
public void cleanupPanel() {
stopPulseEmulator = true;
if (waterRefillWorker != null) {
waterRefillWorker.stopWorker();
}
if (waterPumpTiltWorker != null) {
waterPumpTiltWorker.stopWorker();
}
if (outOfWaterWorker != null) {
outOfWaterWorker.stopWorker();
}
if (waterTankDecreaseWorker != null) {
waterTankDecreaseWorker.stopWorker();
}
if (vehicleHitsEmergencyWorker != null) {
vehicleHitsEmergencyWorker.stopWorker();
}
if (vehicleHitsHospitalWorker != null) {
vehicleHitsHospitalWorker.stopWorker();
}
if (patientMonitorAlertWorker != null) {
patientMonitorAlertWorker.stopWorker();
}
if (heartBeatWorker != null) {
heartBeatWorker.stopWorker();
}
if (gpsWorker != null) {
gpsWorker.stopWorker();
}
}
private void loadMapImage() {
map = new ImageIcon(this.getClass().getClassLoader().getResource("data/png/CityMap.png"));
this.lblMap.setIcon(map);
}
private Map<String, HeartBeatWidget> heartBeatWidgets = new ConcurrentHashMap<String, HeartBeatWidget>();
private void processHeartBeat(String vehicleId, double heartBeatValue, Date time) {
//only if the vehicle already hit the emergency, but it doesnt
//hit the hospital yet;
Boolean hitEmergency = vehicleHitEmergency.get(vehicleId);
Boolean hitHospital = vehicleHitHospital.get(vehicleId);
if (hitEmergency == null) {
hitEmergency = false;
}
if (hitHospital == null) {
hitHospital = false;
}
if (!hitEmergency) {
return;
}
if (hitHospital) {
return;
}
if (!heartBeatWidgets.containsKey(vehicleId)) {
HeartBeatWidget widget = new HeartBeatWidget();
jEmergencyTabbedPane.add("Ambulance " + vehicleId, widget.getChartPanel());
jEmergencyTabbedPane.setSelectedComponent(widget.getChartPanel());
heartBeatWidgets.put(vehicleId, widget);
}
heartBeatWidgets.get(vehicleId).updateMonitorGraph(heartBeatValue);
}
public void addAlert(String vehicleId, Date time, String message) {
alerts.add(0, vehicleId + " - " + message);
DefaultListModel model = new DefaultListModel();
for (String alert : alerts) {
model.addElement(alert);
}
lstAlerts.setModel(model);
this.validate();
}
private boolean stopPulseEmulator = false;
private void startPulseEmulator() {
new Thread() {
@Override
public void run() {
while (!stopPulseEmulator) {
try {
for (String vehicleId : heartBeatWidgets.keySet()) {
try {
MessageFactory.sendMessage(new HeartBeatMessage(emergencyId, vehicleId, 0, new Date()));
} catch (HornetQException ex) {
Logger.getLogger(EmergencyMonitorPanel.class.getName()).log(Level.SEVERE, null, ex);
}
}
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(EmergencyMonitorPanel.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}.start();
}
private FireTruckStatusJPanel getFireTruckPanel(String vehicleId){
if(fireTruckPanels.get(vehicleId) == null){
FireTruckStatusJPanel fireTruckStatusJPanel = new FireTruckStatusJPanel(this, vehicleId);
fireTruckPanels.put(vehicleId,fireTruckStatusJPanel);
jEmergencyTabbedPane.add(fireTruckStatusJPanel);
jEmergencyTabbedPane.setSelectedComponent(fireTruckStatusJPanel);
}
return fireTruckPanels.get(vehicleId);
}
}