Index: trunk/src/scriptbuilder/gui/panels/IncidentTimelineTickPanel.java
===================================================================
--- trunk/src/scriptbuilder/gui/panels/IncidentTimelineTickPanel.java	(revision 53)
+++ trunk/src/scriptbuilder/gui/panels/IncidentTimelineTickPanel.java	(revision 53)
@@ -0,0 +1,192 @@
+package scriptbuilder.gui.panels;
+
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.event.MouseEvent;
+import javax.swing.JPanel;
+import javax.swing.event.MouseInputAdapter;
+import scriptbuilder.gui.ScriptBuilderFrame;
+import scriptbuilder.gui.ScriptBuilderGuiConstants;
+import scriptbuilder.gui.drawers.EventIconDrawer;
+import scriptbuilder.structures.ScriptIncident;
+import scriptbuilder.structures.SimulationScript;
+
+/**
+ * Represents the underlying panel on the main timeline. All the
+ * IncidentTimelinePanel objects sit over it. This panel draws all the
+ * per-minute ticks on the timeline, and adjusts and scales them as necessary.
+ *
+ * @author Greg Eddington <geddingt@calpoly.edu>
+ * @author Bryan McGuffin
+ */
+public class IncidentTimelineTickPanel extends JPanel
+{
+
+    private int longestLength = ScriptBuilderGuiConstants.TICK_TIMELINE_SMALLEST_LENGTH;
+    private int x, y;
+    private boolean focused = false;
+
+    public void setZoom(float zoom)
+    {
+        repaint();
+    }
+
+    /**
+     * Listener for the mouse. Is notified when the mouse enters, exits, or
+     * moves around on the panel.
+     */
+    public class TimelineTickMouseListener extends MouseInputAdapter
+    {
+
+        /**
+         * When the mouse enters the panel, the panel gets focus.
+         *
+         * @param e the mouse event
+         */
+        @Override
+        public void mouseEntered(MouseEvent e)
+        {
+            focused = true;
+        }
+
+        /**
+         * When the mouse leaves the panel, the panel loses focus and refreshes.
+         *
+         * @param e the mouse event
+         */
+        @Override
+        public void mouseExited(MouseEvent e)
+        {
+            focused = false;
+            repaint();
+        }
+
+        /**
+         * When the mouse moves around in the panel, the panel refreshes and
+         * updates its mouse tracker.
+         *
+         * @param e
+         */
+        @Override
+        public void mouseMoved(MouseEvent e)
+        {
+            x = e.getX();
+            y = e.getY();
+
+            repaint();
+        }
+    }
+
+    /**
+     * Constructor. Set up the mouse listener.
+     */
+    public IncidentTimelineTickPanel()
+    {
+        super();
+
+        TimelineTickMouseListener mouseListener
+                = new TimelineTickMouseListener();
+        addMouseMotionListener(mouseListener);
+        addMouseListener(mouseListener);
+    }
+
+    /**
+     * Update the panel's dimensions based on number of events, zoom level, and
+     * which events are collapsed.
+     *
+     * @param script The main script model
+     */
+    public void update(SimulationScript script)
+    {
+        longestLength = ScriptBuilderGuiConstants.TICK_TIMELINE_SMALLEST_LENGTH;
+
+        // Get the stats on the incidents
+        int height = ScriptBuilderGuiConstants.TICK_TOP_MARGIN * 4;
+        for (ScriptIncident incident : script.incidents)
+        {
+            if (incident != null)
+            {
+                height += incident.collapsed
+                        ? ScriptBuilderGuiConstants.TIMELINE_OPENED_HEIGHT
+                        : ScriptBuilderGuiConstants.TIMELINE_OPENED_HEIGHT;
+                if ((incident.length + incident.offset) > longestLength)
+                {
+                    longestLength = incident.length + incident.offset;
+                }
+            }
+        }
+
+        Dimension newSize = new Dimension(longestLength
+                / ScriptBuilderGuiConstants.HORIZONTAL_TICK_RESOLUTION
+                * ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK
+                + ScriptBuilderGuiConstants.TICK_TIMELINE_LEFT_MARGIN + 50,
+                height);
+        this.setPreferredSize(newSize);
+        this.setSize(newSize);
+
+        this.invalidate();
+    }
+
+    /**
+     * Refresh the panel. Redraw the ticks based on zoom level, panel
+     * dimensions, and offset. If the user is trying to add an event, draw that
+     * event's icon under the mouse.
+     *
+     * @param g The graphics component
+     */
+    @Override
+    public void paint(Graphics g)
+    {
+        super.paint(g);
+
+        Graphics2D g2d = (Graphics2D) g;
+
+        // Draw the horizontal line
+        g2d.setFont(ScriptBuilderGuiConstants.TIMELINE_TICK_TIME_FONT);
+        g2d.setColor(ScriptBuilderGuiConstants.TIMELINE_TICK_COLOR);
+        g2d.fillRect(0, ScriptBuilderGuiConstants.TICK_TIMELINE_TOP_MARGIN,
+                longestLength, ScriptBuilderGuiConstants.TICK_TIMELINE_HEIGHT);
+
+        // Draw the ticks
+        int longestLengthPlusMargin = longestLength
+                / ScriptBuilderGuiConstants.HORIZONTAL_TICK_RESOLUTION
+                * ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK
+                + ScriptBuilderGuiConstants.TICK_TIMELINE_LEFT_MARGIN;
+
+        // Minutes
+        g2d.setColor(ScriptBuilderGuiConstants.MINOR_TICK_COLOR);
+        int seconds = 0;
+        for (int i = ScriptBuilderGuiConstants.TICK_TIMELINE_LEFT_MARGIN;
+                i <= longestLengthPlusMargin;
+                i += ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK, seconds += ScriptBuilderGuiConstants.HORIZONTAL_TICK_RESOLUTION)
+        {
+            g2d.drawLine(i, ScriptBuilderGuiConstants.TICK_TOP_MARGIN,
+                    i, ScriptBuilderGuiConstants.TICK_HEIGHT);
+        }
+
+        // Major Ticks
+        g2d.setColor(ScriptBuilderGuiConstants.TIMELINE_TICK_COLOR);
+        seconds = 0;
+        for (int i = ScriptBuilderGuiConstants.TICK_TIMELINE_LEFT_MARGIN;
+                i <= longestLengthPlusMargin;
+                i += ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK
+                * ScriptBuilderGuiConstants.TICKS_PER_MAJOR_TICK, seconds += ScriptBuilderGuiConstants.HORIZONTAL_TICK_RESOLUTION
+                * ScriptBuilderGuiConstants.TICKS_PER_MAJOR_TICK)
+        {
+            g2d.drawLine(i, ScriptBuilderGuiConstants.TICK_TOP_MARGIN,
+                    i, ScriptBuilderGuiConstants.TICK_HEIGHT);
+
+        }
+
+        paintChildren(g);
+
+        if (focused
+                && ((ScriptBuilderFrame) this.getTopLevelAncestor()).currentEventType != null)
+        {
+            EventIconDrawer.DrawEventIcon(g2d,
+                    ((ScriptBuilderFrame) this.getTopLevelAncestor()).currentEventType,
+                    x, y);
+        }
+    }
+}
Index: trunk/src/scriptbuilder/gui/panels/IncidentsPanel.java
===================================================================
--- trunk/src/scriptbuilder/gui/panels/IncidentsPanel.java	(revision 1)
+++ trunk/src/scriptbuilder/gui/panels/IncidentsPanel.java	(revision 53)
@@ -20,6 +20,6 @@
     private SimulationScript script;
     private TimelineTickPanel timelineTickPanel;
