ONOS-7190 - Adding the missing Toolbar items (for current functionality)
ONOS-7188 - Added Overlay Key Commands

The traffic overlay was added to the Toolbar for testing purposes

Change-Id: I59947080763a3fa67394f3a0e222b99491d4b646
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2.js b/web/gui/src/main/webapp/app/view/topo2/topo2.js
index 35a3b1e..94a704f 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2.js
@@ -25,7 +25,7 @@
 
     // references to injected services
     var $scope, $log, fs, mast, ks, wss,
-        gs, sus, t2es, t2fs, t2is, t2bcs, t2kcs, t2ms, t2zs;
+        gs, sus, t2es, t2fs, t2is, t2bcs, t2kcs, t2ms, t2zs, t2ts;
 
     // DOM elements
     var ovtopo2, svg, defs, zoomLayer, forceG;
@@ -100,7 +100,7 @@
         'Topo2BreadcrumbService', 'Topo2KeyCommandService', 'Topo2MapService',
         'Topo2ZoomService', 'Topo2SpriteLayerService',
         'Topo2SummaryPanelService', 'Topo2DeviceDetailsPanel', 'Topo2ToolbarService',
-        'Topo2NoDevicesConnectedService', 'Topo2OverlayService',
+        'Topo2NoDevicesConnectedService', 'Topo2OverlayService', 'Topo2TrafficService',
 
         function (
             _$scope_, _$log_, _$loc_,
@@ -109,7 +109,8 @@
             _t2es_, _t2fs_, _t2is_,
             _t2bcs_, _t2kcs_, _t2ms_,
             _t2zs_, t2sls,
-            summaryPanel, detailsPanel, t2tbs, t2ndcs, t2os
+            summaryPanel, detailsPanel, t2tbs, t2ndcs, t2os,
+            _t2ts_
         ) {
             var params = _$loc_.search(),
                 dim,
@@ -136,6 +137,7 @@
             t2kcs = _t2kcs_;
             t2ms = _t2ms_;
             t2zs = _t2zs_;
+            t2ts = _t2ts_;
 
             // capture selected intent parameters (if they are set in the
             //  query string) so that the traffic overlay can highlight
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2HostsPanel.js b/web/gui/src/main/webapp/app/view/topo2/topo2HostsPanel.js
index f8273b2..73a2325 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2HostsPanel.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2HostsPanel.js
@@ -65,7 +65,6 @@
         init();
 
         hostData = formatHostData(data);
-        console.log(data);
         render();
     }
 
@@ -88,7 +87,6 @@
 
         title.text(hostData.title);
         gs.addGlyph(svg, 'bird', 24, 0, [1, 1]);
-        console.log()
         ls.listProps(tbody, hostData);
     }
 
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 feef3b5..25cea72 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2KeyCommands.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2KeyCommands.js
@@ -43,6 +43,13 @@
 
             esc: handleEscape,
 
