package art.client.maps;
|
|
import art.client.models.Shared;
|
import art.library.interop.serialization.Serialization;
|
import art.library.model.devices.Device;
|
import art.library.model.devices.DeviceGraphicsRuntime;
|
import art.library.model.devices.DeviceStatus;
|
import art.library.model.devices.lighting.lightstuds.LightStuds;
|
import art.library.model.devices.lighting.lightstuds.status.LightStudsStatus_BUSVAO_Circuit;
|
import art.library.model.devices.vms.asf.Asf;
|
import art.library.model.devices.vms.asf.AsfStatus;
|
import art.library.model.devices.vms.general.VmsGeneral;
|
import art.library.model.devices.vms.general.status.VmsGeneralStatusMessage;
|
import art.library.model.devices.vms.pvv.Pvv;
|
import art.library.model.devices.vms.pvv.PvvAlarms;
|
import art.library.model.devices.vms.pvv.PvvStatus;
|
import static art.library.utils.ArticScalableVectorGraphics.getBoundingBox;
|
import art.library.vmsboard.BoardDocument;
|
import com.kitfox.svg.*;
|
import java.awt.Graphics2D;
|
import java.awt.Image;
|
import java.awt.RenderingHints;
|
import java.awt.Shape;
|
import java.awt.image.BufferedImage;
|
import java.lang.reflect.Method;
|
import java.util.*;
|
|
public class BUSVAO extends DeviceGraphicsRuntime
|
{
|
|
private final HashMap<SVGElement, Runnable> mapRunnableElements = new HashMap();
|
|
public BUSVAO(SVGDiagram diagram)
|
{
|
super(diagram);
|
}
|
|
|
public Device getMockedDevice()
|
{
|
Asf asf = new Asf("mock");
|
|
asf.getDeviceStatus().state = AsfStatus.STATE_OFF;
|
|
return asf;
|
}
|
|
|
public void status()
|
{
|
getElementsContainingField("art.device").stream().forEach(this::refreshElement);
|
}
|
|
private void refreshElement(SVGElement element)
|
{
|
try
|
{
|
if (!mapRunnableElements.containsKey(element))
|
{
|
// Device device = Shared.model.modelDevices.getDevice(getAttribute(element, "art.device"));
|
Device device = getMockedDevice();
|
Method method = this.getClass().getMethod("status", device.getClass(), SVGElement.class);
|
|
mapRunnableElements.put(element, () ->
|
{
|
try
|
{
|
method.invoke(this, device, element);
|
}
|
catch (Exception ex){}
|
});
|
}
|
|
mapRunnableElements.get(element).run();
|
}
|
catch (Exception e){}
|
}
|
|
//<editor-fold defaultstate="collapsed" desc="PVV">
|
public void status(Pvv svgDevice, SVGElement element)
|
{
|
PvvStatus status = svgDevice.getDeviceStatus();
|
PvvAlarms alarms = svgDevice.getDeviceAlarms();
|
|
SVGElement background = getChildContainingField(element, "art.id", "Background");
|
SVGElement border = getChildContainingField(element, "art.id", "Border");
|
SVGElement alarm = getChildContainingField(element, "art.id", "Alarm");
|
SVGElement textUnder100 = getChildContainingField(element, "art.id", "Text1");
|
SVGElement textOver100 = getChildContainingField(element, "art.id", "Text2");
|
|
setAttribute(textUnder100, "display", "none", 999);
|
setAttribute(textOver100, "display", "none", 999);
|
setAttribute(alarm, "display", "inline", 999);
|
setAttribute(alarm, "stroke", "#FF0000", 999);
|
|
setAttribute(background, "fill", "#FF00FF");
|
setAttribute(border, "stroke", "#800080");
|
|
setAttribute(alarm, "stroke-width", alarms.getServerityAlarm());
|
setAttribute(background, "fill", getGenericDualStatusColor(status.status)[0]);
|
setAttribute(border, "stroke", getGenericDualStatusColor(status.status)[1]);
|
|
if (status.state != PvvStatus.STATE_OFF)
|
{
|
SVGElement textObject = status.speed >= 100 ? textOver100 : textUnder100;
|
setText(textObject, String.valueOf(status.speed));
|
setAttribute(textObject, "display", "inline", 999);
|
}
|
|
}
|
//</editor-fold>
|
|
//<editor-fold defaultstate="collapsed" desc="LightStuds">
|
public void status(LightStuds svgDevice, SVGElement element)
|
{
|
int circuitNumber = element.getPresAbsolute("art.lightstuds.circuit").getIntValue();
|
Optional<LightStudsStatus_BUSVAO_Circuit> circuitOpt = svgDevice.getDeviceStatus().BUSVAO.circuits.stream()
|
.filter(circuit -> circuit.number == circuitNumber)
|
.findAny();
|
setAttribute(element, "fill", "#FF00FF", 999);
|
setAttribute(element, "stroke-width", svgDevice.getServerityAlarm() > 0 ? 0.2f : 0, 999);
|
if (circuitOpt.isPresent())
|
{
|
setAttribute(element, "fill", circuitOpt.get().status == LightStudsStatus_BUSVAO_Circuit.STATUS_ON ? "#00FF00" : "#EAEAEA", 999);
|
}
|
}
|
//</editor-fold>
|
|
//<editor-fold defaultstate="collapsed" desc="ASF">
|
public void status(Asf svgDevice, SVGElement element) throws Exception
|
{
|
AsfStatus status = svgDevice.getDeviceStatus();
|
|
SVGElement alarm = getChildContainingField(element, "art.id", "Alarm");
|
SVGElement border = getChildContainingField(element, "art.id", "Border");
|
SVGElement background = getChildContainingField(element, "art.id", "Background");
|
SVGElement arrow = getChildContainingField(element, "art.id", "Arrow");
|
SVGElement cross = getChildContainingField(element, "art.id", "Cross");
|
SVGElement right = getChildContainingField(element, "art.id", "Right");
|
SVGElement left = getChildContainingField(element, "art.id", "Left");
|
SVGElement textBUS = getChildContainingField(element, "art.id", "textBUS");
|
SVGElement left_lane_closed = getChildContainingField(element, "art.id", "left_lane_closed");
|
|
setAttribute(alarm, "display", "none", 999);
|
setAttribute(arrow, "display", "none", 999);
|
setAttribute(cross, "display", "none", 999);
|
setAttribute(right, "display", "none", 999);
|
setAttribute(left, "display", "none", 999);
|
setAttribute(textBUS, "display", "none", 999);
|
|
try
|
{
|
setAttribute(left_lane_closed, "display", "none", 999);
|
} catch (Exception ex){}
|
|
boolean knownStatus = status.status != DeviceStatus.STATUS_OFFLINE && status.status != DeviceStatus.STATUS_UNKNOWN;
|
|
if (knownStatus)
|
{
|
setAttribute(arrow, "display", status.state == AsfStatus.STATE_ARROW ? "inline" : "none", 999);
|
setAttribute(cross, "display", status.state == AsfStatus.STATE_CROSS ? "inline" : "none", 999);
|
setAttribute(right, "display", status.state == AsfStatus.STATE_RIGHT ? "inline" : "none", 999);
|
setAttribute(left, "display", status.state == AsfStatus.STATE_LEFT ? "inline" : "none", 999);
|
setAttribute(textBUS, "display", status.state == AsfStatus.STATE_BUS ? "inline" : "none", 999);
|
|
if(status.state == AsfStatus.STATE_S52_LEFT)
|
{
|
setAttribute(left_lane_closed, "display", "inline", 999);
|
}
|
|
}
|
|
String colorBackground = "#000000";
|
String colorAlarm = "#000000";
|
|
switch (status.status)
|
{
|
case DeviceStatus.STATUS_ALARM:
|
colorAlarm = "#FF0000";
|
break;
|
case DeviceStatus.STATUS_OFFLINE:
|
case DeviceStatus.STATUS_UNKNOWN:
|
colorBackground = "#FF00FF";
|
colorAlarm = "#800080";
|
break;
|
}
|
|
setAttribute(border, "stroke", colorAlarm, 999);
|
setAttribute(background, "fill", colorBackground, 999);
|
}
|
//</editor-fold>
|
|
//<editor-fold defaultstate="collapsed" desc="VmsGeneral">
|
public void status(VmsGeneral svgDevice, SVGElement element) throws Exception
|
{
|
SVGElement background = getChildContainingField(element, "art.id", "Background");
|
SVGElement alarm = getChildContainingField(element, "art.id", "Alarm");
|
|
String backGroundColor = "#000000";
|
String alarmColor = "#00FF00";
|
|
switch (svgDevice.getDeviceStatus().status)
|
{
|
case DeviceStatus.STATUS_ALARM:
|
alarmColor = "#FF0000";
|
break;
|
case DeviceStatus.STATUS_OFFLINE:
|
case DeviceStatus.STATUS_UNKNOWN:
|
backGroundColor = "#FF00FF";
|
alarmColor = "#800080";
|
break;
|
}
|
|
setAttribute(background, "fill", backGroundColor, 999);
|
setAttribute(alarm, "stroke", alarmColor, 999);
|
|
//TODO SET PANEL IMAGES
|
}
|
//</editor-fold>
|
|
private static String[] getGenericDualStatusColor(int status)
|
{
|
String color1 = "#FF00FF";
|
String color2 = "#7C007C";
|
|
switch (status)
|
{
|
case DeviceStatus.STATUS_ONLINE:
|
color1 = "#00FF00";
|
color2 = "#007C00";
|
break;
|
case DeviceStatus.STATUS_WARNING:
|
color1 = "#FFFF00";
|
color2 = "#7C7C00";
|
break;
|
case DeviceStatus.STATUS_ALARM:
|
color1 = "#FF0000";
|
color2 = "#7C0000";
|
break;
|
case DeviceStatus.STATUS_INVALID:
|
color1 = "#B97A57";
|
color2 = "#5A3B2A";
|
break;
|
case DeviceStatus.STATUS_DISABLE:
|
color1 = "#7C7C7C";
|
color2 = "#3E3E3E";
|
break;
|
case DeviceStatus.STATUS_SIMULATION:
|
color1 = "#0000FF";
|
color2 = "#00007C";
|
break;
|
case DeviceStatus.STATUS_OFFLINE:
|
color1 = "#FF00FF";
|
color2 = "#7C007C";
|
break;
|
case DeviceStatus.STATUS_UNKNOWN:
|
color1 = "#FF00FF";
|
color2 = "#7C007C";
|
break;
|
}
|
|
return new String[]
|
{
|
color1, color2
|
};
|
}
|
|
private final HashMap<String,VmsMessageStorage> mapMessages = new HashMap<>();
|
|
public void paint(Graphics2D g2)
|
{
|
for (SVGElement element : getElementsContainingField("art.device"))
|
{
|
try
|
{
|
Device device = Shared.model.modelDevices.getDevice(getAttribute(element, "art.device"));
|
|
if (device instanceof VmsGeneral)
|
{
|
if(element.getStyleAbsolute("display").getStringValue().equals("none"))
|
continue;
|
|
VmsGeneral vms = (VmsGeneral) device;
|
|
VmsMessageStorage storemessage = new VmsMessageStorage();
|
|
if(!mapMessages.containsKey(vms.getIdentifier()))
|
mapMessages.put(vms.getIdentifier(),storemessage);
|
|
VmsMessageStorage messageStore = mapMessages.get(vms.getIdentifier());
|
|
SVGElement background = getChildContainingField(element, "art.id", "Background");
|
Shape shape = getBoundingBox(background);
|
|
double w = shape.getBounds2D().getWidth() * g2.getTransform().getScaleX();
|
double h = shape.getBounds2D().getHeight() * g2.getTransform().getScaleY();
|
|
|
messageStore.getNextMessage(vms.getDeviceStatus().lmessage).ifPresent(message ->
|
{
|
BoardDocument document = message.document;
|
|
boolean width = w < document.width * 1.25f;
|
boolean height = h < document.height * 1.25f;
|
|
if (width || height)
|
{
|
BufferedImage image = document.getBufferedImage();
|
g2.drawImage(image.getScaledInstance((int) shape.getBounds2D().getWidth(), (int) shape.getBounds2D().getHeight(), Image.SCALE_SMOOTH), (int) shape.getBounds2D().getX(), (int) shape.getBounds2D().getY(), null);
|
}
|
else
|
{
|
BufferedImage image = document.getRealisticImage((int)shape.getBounds2D().getWidth(), (int)shape.getBounds2D().getHeight(), true);
|
|
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
g2.drawImage(image, (int) shape.getBounds2D().getX(), (int) shape.getBounds2D().getY(), null);
|
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
|
|
}
|
});
|
}
|
}
|
catch (Exception exception)
|
{
|
|
}
|
|
}
|
}
|
|
|
|
public class VmsMessageStorage
|
{
|
private List<VmsGeneralStatusMessage> lMessage;
|
private long currentMessageTimestamp = 0;
|
private VmsGeneralStatusMessage currentMessage;
|
|
public Optional<VmsGeneralStatusMessage> getNextMessage(List<VmsGeneralStatusMessage> currentMessages)
|
{
|
checkMessageList(currentMessages);
|
|
Optional<VmsGeneralStatusMessage> messageOpt = Optional.empty();
|
|
if(lMessage == null || lMessage.isEmpty())
|
return messageOpt;
|
|
if(currentMessage == null)
|
{
|
messageOpt = Optional.of(lMessage.get(0));
|
currentMessageTimestamp = System.currentTimeMillis();
|
currentMessage = messageOpt.get();
|
}
|
else
|
{
|
if((System.currentTimeMillis() - currentMessageTimestamp) >= currentMessage.time * 1000)
|
{
|
currentMessageTimestamp = System.currentTimeMillis();
|
|
int messageIndex = lMessage.indexOf(currentMessage);
|
|
int nextIndex = messageIndex >= lMessage.size() - 1 ? 0 : messageIndex + 1 ;
|
|
currentMessage = lMessage.get(nextIndex);
|
}
|
|
messageOpt = Optional.of(currentMessage);
|
}
|
|
return messageOpt;
|
}
|
|
private void checkMessageList(List<VmsGeneralStatusMessage> currentMessages)
|
{
|
try
|
{
|
if (!Serialization.equals(currentMessages, lMessage))
|
{
|
lMessage = currentMessages;
|
currentMessage = null;
|
}
|
}
|
catch (Exception ex){}
|
}
|
}
|
//</editor-fold>
|
|
}
|