Index: trunk/webapps/visualizer/js/vdsLayer.js
===================================================================
--- trunk/webapps/visualizer/js/vdsLayer.js	(revision 528)
+++ trunk/webapps/visualizer/js/vdsLayer.js	(revision 530)
@@ -1,26 +1,4 @@
-    // Build a solid colored icon to use instead of the classic pin
-    function dotSymbol(color) 
-    {
-        var iconPath = iconVDSwhite;
-        if (color == 'red')
-        {
-           iconPath = iconVDSred;
-        }
-        else if (color == 'yellow')
-        {
-            iconPath = iconVDSyellow;
-        }
-        else if (color == 'lime')
-        {
-            iconPath = iconVDSgreen;
-        }
-        return {
-            url: iconPath, 
-            anchor: new google.maps.Point(6, 6)
-        };
-    }
-
     // Load the map data from a json file and style all the points
-    function loadVDSlayer()
+    function initializeVDSlayer()
     {
         // Load the static map data and call saveCoords when done
@@ -46,4 +24,27 @@
         });
     }
+
+    // Build a solid colored icon to use instead of the classic pin
+    function dotSymbol(color) 
+    {
+        var iconPath = iconVDSwhite;
+        if (color == 'red')
+        {
+           iconPath = iconVDSred;
+        }
+        else if (color == 'yellow')
+        {
+            iconPath = iconVDSyellow;
+        }
+        else if (color == 'lime')
+        {
+            iconPath = iconVDSgreen;
+        }
+        return {
+            url: iconPath, 
+            anchor: new google.maps.Point(6, 6)
+        };
+    }
+
     // callback when load GeoJson completes
     // save each feature's Point as the original coordinates for later reference
@@ -56,8 +57,7 @@
             vds_coords[feature.getId()] = pt; // save the Point in a dictionary
         });
-        // update the dot colors from the dynamic json data 
-        updateVDSlayer();
         // go adjust the marker coordinates so dots don't overlap
         adjustCoords(calcDistanceFactor());
+        processVDS();
     } 
 
@@ -114,4 +114,110 @@
     }
 
+    // Load the highways static json file and update the map
+    function resetVDSlayer()
+    {
+        eventIndex = -1;
+        loadJSON(kMapStartupFile, function(response)
+        {
+            // Parse JSON string into object
+            //initialVDSjson = JSON.parse(response);
+            // Process each new marker - lookup in current map
+            var initialVDSjsonFeatures = JSON.parse(response).features
+            initialVDSjsonFeatures.forEach(updateMarker);
+        });
+    }
+
+    function getColorName(str){
+        if (str === "R\r" || str === "R")
+            return "red";
+        else if (str === "Y\r" || str === "Y")
+            return "yellow";
+        else if (str === "G\r" || str === "G")
+            return "lime";
+    }
+
+// Parses the traffic events file and builds an array of target dots for each line
+    function processVDS() {
+        //var parsed_JSON;
+        loadJSON(kMapStartupFile, function(response)
+        { 
+            // Parse JSON string into object
+            parsed_JSON = JSON.parse(response);
+            // Process each new marker - lookup in current map
+            var parsed_features =  parsed_JSON.features;
+            parsed_features.forEach(updateMarker);
+            var eventsFile = '';
+            // Request the traffic events data file
+            var xmlhttp = new XMLHttpRequest();
+            xmlhttp.open("GET",trafficEventsFile,true); // Ask the server for the traffic events file
+            // Establish listener for handling the traffic events once file is read
+            xmlhttp.onreadystatechange = function()
+            {
+                if(xmlhttp.status == 200 && xmlhttp.readyState == 4)
+                {
+                    eventsFile = xmlhttp.responseText;
+                    // Process the traffic events file
+                    var lines = eventsFile.toString().split("\n");
+                    // For each line in the events file
+                    for (var line = 1; line < lines.length; line++) 
+                    {
+                        var trimmedLine = lines[line].trim();
+                        if (trimmedLine[0] !== '#') //ignores lines with #
+                        {
+                            var dots = [];                            
+                            var event = trimmedLine.split(/[ ,]+/);
+                            var start = parseFloat(event[4]); // extract postmile field
+                            var range = parseFloat(event[5]); // extract distance
+                            var newColor = getColorName(event[6]); // extract DotColor
+                            eventTimes.push(event[1]);  // extract the event time
+                            // Process each VDS in the highway network
+                            parsed_features.forEach(function (marker) {
+                                var marker_fields = marker.id.split(" ");
+                                // See if this marker's highway and direction match to this event
+                                if (marker_fields[0] === event[2] && marker_fields[1] === event[3])
+                                {   //computes difference in postmiles
+                                    var dist = parseFloat(marker_fields[2]) - start; 
+                                    // If this marker is within computed range
+                                    if (dist <= range && dist >= 0) 
+                                    {
+                                        // Add the marker to the dots representing this event
+                                        dots.push({"marker": marker, "color": newColor});
+                                    }
+                                }
+                            });
+                            targetDots.push(dots); // add this events dots to the list of targetdots
+                        } // end if
+                    }  // end for              
+                    // After the traffic events are processed,  go build the differences array
+                    buildDiff();      // side effect: leaves map with last event showing
+                    resetVDSlayer();  // restore the map to initial state
+                }
+            };
+            xmlhttp.send();
+        });
+    }
+
+    // Calls updateMarker for all targetDots after storing the previous marker in diff_arr 
+    // This function only needs to be done once, during startup.
+    function buildDiff() 
+    {
+        for (var i = 0; i <= targetDots.length; i++)
+        {
+            if  (targetDots[i] !== undefined)
+            {
+                var targetMarkers = new Array();
+                targetDots[i].forEach(function(item)
+                {
+                    item.marker.properties.color = item.color;
+                    storePrev(item.marker, targetMarkers);
+                    updateMarker(item.marker);
+                });
+                diff_arr.push(targetMarkers);
+            }
+        }
+    }
+    // Helper function for BuildDiff
+    // Store the previous colors of the targetDots
+    // so it will available if the user goes "back".
     function storePrev(marker, targetMarkers) 
     {
@@ -129,176 +235,88 @@
     }
 