+            // topology overlay selections
+            F1: function () { t2tbs.fnKey(0); },
+            F2: function () { t2tbs.fnKey(1); },
+            F3: function () { t2tbs.fnKey(2); },
+            F4: function () { t2tbs.fnKey(3); },
+            F5: function () { t2tbs.fnKey(4); },
+
             _keyListener: t2tbs.keyListener.bind(t2tbs),
 
             _helpFormat: [
@@ -241,7 +248,7 @@
         'Topo2RegionService', 'Topo2DetailsPanelService', 'SvgUtilService',
 
         function (_$log_, _fs_, _ks_, _flash_, _wss_, _t2ps_, _t2bgs_, _ps_,
-                  _t2is_, _t2sp_, _t2vs_, _t2rs_, _t2dp_, _sus_) {
+                  _t2is_, _t2sp_, _t2vs_, _t2rs_, _t2dp_, _t2tbs_, _sus_) {
 
             $log = _$log_;
             fs = _fs_;
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2Overlay.js b/web/gui/src/main/webapp/app/view/topo2/topo2Overlay.js
index 49f76ea..1f26220 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2Overlay.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2Overlay.js
@@ -26,7 +26,8 @@
 
     // internal state
     var overlays = {},
-        current = null;
+        current = null,
+        reset = true;
 
     function error(fn, msg) {
         $log.error(t2os + fn + '(): ' + msg);
@@ -36,6 +37,39 @@
         $log.warn(t2os + fn + '(): ' + msg);
     }
 
+    function mkGlyphId(oid, gid) {
+        return (gid[0] === '*') ? oid + '-' + gid.slice(1) : gid;
+    }
+
+    function handleGlyphs(o) {
+        var gdata = fs.isO(o.glyphs),
+            oid = o.overlayId,
+            gid = o.glyphId || 'unknown',
+            data = {},
+            note = [];
+
+        o._glyphId = mkGlyphId(oid, gid);
+
+        o.mkGid = function (g) {
+            return mkGlyphId(oid, g);
+        };
+        o.mkId = function (s) {
+            return oid + '-' + s;
+        };
+
+        // process glyphs if defined
+        if (gdata) {
+            angular.forEach(gdata, function (value, key) {
+                var fullkey = oid + '-' + key;
+                data['_' + fullkey] = value.vb;
+                data[fullkey] = value.d;
+                note.push('*' + key);
+            });
+            gs.registerGlyphs(data);
+            $log.debug('registered overlay glyphs:', oid, note);
+        }
+    }
+
     function register(overlay) {
         var r = 'register',
             over = fs.isO(overlay),
@@ -49,7 +83,7 @@
             return warn(r, 'already registered: "' + id + '"');
         }
         overlays[id] = overlay;
-        // TODO handleGlyphs(overlay) ... see topoOverlay.js
+        handleGlyphs(overlay);
 
         if (kb) {
             if (!fs.isA(kb._keyOrder)) {
@@ -66,6 +100,48 @@
         $log.debug(t2os + 'registered overlay: ' + id, overlay);
     }
 
+    // add a radio button for each registered overlay
+    // return an overlay id to index map
+    function augmentRbset(rset, switchFn) {
+        var map = {},
+            idx = 1;
+
+        angular.forEach(overlays, function (ov) {
+            rset.push({
+                gid: ov._glyphId,
+                tooltip: (ov.tooltip || ''),
+                cb: function () {
+                    tbSelection(ov.overlayId, switchFn);
+                },
+            });
+            map[ov.overlayId] = idx++;
+        });
+        return map;
+    }
+
+    // an overlay was selected via toolbar radio button press from user
+    function tbSelection(id, switchFn) {
+        var same = current && current.overlayId === id,
+            payload = {},
+            actions;
+
+        function doop(op) {
+            var oid = current.overlayId;
+            $log.debug('Overlay:', op, oid);
+            current[op]();
+            payload[op] = oid;
+        }
+
+        if (reset || !same) {
+            current && doop('deactivate');
+            current = overlays[id];
+            current && doop('activate');
+            actions = current && fs.isO(current.keyBindings);
+            switchFn(id, actions);
+            // TODO: Update Summary Panel
+        }
+    }
+
     // TODO: check topoOverlay.js for more code
     // TODO: medium term -- factor out common code
     // TODO: longer term -- deprecate classic topology view
@@ -163,6 +239,9 @@
             return {
                 register: register,
                 setOverlay: setOverlay,
+                augmentRbset: augmentRbset,
+                tbSelection: tbSelection,
+                mkGlyphId: mkGlyphId,
 
                 hooks: {
                     escape: escapeHook,
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2Toolbar.js b/web/gui/src/main/webapp/app/view/topo2/topo2Toolbar.js
index ae1cc90..c9e5285 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2Toolbar.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2Toolbar.js
@@ -26,13 +26,12 @@
     var k2b = {
         O: { id: 'topo2-summary-tog', gid: 'm_summary', isel: true },
         I: { id: 'topo2-instance-tog', gid: 'm_uiAttached', isel: true },
-        // D: { id: 'details-tog', gid: 'm_details', isel: true },
-        // H: { id: 'hosts-tog', gid: 'm_endstation', isel: false },
-        // M: { id: 'offline-tog', gid: 'm_switch', isel: true },
+        D: { id: 'details-tog', gid: 'm_details', isel: true },
+        H: { id: 'hosts-tog', gid: 'm_endstation', isel: false },
+        M: { id: 'offline-tog', gid: 'm_switch', isel: true },
         P: { id: 'topo2-ports-tog', gid: 'm_ports', isel: true },
         B: { id: 'topo2-bkgrnd-tog', gid: 'm_map', isel: true },
 
-        // Z: { id: 'oblique-tog', gid: 'm_oblique', isel: false },
         // N: { id: 'filters-btn', gid: 'm_filters' },
         L: { id: 'topo2-cycleLabels-btn', gid: 'm_cycleLabels' },
         R: { id: 'topo2-resetZoom-btn', gid: 'm_resetZoom' },
@@ -43,7 +42,8 @@
     angular.module('ovTopo2')
         .factory('Topo2ToolbarService', [
             'FnService', 'ToolbarService', 'Topo2KeyCommandService',
-            function (fs, tbs, t2kcs) {
+            'Topo2OverlayService',
+            function (fs, tbs, t2kcs, t2ov) {
 
                 var Toolbar = function () {
                     instance = this;
@@ -55,11 +55,14 @@
 
                     init: function () {
                         this.el = tbs.createToolbar(this.className);
+                        this.radioSet;
+                        this.ovIndex;
+
                         this.initKeyData();
                         this.addFirstRow();
                         this.el.addRow();
                         this.addSecondRow();
-
+                        this.addOverlays();
                         this.el.hide();
                     },
                     initKeyData: function () {
@@ -97,20 +100,34 @@
                         this.el.toggle();
                     },
 
+                    selectOverlay: function (ovid) {
+                        var index = this.ovIndex[defaultOverlay] || 0,
+                            pidx = (ovid === null) ? 0 : this.ovIndex[ovid] || -1;
+                        if (pidx >= 0 && pidx < this.radioSet.size()) {
+                            index = pidx;
+                        }
+
+                        this.radioSet.selectedIndex(index);
+                    },
+
+                    fnKey: function (index) {
+                        if (index < this.radioSet.size() && index !== this.radioSet.selectedIndex()) {
+                            this.radioSet.selectedIndex(index);
+                        }
+                    },
+
                     addFirstRow: function () {
                         this.addToggle('I');
                         this.addToggle('O');
-                        // this.addToggle('D');
+                        this.addToggle('D');
                         this.el.addSeparator();
 
-                        // this.addToggle('H');
-                        // this.addToggle('M');
+                        this.addToggle('H');
+                        this.addToggle('M');
                         this.addToggle('P', true);
                         this.addToggle('B');
                     },
                     addSecondRow: function () {
-                        // addToggle('X');
-                        // this.addToggle('Z');
                         // this.addButton('N');
                         this.addButton('L');
                         this.addButton('R');
@@ -118,6 +135,28 @@
                         this.addButton('E');
                     },
 
+                    switchOverlayActions: function () {
+                        // TODO: see TopoToolbar.js
+                        // NOTE: Should add overlay buttons on the third row
+                    },
+
+                    addOverlays: function () {
+                        var _this = this; // Keep context in callback
+                        this.el.addSeparator();
+
+                        // generate radio button set for overlays; start with 'none'
+                        var rset = [{
+                            gid: 'm_unknown',
+                            tooltip: 'ov_tt_none',
+                            cb: function () {
+                                t2ov.tbSelection(null, _this.switchOverlayActions);
+                            },
+                        }];
+
+                        t2ov.augmentRbset(rset, this.switchOverlayActions);
+                        this.radioSet = this.el.addRadioSet('topo-overlays', rset);
+                    },
+
                     destroy: function () {
                         // TODO: Should the tbs remove button id's in the destroyToolbar method?
                         // If you go topo2 -> topo -> topo2 there's a button id conflict