Index: trunk/webapps/einotebook/index.html
===================================================================
--- trunk/webapps/einotebook/index.html	(revision 468)
+++ trunk/webapps/einotebook/index.html	(revision 540)
@@ -52,4 +52,8 @@
              Maps
             </li>
+            <li class="notActive" id="rolesTab" 
+            	onClick="changeTab(this.id); showContent('rolePageContent')">
+             Roles
+            </li>
           </ul><br>
               <div class="simulationTime" id="simulationTime">0:00:00</div>
@@ -80,4 +84,9 @@
 		    </iframe>
           </td>
+          <td class='tabPageContent' id='rolePageContent' style="display:none;">
+            <iframe id='rolePage' src='roles/index.html' frameborder='0' 
+            scrolling='yes' height='100%' width='100%'>
+		    </iframe>
+		  </td>
 	    </td>
       </tr>
Index: trunk/webapps/einotebook/roles/index.html
===================================================================
--- trunk/webapps/einotebook/roles/index.html	(revision 540)
+++ trunk/webapps/einotebook/roles/index.html	(revision 540)
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
+  "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+    <!-- This is the page containing the simulation script and jump button -->
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <link href="roles.css" rel="stylesheet" type="text/css">
+    <script type="text/javascript" src="../scripts/Time.js"></script> 
+    <script type="text/javascript" src="roles.js"></script> 
+    <script type="text/javascript" src="../scripts/cookies.js"></script>
+    <title>Script</title>
+  </head>
+  <body>
+   
+    <button class="jumpToCurrentEvent" 
+            onclick="jumpToLastExecutedEvent()">Jump to Current Event</button>
+    <!-- A combo box for which role is to be displayed on the page -->
+    <select id="desiredRole" onchange="changeRole()">
+      <option value="TELEPHONE CONVERSATION" selected="selected">TELEPHONE CONVERSATION</option>
+      <option value="MAINTENANCE_RADIO">MAINTENANCE_RADIO</option>
+      <option value="TMT_RADIO">TMT_RADIO</option>
+      <option value="CHP RADIO">CHP RADIO</option>
+    </select>
+      
+    <iframe id='view' src='../script/scrollframe.html' frameborder='0' scrolling='yes'
+            width='100%'></iframe>
+  </body>
+</html>
Index: trunk/webapps/einotebook/roles/roles.css
===================================================================
--- trunk/webapps/einotebook/roles/roles.css	(revision 540)
+++ trunk/webapps/einotebook/roles/roles.css	(revision 540)
@@ -0,0 +1,33 @@
+@CHARSET "UTF-8";
+
+body {
+	font-family: Verdana, sans-serif;	
+}
+
+/*=============================== Button Panel ======================*/
+
+button.expandButton {
+	width:100px;
+}
+
+button.collapseButton {
+	width:100px;
+}
+
+input.timeText {
+	padding-left:0px; 
+	padding-right:0px; 
+	margin-left:0px; 
+	margin-right:0px;  
+	width:1.5em;
+}
+
+td.buttonPanel {
+	padding:1px;
+}
+
+table.buttonTable
+{
+	margin:0px;
+	padding:0px;
+}
Index: trunk/webapps/einotebook/roles/roles.js
===================================================================
--- trunk/webapps/einotebook/roles/roles.js	(revision 540)
+++ trunk/webapps/einotebook/roles/roles.js	(revision 540)
@@ -0,0 +1,224 @@
+// global variable: The user selected role to be displayed
+var selectedRole = "TELEPHONE CONVERSATION"; // default value
+
+/**
+ * Holds references to the events and incidents.
+ */
+function Roles()
+{
+	Roles.events = null;
+	Roles.incidents = null;
+}
+
+/**
+ * Change which role to display on this page.
+ * Invoked by "onchange" in SELECT box.
+ */
+function changeRole()
+{
+    // Assign the user's choice to a global variable
+    selectedRole = document.getElementById("desiredRole").value;
+    displayRolesPage();
+}
+
+/**
+ * Scrolls to the last event executed based on time.
+ */
+function jumpToLastExecutedEvent()
+{	
+	var lastEventArray = Roles.events.getLastExecutedEvent(readCookie("time"));
+
+	// IF a current event exists THEN
+	if (lastEventArray != null)
+	{
+        // Move window focus to first event of the current ones
+        var last = lastEventArray.length - 1;
+	    lastEventArray[last].focus();
+	}
+	else
+	{
+		alert("No events have been executed yet.");
+	}
+}
+
+/**
+ * Finds the Event that was last executed by based on time and highlights it.
+ * Removes highlighting from old events.
+ * @return
+ */
+function highlightLatestEvent() 
+{
+    Roles.events.setEmphasis();  // Set text colors on all events
+
+    var currentEventArray = Roles.events.getLastExecutedEvent(readCookie("time"));
+	/* highlight the items in the current event array */
+    for (var i=0; i<currentEventArray.length; i++) 
+    {
+		currentEventArray[i].highlight();
+	}
+
+    // Set timer to do this again in one second
+	setTimeout("highlightLatestEvent()", 1000);
+}
+
+/**
+ * Inital load of the the roles tab for the given document.
+ */
+function loadRoles(theEvents, theIncidents)
+{
+	Roles.incidents = theIncidents;
+	Roles.events = theEvents;
+	Roles.events.win = document.getElementById("view").contentWindow;
+	Roles.events.doc = getDocumentFromFrame('view');
+    // reset SELECT box to default value
+    document.getElementById("desiredRole").value = "TELEPHONE CONVERSATION";
+    displayRolesPage();
+}
+
+/**
+ * Display the events of the selected type on the page.
+ * Uses global variable: selectedRole
+ */
+function displayRolesPage()
+{
+	var html = "";
+	
+	// FOR each Event
+	for (var i = 0; i < Roles.events.length; i++)
+	{
+        // Consider each property of this event
+        for (var j = 0; j < Roles.events[i].properties.properties.length; j++)
+        {
+            // If it matches the currently selected role
+            if (Roles.events[i].properties.properties[j].type == selectedRole)
+            {
+                    // add the Event's html
+                    html += "<table class='event'>";
+                    html += Roles.events[i].get_html_headerRow();
+                    html += "<tr>" + 
+                       "<td class='eventData' style='background-color:" + Roles.events[i].incident.color + "' id='" +
+                       Roles.events[i].dataID + "'>" + 
+                       Roles.events[i].properties.properties[j].html() + 
+                       "</td>" +
+                       "</tr>";
+                    html += "</table>";
+            }
+        }
+	}
+	
+	// display events in iframe
+	getDocumentFromFrame('view').body.innerHTML = html;	
+   
+	// resize iframe to appropriate height
+	resizeIframe();
+	window.onresize = resizeIframe;
+	
+	Roles.events.win.scrollTo(0, readCookie('scriptScrollY'));
+	
+	highlightLatestEvent();
+
+}
+/**
+ * @param id The id of the frame element.
+ * @return The document of the frame element.
+ */
+function getDocumentFromFrame(id)
+{
+    var frame=document.getElementById(id);
+    var doc=(frame.contentWindow || frame.contentDocument);
+    
+    if (doc.document)doc=doc.document;
+    
+    return doc;
+}
+
+/**
+ * Finds the height of an element relative to the BODY tag.
+ * @param elem The element to find the height of.
+ * @return The y-coordinate of the given element relative to the BODY tag.
+ */
+function pageY(elem) 
+{
+    return elem.offsetParent ? (elem.offsetTop + pageY(elem.offsetParent)) : elem.offsetTop;
+}
+
+/**
+ * Resizes the view for the events so that the view's height is at the bottom of its
+ * container.
+ */
+function resizeIframe() 
+{
+    var height = document.documentElement.clientHeight;
+    height -= pageY(document.getElementById('view'));
+    height = (height < 0) ? 0 : height - 10;
+    document.getElementById('view').style.height = height + 'px';
+}
+
+/**
+ * Highlights the text of an input text element after a small delay.
+ * This method was made because using the code "onFocus='this.focus()'" did not work.
+ * @pre textField must have an 'id' attribute
+ * @param textField An input text element.
+ */
+function highlightTextField(textField)
+{
+	setTimeout("document.getElementById('" + textField.id + "').select();", 100);
+}
+
+/**
+ * Formats a two digit textbox. If the text box contains only one digit, then a zero
+ * is appended to the front.
+ * @param textField An input text element.
+ */
+function formatTimeTextfield(textField)
+{
+	// IF the text field contains 1 digits THEN
+	if (textField.value.length == 1)
+	{
+		textField.value = "0".concat(textField.value);
+	}
+}
+
+/**
+ * Scrolls to the event latest executed event if the current simulation time was given
+ * by text fields 'timeTextSeconds', 'timeTextMinutes', 'timeTextHours'.
+ */
+function jumpToTime()
+{
+	var seconds = parseInt(document.getElementById('timeTextSeconds').value, 10);
+	var minutes = parseInt(document.getElementById('timeTextMinutes').value, 10);
+	var hours = parseInt(document.getElementById('timeTextHours').value, 10);
+
+	var lastEvent = Roles.events.getLastExecutedEvent(new Time(hours, minutes, seconds).getSeconds());
+
+	// IF an event was executed THEN
+	if (lastEvent != null)
+	{
+		lastEvent.focus();
+	}
+}
+
+/**
+ * Collapses the elements based on the value of the dropdownbox with id 'domain'.
+ */
+function collapse()
+{
+	var selection = document.getElementById('domain');
+	var selectedIndex = selection.selectedIndex;
+	var selectedValue = selection.options[selectedIndex].value;
+	
+	eval("Roles.events.collapseAll" + selectedValue + "();");
+}
+
+/**
+ * Expands the elements based on the value of the dropdownbox with id 'domain'.
+ */
+function expand()
+{
+	var selection = document.getElementById('domain');
+	var selectedIndex = selection.selectedIndex;
+	var selectedValue = selection.options[selectedIndex].value;
+	
+	eval("Roles.events.expandAll" + selectedValue + "();");
+}
+
Index: trunk/webapps/einotebook/scripts/Event.js
===================================================================
--- trunk/webapps/einotebook/scripts/Event.js	(revision 538)
+++ trunk/webapps/einotebook/scripts/Event.js	(revision 540)
@@ -35,4 +35,5 @@
     this.normalize = normalize;
 	this.focus = focus;
