package scriptbuilder.structures; import java.awt.Color; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Observable; import java.util.Random; import java.util.Vector; import java.util.logging.Level; import java.util.logging.Logger; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory; import scriptbuilder.structures.ScriptEvent.ScriptEventType; import scriptbuilder.structures.ScriptIncident.IncidentFocusedEvent; import scriptbuilder.structures.ScriptIncident.SliceChangedEvent; /** * Representation of the script to be run by the TMC Simulator. Holds a list of * incidents, which have start and end times and contain events. * * @author Greg Eddington * * @author Bryan McGuffin * @version 2017/06/22 */ public class SimulationScript extends Observable { /** * All default options for GUI colorings of incidents. */ public static final Color[] incidentColors = { Color.BLACK, Color.BLUE, Color.RED, new Color(0x38, 0x5E, 0x0F), new Color(128, 0, 128), Color.MAGENTA, new Color(0x23, 0x6B, 0x8E), Color.ORANGE, new Color(0x60, 0x33, 0x11), Color.GRAY }; /** * The incidents displayed by the GUI. */ public List incidents; //Somewhere in the code, something assumes that the list of incidents //contains exactly 10 items. Until I can find and un-break that, this will do. private final int INCIDENT_FILL_COUNT = 10; /** * Number of incidents currently displayed. */ private int numberOfIncidents; /** * Script handler for parsing incoming XML files. */ private MyScriptHandler sh; //TODO: Pretty much everything in this constructor is dummy data. //Replace all of it. /** * Constructor. Backfill incident list with null objects, to be replaced * later. */ public SimulationScript() { sh = new MyScriptHandler(this); incidents = new ArrayList(); numberOfIncidents = 0; // Create the media event /*incidents.add(new ScriptIncident(incidentColors[0], 100, "Media", "An incident for the media in CAD.", 10800, this)); numberOfIncidents++; // Create the "other" event incidents.add(new ScriptIncident(incidentColors[9], 999, "Other", "An incident for small-scale events, false events, " + "and noise. All events added to this incident will " + "receive a randomly generated incident number.", 10800, this)); numberOfIncidents++;*/ //Backfill with null incidents for (int i = numberOfIncidents; i < INCIDENT_FILL_COUNT; i++) { incidents.add(null); } /* // Add some demo events incidents.add(new ScriptIncident(incidentColors[1], 174, "Blueberry Truck", "Blueberry truck crashed on the freeway.", 8800, this)); numberOfIncidents++; incidents.add(new ScriptIncident(incidentColors[2], 175, "Construction Crash", "Crash at construction site on Red Road.", 6800, this)); numberOfIncidents++; incidents.add(new ScriptIncident(incidentColors[3], 176, "Car Freeway Flip", "Car flipped across the lane divider on the freeway.", 7200, this)); numberOfIncidents++; incidents.add(new ScriptIncident(incidentColors[4], 177, "Two Lane Crash", "Crash taking two lanes on Tree Road.", 4200, this)); numberOfIncidents++; incidents.add(new ScriptIncident(incidentColors[5], 178, "Stalled Truck", "Truck stalled on the freeway.", 2800, this)); numberOfIncidents++; //incidents.add(new ScriptIncident(incidentColors[6], 179, "Tomato Truck Spill", // "Tomato trucked spilt tomatos all over the freeway.", 3200, this)); //incidents.add(new ScriptIncident(incidentColors[7], 180, "Crash at Intersection", // "Crash at the intersection of Tree Road and Red Road.", 4300, this)); //incidents.add(new ScriptIncident(incidentColors[8], 181, "Bomb Threat", // "Bomb threat and Road X.", 6000, this)); incidents.add(null); incidents.add(null); incidents.add(null); Random rng = new Random(); ScriptEventType[] eventTypes = ScriptEventType.values(); if (numberOfIncidents > 0) { for (int i = 0; i < 300; i++) { int n = rng.nextInt(); int s = rng.nextInt(); int e = rng.nextInt(); if (n < 0) { n *= -1; } if (s < 0) { s *= -1; } if (e < 0) { e *= -1; } incidents.get(n % numberOfIncidents).slices.get(s % (incidents.get(n % numberOfIncidents).slices.size())).addEvent(new ScriptEvent(eventTypes[e % eventTypes.length])); } incidents.get(1).setOffset(200); incidents.get(2).setOffset(3400); incidents.get(3).setOffset(1400); incidents.get(4).setOffset(4400); incidents.get(5).setOffset(1400); //incidents.get(6).setOffset(7600); //incidents.get(7).setOffset(2400); //incidents.get(8).setOffset(4800); } */ } /** * Update the script's observers. * */ public void update() { // The script has changed, notify observers setChanged(); notifyObservers(this); } /** * Tell this script's observers that there is a new slice event. * * @param e the slice focus event */ public void broadcastEvent(SliceChangedEvent e) { // The slice focus has changed; pass the message setChanged(); notifyObservers(e); } /** * Tell this script's observers that there is a new slice event. * * @param e the incident focus event */ public void broadcastEvent(IncidentFocusedEvent e) { // The slice focus has changed; pass the message setChanged(); notifyObservers(e); } /** * Load in an existing script from an XML file. * * @param f the file containing the script */ public void loadScriptFromFile(File f) { try { SAXParserFactory.newInstance().newSAXParser().parse(f, sh); Vector inc = sh.getIncidents(); for (ScriptIncident sci : inc) { if (numberOfIncidents < INCIDENT_FILL_COUNT) { incidents.set(numberOfIncidents++, sci); } } } catch (Exception ex) { System.out.println("ERROR LOADING SCRIPT"); ex.printStackTrace(); } this.update(); } }