-    // Load the highways dynamic json file and update the map
-    function updateVDSlayer()
-    {
-        index = -1;
-        var parsed_JSON;
-        loadJSON(kVDSstatusFile, function(response)
-        {
-            // Parse JSON string into object
-            parsed_JSON = JSON.parse(response);
-            // Process each new marker - lookup in current map
-            parsed_JSON.features.forEach(updateMarker);
-        });
-    }
-
-    function getColorName(str){
-        if (str === "R\r" || str === "R")
-            return "red";
-        else if (str === "Y\r" || str === "Y")
-            return "yellow";
-        else if (str === "G\r" || str === "G")
-            return "lime";
-    }
-
-    function processVDS() {
-        var parsed_JSON;
-        loadJSON(kVDSstatusFile, function(response)
-        { 
-            // Parse JSON string into object
-            parsed_JSON = JSON.parse(response);
-            // Process each new marker - lookup in current map
-            var array =  parsed_JSON.features;
-            var txt = '';
-            var xmlhttp = new XMLHttpRequest();
-            xmlhttp.onreadystatechange = function(){
-                if(xmlhttp.status == 200 && xmlhttp.readyState == 4){
-                    txt = xmlhttp.responseText;
-                    var lines = txt.toString().split("\n");
-                    for (var line = 1; line < lines.length; line++) {
-                        filters[line-1] = [];
-                        var event = lines[line].split(/[ ,]+/);
-                        var start = parseFloat(event[4]); // 7.73
-                        var range = parseFloat(event[5]); // 0.5
-                        var newColor = getColorName(event[6]); // "R"
-                        times.push(event[1]);
-                        array.forEach(function (marker) {
-                            var id_arr = marker.id.split(" ");
-                            if (id_arr[0] === event[2] && id_arr[1] === event[3]){
-                                var dist = parseFloat(id_arr[2]) - start; //difference of postmiles
-                                if (dist <= range && dist >= 0){
-                                    filters[line-1].push({"marker": marker, "color": newColor});
-                                }
-                            }
-                        });
-                    }
-                }
-            };
-            xmlhttp.open("GET",trafficEventsFile,true); //read traffic events text file
-            xmlhttp.send();
-        });
-    }
-      
-    // updates color for each marker based on color in filters array
-    function updateVDS(forwards) { 
-		if (forwards) {
-            index++;
-            if (index >= filters.length) 
-            {
-                index = filters.length - 1;
-            }
-            if  (filters[index] !== undefined) {
-                filters[index].forEach(function(item){
-                    item.marker.properties.color = item.color;
-                    updateMarker(item.marker);
-                });
-            }
-        }
-		else {
-            if  (diff_arr[index] !== undefined) {
-                diff_arr[index].forEach(function(item){
-                    updateMarker(item);
-                });
-            }
-            index--; 
-            if (index < -1)
-            {
-                index = -1;
-            }
-        }
-    }
-
-    function buildDiff() 
-    {
-        for (var i = 0; i <= filters.length; i++)
-        {
-            if  (filters[i] !== undefined)
-            {
-                var targetMarkers = new Array();
-                filters[i].forEach(function(item){
-                    item.marker.properties.color = item.color;
-                    storePrev(item.marker, targetMarkers);
-                    updateMarker(item.marker);
-                });
-                diff_arr.push(targetMarkers);
-            }
-        }
-    }
-
-function initVDSbutton()
-{
-
-    var vdsBtnDiv = document.getElementById('vdsButton');
-    map.controls[google.maps.ControlPosition.LEFT_BOTTOM].push(vdsBtnDiv)
-    vdsBtnDiv.title = 'Click to toggle vds view';
-
-    // Setup the click event listeners to toggle icon display
-    vdsBtnDiv.addEventListener('click', function()
-    {
-        vds_showing = !vds_showing;
-        // reveal or hide all the dots
-        map.data.forEach(function(feature)
-        {
-            map.data.overrideStyle(feature,
-            {
-                visible: vds_showing
+
+
+    // Increments the eventIndex from and updates all the targetDots on map
+    function updateForwards() {
+        eventIndex++;
+        // limit eventIndex to length of targetDots
+        if (eventIndex >= targetDots.length) 
+        {
+            eventIndex = targetDots.length - 1;
+        }
+        // update all the target dots
+        if  (targetDots[eventIndex] !== undefined) {
+            targetDots[eventIndex].forEach(function(item){
+                item.marker.properties.color = item.color;
+                updateMarker(item.marker);
             });
-        });
-        // Determine which button image to show
-        if (vds_showing)
-        {
-            pic = "images/btnDepressed_VDS.png"
-        }
-        else
-        {
-            pic = "images/btnReady_VDS.png"
-        }
-        document.getElementById('vdsBtnImg').src = pic;
-    });
-}
-
-// init beginning and next buttons as well as time display on map
-function initForwardbutton()
+        }
+    }
+
+    // Decrements the eventIndex and updates all the targetDots from diff_arr on map
+    function updateBackwards() {
+        //update each target dot in order to revert to previous color
+        if  (diff_arr[eventIndex] !== undefined) {
+            diff_arr[eventIndex].forEach(function(item){
+                updateMarker(item);
+            });
+        }
+        eventIndex--; 
+        // restrict eventIndex to -1
+        if (eventIndex < -1)
+        {
+            eventIndex = -1;
+        }
+    }
+    
+
+// init beginning, forward and back buttons as well as time display on map
+function initControlButtons()
 {
     var i = 0;
+    // setup the time display
     var time = document.getElementById('time');
     map.controls[google.maps.ControlPosition.BOTTOM_CENTER].push(time)
-    var start = document.getElementById('start');
-    map.controls[google.maps.ControlPosition.BOTTOM_CENTER].push(start)
-    start.title = 'Click to see the first event';
+    // set up the "beginning" button
+    var beginning = document.getElementById('beginning');
+    map.controls[google.maps.ControlPosition.BOTTOM_CENTER].push(beginning)
+    beginning.title = 'Click to see the first event';
+    // set up the "next" button
     var forward = document.getElementById('forward');
     map.controls[google.maps.ControlPosition.BOTTOM_CENTER].push(forward)
+    // set up the "back" button
 	var backward = document.getElementById('backward');
 	map.controls[google.maps.ControlPosition.BOTTOM_CENTER].push(backward)
     forward.title = 'Click to see the next event';
-    //console.log(diff_arr);
+    //console.log(targetDots, eventTimes);
+    // Establish the listeners for each button
     forward.addEventListener('click', function() {
-        updateVDS(1);
-        if (i < times.length - 1)
+        updateForwards();
+        backward.disabled = false;
+        if (i < eventTimes.length - 1) // get the next eventTime 
         {
             ++i;
-            time.innerHTML = times[i];
+            time.innerHTML = eventTimes[i];
+        }
+        if (eventIndex === targetDots.length - 1) // disable next button if last event reached
+        {
+            forward.disabled = true;
         }
     });
 	backward.addEventListener('click', function() {
-        updateVDS(0);
-        if (i > 0)
+        updateBackwards();
+        forward.disabled = false;
+        if (i > 0)  // get the prev eventTime 
         {
             --i;
-            time.innerHTML = times[i];
+            time.innerHTML = eventTimes[i];
+        }
+        if (eventIndex < 0) // disable back button if at first event 
+        {
+            backward.disabled = true;
         }
 	});
-    start.addEventListener('click', function() {
-        updateVDSlayer();
+    beginning.addEventListener('click', function() {
+        resetVDSlayer(); // redraw markers on map from startup file
         i = 0;
         time.innerHTML = "00:00:00";