+    this.get_html_headerRow = get_html_headerRow;
 	
 	//========== private methods ==========//
@@ -159,5 +160,16 @@
 			   "</table>";
 	}
-	
+	/**
+	 * @return The html representation of only the header for this event.
+     * Used by Roles page.
+	 */
+	function get_html_headerRow()
+	{
+		return "<tr>" +
+			   "<td class='eventHeader' style='background-color:" + this.incident.color + "'" +
+               "id='" + this.eventHeaderID + "'>" + 
+			      this.headerHTML() + "</td>" +
+			   "</tr>";
+	}	
 	/**
 	 * Scrolls the window to this Event.
@@ -181,4 +193,6 @@
 	{
 		this.highlighted = true;
+        if (events.doc.getElementById(this.eventHeaderID) != null)
+        {
 		events.doc.getElementById(this.eventHeaderID).style.borderColor = "blue";
 		events.doc.getElementById(this.eventHeaderID).style.backgroundColor = "yellow";
@@ -196,5 +210,5 @@
 			events.doc.getElementById(this.dataID).style.border = "none";
 		}
-	
+        }
 	}
 	
@@ -206,10 +220,13 @@
 	{
 		this.highlighted = false;
-		events.doc.getElementById(this.eventHeaderID).style.backgroundColor = "white";
-		events.doc.getElementById(this.eventHeaderID).style.borderColor = "gainsboro";
-		events.doc.getElementById(this.eventHeaderID).style.color = "gray";
-		events.doc.getElementById(this.dataID).style.border = "0px solid red";
-		events.doc.getElementById(this.dataID).style.backgroundColor = "white";
-		events.doc.getElementById(this.dataID).style.color = "gray";
+        if (events.doc.getElementById(this.eventHeaderID) != null)
+        {
+            events.doc.getElementById(this.eventHeaderID).style.backgroundColor = "white";
+            events.doc.getElementById(this.eventHeaderID).style.borderColor = "gainsboro";
+            events.doc.getElementById(this.eventHeaderID).style.color = "gray";
+            events.doc.getElementById(this.dataID).style.border = "0px solid red";
+            events.doc.getElementById(this.dataID).style.backgroundColor = "white";
+            events.doc.getElementById(this.dataID).style.color = "gray";
+        }
 	}
 	/**
@@ -219,10 +236,15 @@
 	{
         var myColor = this.incident.color;
-		events.doc.getElementById(this.eventHeaderID).style.backgroundColor = "white";
-		events.doc.getElementById(this.eventHeaderID).style.borderColor = "black";
-		events.doc.getElementById(this.eventHeaderID).style.color = "black";
-		events.doc.getElementById(this.dataID).style.color = "black";
-        events.doc.getElementById(this.dataID).style.backgroundColor = myColor;
-		events.doc.getElementById(this.eventHeaderID).style.backgroundColor = myColor;
+        // On the Roles page, we don't list every event, so some will be null
+        // This check will make sure we don't try to normalize non-existing events
+        if (events.doc.getElementById(this.eventHeaderID) != null)
+        {
+            events.doc.getElementById(this.eventHeaderID).style.backgroundColor = "white";
+            events.doc.getElementById(this.eventHeaderID).style.borderColor = "black";
+            events.doc.getElementById(this.eventHeaderID).style.color = "black";
+            events.doc.getElementById(this.dataID).style.color = "black";
+            events.doc.getElementById(this.dataID).style.backgroundColor = myColor;
+            events.doc.getElementById(this.eventHeaderID).style.backgroundColor = myColor;
+        }
     }		
 
Index: trunk/webapps/einotebook/scripts/LoadEvents.js
===================================================================
--- trunk/webapps/einotebook/scripts/LoadEvents.js	(revision 538)
+++ trunk/webapps/einotebook/scripts/LoadEvents.js	(revision 540)
@@ -74,7 +74,7 @@
                         break;
                     case "TELEPHONE": 
-                        telProp = new Evaluation("TELEPHONE CONVERSATION", 
+                        telProp = new Property("TELEPHONE CONVERSATION", 
                                  parseTelephone(currEvt.childNodes[child]) );  
-                        evalarray.push(telProp);
+                        proparray.push(telProp);
                         break;
                     case "CHP_RADIO": 
@@ -156,9 +156,10 @@
         if (element.childNodes[child].localName != undefined)
         {
+            // IF line is INSTRUCTOR THEN display only the Role field
             if (element.childNodes[child].localName == "INSTRUCTOR")
             {
                 result.push(element.childNodes[child].attributes["Role"].value);
             }
-            else
+            else  // Display the name (e.g., STUDENT)
             {
                 result.push(element.childNodes[child].localName);   
Index: trunk/webapps/einotebook/notebook.js
===================================================================
--- trunk/webapps/einotebook/notebook.js	(revision 468)
+++ trunk/webapps/einotebook/notebook.js	(revision 540)
@@ -32,4 +32,5 @@
    window.frames[1].loadScript(events, incidents);
    window.frames[2].loadScript(events, incidents);
+   window.frames[4].loadRoles(events, incidents);
 }
 
@@ -89,4 +90,5 @@
     document.getElementById("currentTab").className = "notActive";
     document.getElementById("mapsTab").className = "notActive";
+    document.getElementById("rolesTab").className = "notActive";
 
     /* Set the selected tab to being active */
@@ -127,4 +129,5 @@
     hideContent('currentEventPageContent');
     hideContent('mapsPageContent');    
+    hideContent('rolePageContent');    
     document.getElementById(d).style.display = "block"; 
 }
