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 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){} } // 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); } } // // public void status(LightStuds svgDevice, SVGElement element) { int circuitNumber = element.getPresAbsolute("art.lightstuds.circuit").getIntValue(); Optional 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); } } // // 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); } // // 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 } // 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 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 lMessage; private long currentMessageTimestamp = 0; private VmsGeneralStatusMessage currentMessage; public Optional getNextMessage(List currentMessages) { checkMessageList(currentMessages); Optional 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 currentMessages) { try { if (!Serialization.equals(currentMessages, lMessage)) { lMessage = currentMessages; currentMessage = null; } } catch (Exception ex){} } } // }