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.barrier.Barrier;
import art.library.model.devices.barrier.BarrierAlarms;
import art.library.model.devices.barrier.BarrierRealtime;
import art.library.model.devices.barrier.BarrierStatus;
import art.library.model.devices.barrier.realtime.BarrierRealtimeITC;
import art.library.model.devices.signalsboard.SignalsBoard;
import art.library.model.devices.signalsboard.status.SignalStatus;
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 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.text.DecimalFormat;
import java.util.*;
import java.util.stream.Stream;
public class LaGoleta extends DeviceGraphicsRuntime
{
private boolean even = false;
private final DecimalFormat decimalFormat = new DecimalFormat("0.00");
private final Class[] ldeviceClasses = new Class[]
{
SignalsBoard.class,
Asf.class,
Barrier.class,
VmsGeneral.class,
};
public LaGoleta (SVGDiagram diagram)
{
super(diagram);
}
public void status()
{
Calendar calendardate = java.util.Calendar.getInstance();
calendardate.set(java.util.Calendar.MILLISECOND, 0);
long seconds = calendardate.getTimeInMillis() / 1000;
even = (seconds % 2) == 0;
for (SVGElement element : getElementsContainingField("art.device"))
{
try
{
for (Class deviceClass : ldeviceClasses)
{
if (Shared.model.modelDevices.getDevice(getAttribute(element, "art.device")).getClassName().equals(deviceClass.getName()))
{
this.getClass()
.getMethod("status", deviceClass, SVGElement.class)
.invoke(this, Shared.model.modelDevices.getDevice(getAttribute(element, "art.device")), element);
break;
}
}
} catch (Exception e){}
}
}
//
public void status(SignalsBoard svgDevice, SVGElement element)
{
String[] signals = getAttribute(element, "art.device.signal").contains(";")
? getAttribute(element, "art.device.signal").split(";")
: new String[] {getAttribute(element, "art.device.signal")} ;
if (signals.length > 0)
{
System.out.println("<
//
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");
setAttribute(arrow, "display", "none", 999);
setAttribute(cross, "display", "none", 999);
setAttribute(right, "display", "none", 999);
setAttribute(left, "display", "none", 999);
boolean knownStatus = status.state != DeviceStatus.STATUS_OFFLINE && status.state != 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);
}
String colorBackground = "#000000";
String colorAlarm = "#FF0000";
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
}
//element,"art.id",
//
public void status(Barrier svgDevice, SVGElement element) throws Exception //BARRIER
{
BarrierRealtimeITC realtime = ((BarrierRealtime) device.getDeviceRealtime()).itc;
{
barrierStatus(element, realtime);
semaphoreStatus(element, realtime);
roadSensor(element, realtime);
}
barierDeviceStatus(element,svgDevice.getDeviceStatus());
barrierAlarms(element, svgDevice.getDeviceAlarms());
}
private void barrierStatus(SVGElement element, BarrierRealtimeITC realtimeItc)
{
SVGElement[] barrierElements = new SVGElement[]
{
getChildContainingField(element,"art.id","Barrier.Opened"),
getChildContainingField(element,"art.id","Barrier.Closed"),
getChildContainingField(element,"art.id","Barrier.Closing"),
getChildContainingField(element,"art.id","Barrier.Opening"),
getChildContainingField(element,"art.id","Barrier.Locked")
};
Stream.of(barrierElements).forEach(svgElement -> setAttribute(svgElement, "display", "none", 999));
SVGElement elementToShow = null;
switch (realtimeItc.position)
{
case BarrierRealtimeITC.POSITION_UP: elementToShow = barrierElements[0]; break;
case BarrierRealtimeITC.POSITION_DOWN: elementToShow = barrierElements[1]; break;
case BarrierRealtimeITC.POSITION_CLOSING: elementToShow = barrierElements[2]; break;
case BarrierRealtimeITC.POSITION_OPENING: elementToShow = barrierElements[3]; break;
}
if(elementToShow != null)
setAttribute(elementToShow, "display", "inline", 999);
if(realtimeItc.lock == BarrierRealtimeITC.LOCK_LOCK)
setAttribute(barrierElements[4], "display", "inline", 999);
}
private void roadSensor(SVGElement element, BarrierRealtimeITC realtimeItc)
{
SVGElement loop1 = getChildContainingField(element,"art.id","Loop1");
SVGElement loop2 = getChildContainingField(element,"art.id","Loop2");
setAttribute(loop1, "fill", "#E0E0E0");
setAttribute(loop2,"fill", "#E0E0E0");
if (realtimeItc.loopInput == BarrierRealtimeITC.LOOP_ACTIVE)
setAttribute(loop1, "fill", "#ffff0080");
if (realtimeItc.loopOutput == BarrierRealtimeITC.LOOP_ACTIVE)
setAttribute(loop2, "fill", "#ffff0080");
}
private void semaphoreStatus(SVGElement element, BarrierRealtimeITC realtimeItc)
{
SVGElement semaphoreRed = getChildContainingField(element,"art.id","Sempahore.Red");
SVGElement semaphoreYellow = getChildContainingField(element,"art.id","Sempahore.Yellow");
SVGElement semaphoreGreen = getChildContainingField(element,"art.id","Sempahore.Green");
setAttribute(semaphoreGreen, "fill", "#000000",999);
setAttribute(semaphoreYellow, "fill", "#000000",999);
setAttribute(semaphoreRed, "fill", "#000000",999);
switch (realtimeItc.trafficLight)
{
case BarrierRealtimeITC.TRAFFIC_LIGHT_GREEN:
setAttribute(semaphoreGreen, "fill", "#00FF00",999);
case BarrierRealtimeITC.TRAFFIC_LIGHT_YELLOW:
setAttribute(semaphoreGreen, "fill", "#FFFF00",999);
case BarrierRealtimeITC.TRAFFIC_LIGHT_RED:
setAttribute(semaphoreGreen, "fill", "#FF0000",999);
}
}
private void barrierAlarms(SVGElement element, BarrierAlarms alarms)
{
String[] semaphoreAlarms = new String[]
{
"alarm_blown_green",
"alarm_blown_yellow",
"alarm_blown_red",
"alarm_damaged_green",
"alarm_damaged_green",
"alarm_damaged_red",
};
String[] barrierAlarms = new String[]
{
"alarm_opening",
"alarm_closing",
"alarm_broken",
"alarm_manual",
};
String[] loopInputAlarms = new String[]
{
"alarm_error_loop_input",
"alarm_loop_input_active",
"alarm_internal_error",
};
String[] loopOutputAlarms = new String[]
{
"alarm_error_loop_output",
"alarm_internal_error",
};
boolean semaphoreActiveAlarm = Stream.of(semaphoreAlarms).anyMatch(alarm -> alarms.getAlarm(alarm) > 0);
boolean barrierActiveAlarm = Stream.of(barrierAlarms).anyMatch(alarm -> alarms.getAlarm(alarm) > 0);
boolean loopInputActiveAlarm = Stream.of(loopInputAlarms).anyMatch(alarm -> alarms.getAlarm(alarm) > 0);
boolean loopOutputActiveAlarm = Stream.of(loopOutputAlarms).anyMatch(alarm -> alarms.getAlarm(alarm) > 0);
SVGElement semaphoreAlarm = getChildContainingField(element,"art.id","Sempahore.Alarm");
SVGElement barrierAlarm = getChildContainingField(element,"art.id","Barrier.Alarm");
setAttribute(semaphoreAlarm, "fill", semaphoreActiveAlarm ? "#FF0000" : "#00FF00", 999);
setAttribute(barrierAlarm, "fill", barrierActiveAlarm ? "#FF0000" : "#00FF00", 999);
SVGElement barrierBackground = getChildContainingField(element,"art.id","Barrier.Background");
SVGElement semaphoreBackground = getChildContainingField(element,"art.id","Sempahore.Background");
SVGElement loop1 = getChildContainingField(element,"art.id","Loop1");
SVGElement loop2 = getChildContainingField(element,"art.id","Loop2");
if (barrierActiveAlarm)
setAttribute(barrierBackground, "fill", "#FF0000",999);
if(semaphoreActiveAlarm)
setAttribute(semaphoreBackground, "fill", "#FF0000",999);
if(loopInputActiveAlarm)
setAttribute(loop1, "fill", "#FF0000",999);
if(loopOutputActiveAlarm)
setAttribute(loop2, "fill", "#FF0000",999);
}
private void barierDeviceStatus(SVGElement element, BarrierStatus deviceStatus)
{
SVGElement barrierBackground = getChildContainingField(element,"art.id","Barrier.Background");
SVGElement semaphoreBackground = getChildContainingField(element,"art.id","Sempahore.Background");
String statusColor = "#00FF00";
switch (deviceStatus.status)
{
case DeviceStatus.STATUS_OFFLINE:
case DeviceStatus.STATUS_UNKNOWN:
statusColor = "#FF00FF";
break;
}
setAttribute(barrierBackground, "fill", statusColor, 999);
setAttribute(semaphoreBackground, "fill", statusColor, 999);
}
//
private final HashMap mapMessages = new HashMap<>();
public void paint(Graphics2D g2)
{
System.out.println("PAINTING VMS");
for (SVGElement element : getElementsContainingField("art.device"))
{
Device device = Shared.model.modelDevices.getDevice(getAttribute(element, "art.device"));
if (device instanceof VmsGeneral)
{
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_FAST), (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);
}
});
}
}
}
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.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){}
}
}
}