-    private List<IncidentTimelinePanel> incidentPanels;
-    private List<IncidentNumberPanel> numberPanels;
+    private List<ScriptBuilderTimelinePanel> incidentPanels;
+    private List<ScriptBuilderNumberPanel> numberPanels;
 
     /**
Index: trunk/src/scriptbuilder/gui/panels/ScriptBuilderTimelinePanel.java
===================================================================
--- trunk/src/scriptbuilder/gui/panels/ScriptBuilderTimelinePanel.java	(revision 53)
+++ trunk/src/scriptbuilder/gui/panels/ScriptBuilderTimelinePanel.java	(revision 53)
@@ -0,0 +1,309 @@
+package scriptbuilder.gui.panels;
+
+import event.editor.Editor;
+import event.editor.Properties;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.event.MouseEvent;
+import java.util.HashMap;
+import java.util.Map;
+import javax.swing.JPanel;
+import javax.swing.event.MouseInputAdapter;
+import scriptbuilder.gui.ScriptBuilderFrame;
+import scriptbuilder.gui.ScriptBuilderGuiConstants;
+import scriptbuilder.gui.drawers.CursorDrawer;
+import scriptbuilder.gui.drawers.EventIconDrawer;
+import scriptbuilder.gui.drawers.IncidentTimelineDrawer;
+import scriptbuilder.structures.ScriptEvent;
+import scriptbuilder.structures.ScriptEvent.ScriptEventType;
+import scriptbuilder.structures.ScriptIncident;
+import scriptbuilder.structures.TimeSlice;
+import scriptbuilder.structures.events.I_ScriptEvent;
+
+/**
+ * Represents a single incident timeline in the GUI. Listens for mouse actions.
+ *
+ * @author Greg Eddington <geddingt@calpoly.edu>
+ * @author Bryan McGuffin
+ * @version 2017/06/30
+ */
+public class ScriptBuilderTimelinePanel extends JPanel
+{
+
+    /**
+     * The incident this panel represents.
+     */
+    ScriptIncident incident;
+    /**
+     * If true, this panel is in its minimized state.
+     */
+    //boolean collapsed;
+    /**
+     * If false, this panel won't be drawn.
+     */
+    boolean visible;
+    /**
+     * If true, this panel has focus.
+     */
+    boolean focused;
+
+    int cursorTime, lastSlice, x, y;
+
+    /**
+     * The map representing the properties of this incident's events. Keys:
+     * event types. Values: Properties objects for those events.
+     */
+    Map<ScriptEventType, Properties> eventTypeToPropertyMap;
+
+    /**
+     * Listener for the mouse. Receives notifications when the mouse enters,
+     * exits, moves through, or clicks inside the panel.
+     */
+    public class IncidentTimelineMouseListener extends MouseInputAdapter
+    {
+
+        /**
+         * Action to take when the mouse enters the panel. Here, the incident
+         * corresponding to this panel gains focus.
+         *
+         * @param e the mouse event
+         */
+        @Override
+        public void mouseEntered(MouseEvent e)
+        {
+            incident.setIncidentActive();
+            focused = true;
+        }
+
+        /**
+         * Action to take when the mouse leaves the panel. Here, the incident
+         * loses focus and the panel gets repainted.
+         *
+         * @param e the mouse event
+         */
+        @Override
+        public void mouseExited(MouseEvent e)
+        {
+            focused = false;
+            repaint();
+        }
+
+        /**
+         * Determine if the mouse click happened within a valid timeSlice on
+         * this incident; if so, activate the Editor window for that timeSlice.
+         *
+         * @param e the mouse event
+         */
+        @Override
+        public void mouseClicked(MouseEvent e)
+        {
+            Editor ed = new Editor();
+            ScriptBuilderFrame f = (ScriptBuilderFrame) getTopLevelAncestor();
+
+            x = cursorTime = e.getX();
+            y = e.getY();
+
+            if (e.getX() % ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK
+                    > ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK / 2)
+            {
+                cursorTime += ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK
+                        - e.getX()
+                        % ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK;
+            }
+            else
+            {
+                cursorTime -= e.getX()
+                        % ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK;
+            }
+
+            int newSlice = (cursorTime / ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK);
+            newSlice *= ScriptBuilderGuiConstants.HORIZONTAL_TICK_RESOLUTION;
+            /**
+             * Check if click is out of bounds *
+             */
+            if (newSlice < 0 || incident == null)
+            {
+                return;
+            }
+
+            if (incident.slices.get(newSlice) != null)
+
+            {
+                for (I_ScriptEvent se : incident.slices.get(newSlice).events)
+                {
+                    ed.addProperty(eventTypeToPropertyMap.get(se.getScriptEventType()), se);
+                }
+            }
+
+            /**
+             * Add a new icon if left mouse button was clicked *
+             */
+            if (e.getButton() == MouseEvent.BUTTON1)
+            {
+                if (f.currentEventType != null)
+                {
+                    I_ScriptEvent s = ScriptEvent.factoryByType(f.currentEventType);
+                    ed.addProperty(eventTypeToPropertyMap.get(f.currentEventType), s);
+                    if (incident.slices.get(newSlice) == null)
+                    {
+                        incident.addNewEvent(s, newSlice);
+                    }
+                    else
+                    {
+                        incident.slices.get(newSlice).addEvent(s);
+                    }
+                    f.update(f.getScript(), f.getScript());
+                }
+            }
+
+            if (incident.slices.get(newSlice) != null)
+            {
+                ed.setVisible(true);
+            }
+        }
+
+        /**
+         * Determine if the mouse is now hovering over a valid timeslice; if so,
+         * alter tooltip text and info window text to reflect the new timeslice.
+         *
+         * @param e the mouse event
+         */
+        @Override
+        public void mouseMoved(MouseEvent e)
+        {
+            x = cursorTime = e.getX();
+            y = e.getY();
+
+            if (e.getX() % ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK
+                    > ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK / 2)
+            {
+                cursorTime += ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK
+                        - e.getX()
+                        % ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK;
+            }
+            else
+            {
+                cursorTime -= e.getX()
+                        % ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK;
+            }
+
+            if (incident != null)
+            {
+                int newSlice = (cursorTime / ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK);
+                newSlice *= ScriptBuilderGuiConstants.HORIZONTAL_TICK_RESOLUTION;
+                if (newSlice >= 0 && incident.slices.get(newSlice) != null)
+                {
+                    incident.setSliceActive(newSlice);
+                    lastSlice = newSlice;
+                    String newToolTip;
+
+                    newToolTip = incident.slices.get(newSlice).toString();
+
+                    setToolTipText((newToolTip == null || newToolTip.equals(""))
+                            ? null : newToolTip);
+                }
+            }
+
+            repaint();
+        }
+    }
+
+    /**
+     * Constructor. Generates a HashMap of all possible event types.
+     */
+    public ScriptBuilderTimelinePanel()
+    {
+        super();
+
+//        FACILITATOR_EVAL_EVENT, RADIO_EVAL_EVENT
+        eventTypeToPropertyMap = new HashMap();
+        eventTypeToPropertyMap.put(ScriptEventType.AUDIO_EVENT, Properties.Audio);
+        eventTypeToPropertyMap.put(ScriptEventType.CAD_EVENT, Properties.CADLog);
+        eventTypeToPropertyMap.put(ScriptEventType.CCTV_EVENT, Properties.CCTV);
+        eventTypeToPropertyMap.put(ScriptEventType.CHP_RADIO_EVENT, Properties.CHPRadio);
+        eventTypeToPropertyMap.put(ScriptEventType.PARAMICS_EVENT, Properties.Paramics);
+        eventTypeToPropertyMap.put(ScriptEventType.TOW_EVENT, Properties.Tow);
+        eventTypeToPropertyMap.put(ScriptEventType.UNIT_EVENT, Properties.Unit);
+        eventTypeToPropertyMap.put(ScriptEventType.WITNESS_EVENT, Properties.Witness);
+        eventTypeToPropertyMap.put(ScriptEventType.MAINTENANCE_RADIO_EVENT, Properties.MaintenanceRadio);
+        eventTypeToPropertyMap.put(ScriptEventType.TMT_RADIO_EVENT, Properties.TMTRadio);
+        eventTypeToPropertyMap.put(ScriptEventType.TELEPHONE_EVENT, Properties.Telephone);
+        eventTypeToPropertyMap.put(ScriptEventType.ATMS_EVAL_EVENT, Properties.ATMS);
+        eventTypeToPropertyMap.put(ScriptEventType.ACTIVITY_LOG_EVAL_EVENT, Properties.ActivityLog);
+        eventTypeToPropertyMap.put(ScriptEventType.CAD_EVAL_EVENT, Properties.CAD);
+        eventTypeToPropertyMap.put(ScriptEventType.CMS_EVAL_EVENT, Properties.CMS);
+        eventTypeToPropertyMap.put(ScriptEventType.FACILITATOR_EVAL_EVENT, Properties.Facilitator);
+        eventTypeToPropertyMap.put(ScriptEventType.RADIO_EVAL_EVENT, Properties.Radio);
+
+        // Add the mouse listener
+        IncidentTimelineMouseListener mouseListener
+                = new IncidentTimelineMouseListener();
+        addMouseMotionListener(mouseListener);
+        addMouseListener(mouseListener);
+    }
+
+    /**
+     * Update the panel if it's changed collapsed status. Redraw it with the
+     * correct dimensions for its status.
+     *
+     * @param incident the incident this panel represents
+     */
+    public void timelinePanelUpdate(ScriptIncident incident)
+    {
+        this.incident = incident;
+        this.visible = incident != null;
+
+        Dimension newSize;
+        if (visible)
+        {
+
+            newSize = new Dimension(((incident.length + incident.offset)
+                    / ScriptBuilderGuiConstants.HORIZONTAL_TICK_RESOLUTION
+                    * ScriptBuilderGuiConstants.PIXEL_WIDTH_PER_HORIZONTAL_TICK)
+                    + ScriptBuilderGuiConstants.EVENT_ICON_WIDTH,
+                    ScriptBuilderGuiConstants.TIMELINE_COLLAPSED_HEIGHT
+                    + ScriptBuilderGuiConstants.SCRIPT_EVENT_ICON_STEP * 2);
+
+        }
+        else
+        {
+            newSize = new Dimension(0, 0);
+        }
+        this.setSize(newSize);
+        this.setPreferredSize(newSize);
+
+        invalidate();
+    }
+
+    /**
+     * Redraw this panel and all the icons inside it. If user is holding an
+     * event, draw that icon under the mouse.
+     *
+     * @param g the graphics component
+     */
+    @Override
+    public void paint(Graphics g)
+    {
+        super.paint(g);
+
+        if (!visible)
+        {
+            return;
+        }
+
+        Graphics2D g2d = (Graphics2D) g;
+        IncidentTimelineDrawer.DrawScriptBuilderTimeline(g2d, incident);
+
+        if (focused)
+        {
+            CursorDrawer.DrawCursor(g2d, cursorTime, false);
+            if (((ScriptBuilderFrame) this.getTopLevelAncestor()).currentEventType != null)
+            {
+                EventIconDrawer.DrawEventIcon(g2d,
+                        ((ScriptBuilderFrame) this.getTopLevelAncestor()).currentEventType,
+                        x + 5, y + 10);
+            }
+        }
+    }
+}
Index: trunk/src/scriptbuilder/gui/panels/ScriptBuilderNumberPanel.java
===================================================================
--- trunk/src/scriptbuilder/gui/panels/ScriptBuilderNumberPanel.java	(revision 53)
+++ trunk/src/scriptbuilder/gui/panels/ScriptBuilderNumberPanel.java	(revision 53)
@@ -0,0 +1,133 @@
+package scriptbuilder.gui.panels;
+
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.event.MouseEvent;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.imageio.ImageIO;
+import javax.swing.JPanel;
+import javax.swing.event.MouseInputAdapter;
+import scriptbuilder.gui.ScriptBuilderFrame;
+import scriptbuilder.gui.ScriptBuilderGuiConstants;
+import scriptbuilder.structures.ScriptIncident;
+import scriptbuilder.structures.TimeSlice;
+
+/**
+ * Displays the Incident ID number and name. Holds the button to toggle
+ * collapsed state.
+ *
+ * @author Greg Eddington <geddingt@calpoly.edu>
+ * @author Bryan McGuffin
+ */
+public class ScriptBuilderNumberPanel extends JPanel
+{
+
+    ScriptIncident incident;
+    boolean visible;
+
+    /**
+     * Listener for the mouse. Receives notifications if the mouse is clicked
+     * inside the button.
+     */
+    private class IncidentNumberMouseListener extends MouseInputAdapter
+    {
+
+        /**
+         * If the click occurs inside the icon borders, toggle the collapsed
+         * state.
+         *
+         * @param e the mouse event
+         */
+        @Override
+        public void mouseClicked(MouseEvent e)
+        {
+
+        }
+    }
+
+    /**
+     * Constructor. Sets up the mouse listener.
+     */
+    public ScriptBuilderNumberPanel()
+    {
+        super();
+
+        // Add the mouse listener
+        IncidentNumberMouseListener mouseListener
+                = new IncidentNumberMouseListener();
+        addMouseMotionListener(mouseListener);
+        addMouseListener(mouseListener);
+    }
+
+    /**
+     * Update the dimensions of the panel.
+     *
+     * @param incident The incident to be represented by this panel.
+     */
+    public void update(ScriptIncident incident)
+    {
+        this.incident = incident;
+        this.visible = incident != null;
+
+        Dimension newSize;
+        if (visible)
+        {
+
+            newSize = new Dimension(ScriptBuilderGuiConstants.INCIDENT_NUMBER_WIDTH,
+                    ScriptBuilderGuiConstants.TIMELINE_COLLAPSED_HEIGHT
+                    + ScriptBuilderGuiConstants.SCRIPT_EVENT_ICON_STEP * 2);
+
+        }
+        else
+        {
+            newSize = new Dimension(0, 0);
+        }
+        this.setSize(newSize);
+        this.setPreferredSize(newSize);
+
+        if (incident != null)
+        {
+            this.setToolTipText(incident.name);
+        }
+
+        invalidate();
+    }
+
+    /**
+     * Refresh the panel. Choose button icon depending on collapsed state.
+     *
+     * @param g the graphics component
+     */
+    @Override
+    public void paint(Graphics g)
+    {
+        super.paint(g);
+
+        if (!visible)
+        {
+            return;
+        }
+
+        Graphics2D g2d = (Graphics2D) g;
+        g2d.setColor(incident.color);
+        g2d.setFont(ScriptBuilderGuiConstants.INCIDENT_NUMBER_FONT);
+        g2d.drawString(Integer.toString(incident.number),
+                ScriptBuilderGuiConstants.INCIDENT_NUMBER_LEFT_MARGIN,
+                ScriptBuilderGuiConstants.INCIDENT_NUMBER_TOP_MARGIN);
+
+        int y = ScriptBuilderGuiConstants.INCIDENT_NUMBER_TOP_MARGIN * 2 - 14;
+        g2d.setFont(ScriptBuilderGuiConstants.INCIDENT_NAME_FONT);
+        for (String line : incident.name.split(" "))
+        {
+            g2d.drawString(line, 20, y);
+            y += 12;
+        }
+
+    }
+}
