Topo2: Refactored Hide, Show and Toggle methods to the ViewController

Change-Id: I63c9a0cf99f7e631a6b0000c28b637e5983c35c8
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2KeyCommands.js b/web/gui/src/main/webapp/app/view/topo2/topo2KeyCommands.js
index 4f65679..0f54273 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2KeyCommands.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2KeyCommands.js
@@ -17,7 +17,7 @@
 (function () {
 
     // Injected Services
-    var ks, flash, wss, t2ps, t2ms, ps, t2is, t2sp, t2vs, t2rs, t2fs;
+    var ks, flash, wss, t2ps, t2ms, ps, t2is, t2sp, t2vs, t2rs, t2fs, t2sls;
 
     // Commmands
     var actionMap = {
@@ -31,6 +31,7 @@
         E: [equalizeMasters, 'Equalize mastership roles'],
         X: [resetAllNodeLocations, 'Reset Node Location'],
         U: [unpinNode, 'Unpin node (mouse over)'],
+        S: [toggleSpriteLayer, 'Toggle sprite layer'],
 
         esc: handleEscape
     };
@@ -119,6 +120,10 @@
         flash.flash('Pan and zoom reset');
     }
 
+    function toggleSpriteLayer() {
+        t2sls.toggle();
+    }
+
     function togglePorts(x) {
         updatePrefsState('porthl', t2vs.togglePortHighlights(x));
         t2fs.updateLinks();
@@ -144,8 +149,9 @@
         'KeyService', 'FlashService', 'WebSocketService', 'Topo2PrefsService',
         'Topo2MapService', 'PrefsService', 'Topo2InstanceService',
         'Topo2SummaryPanelService', 'Topo2ViewService', 'Topo2RegionService',
+        'Topo2SpriteLayerService',
         function (_ks_, _flash_, _wss_, _t2ps_, _t2ms_, _ps_, _t2is_, _t2sp_,
-                  _t2vs_, _t2rs_) {
+                  _t2vs_, _t2rs_, _t2sls_) {
 
             ks = _ks_;
             flash = _flash_;
@@ -157,6 +163,7 @@
             t2sp = _t2sp_;
             t2vs = _t2vs_;
             t2rs = _t2rs_;
+            t2sls = _t2sls_;
 
             return {
                 init: init,
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2Map.js b/web/gui/src/main/webapp/app/view/topo2/topo2Map.js
index ff595e7..aa9766e 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2Map.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2Map.js
@@ -29,12 +29,12 @@
     var MapSelectionDialog;
 
     // internal state
-    var mapG, zoomLayer, zoomer;
+    var instance, mapG, zoomLayer, zoomer;
 
     function init(_zoomLayer_, _zoomer_) {
         zoomLayer = _zoomLayer_;
         zoomer = _zoomer_;
-        return setUpMap();
+        return setUpMap.bind(this)();
     }
 
     function setUpMap() {
@@ -50,11 +50,15 @@
         if (mapG.empty()) {
             mapG = zoomLayer.append('g').attr('id', 'topo-map');
         } else {
-            mapG.each(function (d, i) {
+            mapG.each(function () {
                 d3.selectAll(this.childNodes).remove();
             });
         }
 
+        if (!ps.getPrefs('topo_prefs')[this.prefs.visible]) {
+            this.hide();
+        }
+
         if (mapFilePath === '*countries') {
             cfilter = countryFilters[mapId] || countryFilters.uk;
             loadMap = ms.loadMapRegionInto;
@@ -66,10 +70,6 @@
             shading: ''
         });
 
-        if (!ps.getPrefs('topo_prefs').bg) {
-            toggle(false);
-        }
-
         return promise;
     }
 
@@ -86,55 +86,13 @@
         );
     }
 
-    function opacifyMap(b) {
-        mapG.transition()
-            .duration(1000)
-            .attr('opacity', b ? 1 : 0);
-    }
-
     function setMap(map) {
         ps.setPrefs('topo_mapid', map);
-        opacifyMap(true);
-        return setUpMap();
-    }
-
-    // TODO: -- START -- Move to dedicated module
-    var prefsState = {};
-
-    function updatePrefsState(what, b) {
-        prefsState[what] = b ? 1 : 0;
-        ps.setPrefs('topo_prefs', prefsState);
-    }
-
-    function _togSvgLayer(x, G, tag, what) {
-        var on = (x === 'keyev') ? !sus.visible(G) : Boolean(x),
-            verb = on ? 'Show' : 'Hide';
-        sus.visible(G, on);
-        updatePrefsState(tag, on);
-
-        if (x === 'keyev') {
-            flash.flash(verb + ' ' + what);
-        }
-
-        return on;
-    }
-    // TODO: -- END -- Move to dedicated module
-
-    function show() {
-        sus.visible(mapG, true);
-    }
-
-    function hide() {
-        sus.visible(mapG, false);
-    }
-
-    function toggle(x) {
-        return _togSvgLayer(x, mapG, 'bg', 'background map');
+        return setUpMap.bind(this)();
     }
 
     function openMapSelection() {
 
-        // TODO: Create a view class with extend method
         MapSelectionDialog.prototype.currentMap = currentMap;
 
         new MapSelectionDialog({
@@ -149,31 +107,32 @@
     }
 
     angular.module('ovTopo2')
-    .factory('Topo2MapService',
-        ['$location', 'PrefsService', 'MapService', 'FlashService',
-            'SvgUtilService', 'Topo2CountryFilters', 'Topo2MapDialog',
-            function (_$loc_, _ps_, _ms_, _flash_, _sus_, _t2cf_, _t2md_) {
+    .factory('Topo2MapService', [
+        '$location', 'Topo2ViewController', 'PrefsService', 'MapService', 'FlashService',
+        'SvgUtilService', 'Topo2CountryFilters', 'Topo2MapDialog',
 
-                $loc = _$loc_;
-                ps = _ps_;
-                ms = _ms_;
-                flash = _flash_;
-                sus = _sus_;
-                countryFilters = _t2cf_;
-                MapSelectionDialog = _t2md_;
+        function (_$loc_, ViewController, _ps_, _ms_, _flash_, _sus_, _t2cf_, _t2md_) {
 
-                return {
-                    init: init,
-                    setMap: setMap,
-                    openMapSelection: openMapSelection,
+            $loc = _$loc_;
+            ps = _ps_;
+            ms = _ms_;
+            flash = _flash_;
+            sus = _sus_;
+            countryFilters = _t2cf_;
+            MapSelectionDialog = _t2md_;
 
-                    show: show,
-                    hide: hide,
-                    toggle: toggle,
+            var MapLayer = ViewController.extend({
 
-                    resetZoom: resetZoom
-                };
-            }
-        ]);
+                id: 'topo-map',
+                displayName: 'Map',
 
+                init: init,
+                setMap: setMap,
+                openMapSelection: openMapSelection,
+                resetZoom: resetZoom
+            });
+
+            return instance || new MapLayer();
+        }
+    ]);
 })();
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2Region.js b/web/gui/src/main/webapp/app/view/topo2/topo2Region.js
index bb8e0db..0202ca9 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2Region.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2Region.js
@@ -53,22 +53,26 @@
                     if (data.bgType === 'geo') {
                         t2ms.setMap({
                             mapid: data.bgId,
-
-                            // TODO: The following value will be specified in the Topo2CurrentLayout Payload
-                            mapfilepath: "*bayarea"
+                            mapfilepath: data.bgFilePath
                         }).then(function () {
                             _.each(_this.regionNodes(), function (node) {
                                 node.resetPosition();
                             });
                         });
-                        t2ms.show();
+
+                        if (t2ms.enabled()) {
+                            t2ms.show();
+                        }
                     } else {
                         t2ms.hide();
                     }
 
                     if (data.bgType === 'grid') {
                         t2sls.loadLayout(data.bgId);
-                        t2sls.show();
+
+                        if (t2sls.enabled()) {
+                            t2sls.show();
+                        }
                     } else {
                         t2sls.hide();
                     }
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2SpriteLayer.js b/web/gui/src/main/webapp/app/view/topo2/topo2SpriteLayer.js
index 411d130..1701f6b 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2SpriteLayer.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2SpriteLayer.js
@@ -36,10 +36,14 @@
             function (ViewController, ss) {
 
                 var SpriteLayer = ViewController.extend({
+
+                    id: 'topo-sprites',
+                    displayName: 'Sprite Layer',
+
                     init: function(svg, zoomLayer) {
                         this.svg = svg;
                         this.createSpriteDefs();
-                        this.container = zoomLayer.append('g').attr('id', 'topo-sprites');
+                        this.container = zoomLayer.append('g').attr('id', this.id);
                     },
                     loadLayout: function (id) {
                         this.container.selectAll("*").remove();
@@ -111,27 +115,6 @@
                                 .attr('x', spriteData.x)
                                 .attr('y', spriteData.y);
                         });
-                    },
-
-                    hide: function () {
-                        if (this.visible) {
-                            this.container
-                                .style('opacity', 1)
-                                .transition()
-                                .duration(400)
-                                .style('opacity', 0);
-                        }
-                        this.visible = false;
-                    },
-                    show: function () {
-                        if (!this.visible) {
-                            this.container
-                                .style('opacity', 0)
-                                .transition()
-                                .duration(400)
-                                .style('opacity', 1);
-                        }
-                        this.visible = true;
                     }
                 });
 
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2ViewController.js b/web/gui/src/main/webapp/app/view/topo2/topo2ViewController.js
index 9d9f399..ac475be 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2ViewController.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2ViewController.js
@@ -22,20 +22,79 @@
 (function () {
     'use strict';
 
+    var flash, ps;
+
     function ViewController(options) {
         this.initialize.apply(this, arguments);
     }
 
     ViewController.prototype = {
-        initialize: function () {
 
+        id: null,
+        displayName: 'View',
+
+        initialize: function () {
+            this.name = this.displayName.toLowerCase().replace(/ /g,"_");
+            this.prefs = {
+                visible: this.name + '_visible'
+            }
+        },
+        node: function() {
+            return d3.select('#' + this.id);
+        },
+        enabled: function () {
+            return ps.getPrefs('topo_prefs')[this.prefs.visible];
+        },
+        isVisible: function () {
+            return this.node().style('visibility') === 'visible';
+        },
+        hide: function () {
+            var node = this.node();
+
+            if (this.isVisible()) {
+                node
+                    .transition()
+                    .duration(400)
+                    .style('opacity', 0)
+                    .each('end', function () {
+                        node.style('visibility', 'hidden')
+                    });
+            }
+        },
+        show: function () {
+            var node = this.node();
+
+            if (!this.isVisible()) {
+                node
+                    .style('visibility', 'visible')
+                    .transition()
+                    .duration(400)
+                    .style('opacity', 1)
+            }
+        },
+        toggle: function () {
+            var on = !Boolean(this.isVisible()),
+                verb = on ? 'Show' : 'Hide';
+
+            on ? this.show() : this.hide();
+            flash.flash(verb + ' ' + this.displayName);
+            this.updatePrefState(this.prefs.visible, on);
+        },
+        updatePrefState: function (key, value) {
+            var state = ps.getPrefs('topo_prefs');
+            state[key] = value ? 1 : 0;
+            ps.setPrefs('topo_prefs', state);
         }
     };
 
     angular.module('ovTopo2')
         .factory('Topo2ViewController', [
-            'FnService',
-            function (fn) {
+            'FnService', 'FlashService', 'PrefsService',
+            function (fn, _flash_, _ps_) {
+
+                flash = _flash_;
+                ps = _ps_;
+
                 ViewController.extend = fn.extend;
                 return ViewController;
             }