GUI -- TopoToolbarService created, working first set of toggles added.
- WIP on svg exercise (tabled to be worked on on another date)

Change-Id: I8d4ed84f0de44516419910dc5ee4c8eca7dc46ff
diff --git a/web/gui/src/main/webapp/_bripc/svg-exercise.html b/web/gui/src/main/webapp/_bripc/svg-exercise.html
index 676f71a..3952b6c 100644
--- a/web/gui/src/main/webapp/_bripc/svg-exercise.html
+++ b/web/gui/src/main/webapp/_bripc/svg-exercise.html
@@ -33,10 +33,11 @@
 
     <style>
         html,
-        body {
+        body, div {
             background-color: #eee;
             font-family: Arial, Helvetica, sans-serif;
             font-size: 9pt;
+            margin: 0;
         }
         .button {
             fill: #369;
diff --git a/web/gui/src/main/webapp/_bripc/svg-exercise.js b/web/gui/src/main/webapp/_bripc/svg-exercise.js
index f1491f4..a550192 100644
--- a/web/gui/src/main/webapp/_bripc/svg-exercise.js
+++ b/web/gui/src/main/webapp/_bripc/svg-exercise.js
@@ -28,13 +28,16 @@
     var btnWidth = 175,
         btnHeight = 50,
         hoverZone = 60,
+        sectorDivisions = 3,
         pageMargin = 20;
 
     // svg elements
-    var g;
+    var svg, g;
 
     // other variables
     var winWidth, winHeight,
+        sectorWidth, sectorHeight,
+        currSector = 4,
         mouse;
 
     // ====================================================
@@ -44,27 +47,112 @@
         return (axis / 2) - (dim / 2);
     }
 
-    function randomPos() {
+    // ====================================================
+
+    function center(elem) {
+        $log.debug(winWidth / 2);
+        $log.debug(winHeight / 2);
+        $log.debug((winWidth / 2) - ((elem.node().getBBox().width) / 2));
+        $log.debug((winHeight / 2) - ((elem.node().getBBox().height) / 2));
         return {
-            x: Math.random() * winWidth,
-            y: Math.random() * winHeight
+            x: (winWidth / 2) - ((elem.node().getBBox().width) / 2),
+            y: (winHeight / 2) - ((elem.node().getBBox().height) / 2)
         }
     }
 
-    function getPosition() {
-        var x = randomPos().x + pageMargin,
-            y = randomPos().y + pageMargin,
-            x1 = x + btnWidth,
-            y1 = y + btnHeight,
-            wwMargin = winWidth - pageMargin,
-            whMargin = winHeight - pageMargin;
+    function showSectors() {
+        svg.append('line')
+            .attr({
+                x1: winWidth / 2,
+                x2: winWidth / 2,
+                y1: 0,
+                y2: winHeight,
+                stroke: 'purple',
+                'stroke-width': '3px'
+            });
+        svg.append('line')
+            .attr({
+                x1: 0,
+                x2: winWidth,
+                y1: winHeight / 2,
+                y2: winHeight / 2,
+                stroke: 'purple',
+                'stroke-width': '3px'
+            });
+        for (var i = 1; i < 5; i++) {
+            var j;
+            if (i < 3) {
+                j = i;
+                svg.append('line')
+                    .attr({
+                        x1: sectorWidth * j,
+                        x2: sectorWidth * j,
+                        y1: 0,
+                        y2: winHeight,
+                        stroke: 'red',
+                        'stroke-width': '3px'
+                    });
+            }
+            else {
+                j = i - 2;
+                svg.append('line')
+                    .attr({
+                        x1: 0,
+                        x2: winWidth,
+                        y1: sectorHeight * j,
+                        y2: sectorHeight * j,
+                        stroke: 'red',
+                        'stroke-width': '3px'
+                    });
+            }
+        }
+    }
 
-        while (x1 >= wwMargin || y1 >= whMargin) {
-            x = randomPos().x + pageMargin;
-            y = randomPos().y + pageMargin;
+    function onMouseMove() {
+        mouse = d3.mouse(this);
+        moveButton();
+    }
+
+    function removeMouseListener() {
+        g.on('mousemove', null);
+    }
+
+    function addMouseListener() {
+        g.on('mousemove', onMouseMove);
+    }
+
+    function selectSector() {
+        var sector, row, col;
+
+        do {
+            sector = Math.floor((Math.random() * 9));
+        } while (sector === currSector);
+        $log.debug('sector after loop: ' + sector);
+        $log.debug('currSector after loop: ' + currSector);
+        currSector = sector;
+        $log.debug('currSector after assignment: ' + currSector);
+        row = Math.floor(sector / sectorDivisions);
+        col = sector % sectorDivisions;
+
+        $log.debug('row: ' + row);
+        $log.debug('col: ' + col);
+
+        return {
+            xmin: sectorWidth * col,
+            xmax: (sectorWidth * col) + sectorWidth,
+            ymin: sectorHeight * row,
+            ymax: (sectorHeight * row) + sectorHeight
+        }
+    }
+
+    function selectXY(sectorCoords) {
+        var x, y, x1, y1;
+        do {
+            x = (Math.random() * sectorCoords.xmax) + sectorCoords.xmin;
+            y = (Math.random() * sectorCoords.ymax) + sectorCoords.ymin;
             x1 = x + btnWidth;
             y1 = y + btnHeight;
-        }
+        } while (x1 >= winWidth - pageMargin || y1 >= winHeight - pageMargin);
 
         return {
             x: x,
@@ -77,13 +165,15 @@
     }
 
     function moveButton() {
-        var pos = getPosition(),
-            x = pos.x,
-            y = pos.y;
+        var sec = selectSector(),
+            pos = selectXY(sec);
+        $log.debug(pos.x, pos.y);
         g.transition()
             .duration(400)
             .ease('cubic-out')
-            .attr('transform', gTranslate(x, y));
+            .each('start', removeMouseListener)
+            .attr('transform', gTranslate(pos.x, pos.y))
+            .each('end', addMouseListener);
     }
 
     angular.module('svgExercise', ['onosUtil'])
@@ -99,16 +189,22 @@
                 link: function (scope, elem, attrs) {
                     winWidth = fs.windowSize().width;
                     winHeight = fs.windowSize().height;
-                    var svg = d3.select(elem[0])
+                    // getting rid of pageMargin to see if the math is easier
+                    // could put the padding somewhere else as in where it's ok to move the button
+                    //sectorWidth = (winWidth / sectorDivisions) - pageMargin;
+                    //sectorHeight = (winHeight / sectorDivisions) - pageMargin;
+                    sectorWidth = winWidth / sectorDivisions;
+                    sectorHeight = winHeight / sectorDivisions;
+
+                    svg = d3.select(elem[0])
                         .append('svg')
                         .attr({
                             width: winWidth + 'px',
                             height: winHeight + 'px'
                         });
-                    g = svg.append('g')
-                        .attr('transform',
-                            gTranslate(centeredOnWindow(winWidth, btnWidth),
-                                       centeredOnWindow(winHeight, btnHeight)));
+
+                    showSectors();
+                    g = svg.append('g');
 
                     var button = g.append('rect')
                             .attr({
@@ -132,13 +228,14 @@
                                 height: btnHeight + hoverZone + 'px',
                                 x: -(hoverZone / 2),
                                 y: -(hoverZone / 2)
-                            });
+                            }),
+                        centeredG = center(g);
+                    g.attr('transform',
+                        gTranslate(centeredG.x, centeredG.y));
+                    //gTranslate(centeredOnWindow(winWidth, btnWidth),
+                    //           centeredOnWindow(winHeight, btnHeight)));
 
-                        g.on('mousemove', function () {
-                        mouse = d3.mouse(this);
-                        moveButton();
-                    });
-
+                    addMouseListener();
                 }
             };
         }]);
diff --git a/web/gui/src/main/webapp/app/view/topo/topo.js b/web/gui/src/main/webapp/app/view/topo/topo.js
index 2a6d037..5156fb0 100644
--- a/web/gui/src/main/webapp/app/view/topo/topo.js
+++ b/web/gui/src/main/webapp/app/view/topo/topo.js
@@ -29,20 +29,20 @@
 
     // references to injected services etc.
     var $log, fs, ks, zs, gs, ms, sus, flash, wss,
-        tes, tfs, tps, tis, tss, tts, tos;
+        tes, tfs, tps, tis, tss, tts, tos, ttbs;
 
     // DOM elements
     var ovtopo, svg, defs, zoomLayer, mapG, forceG, noDevsLayer;
 
     // Internal state
-    var zoomer;
+    var zoomer, actionMap;
 
     // --- Short Cut Keys ------------------------------------------------
 
     function setUpKeys() {
         // key bindings need to be made after the services have been injected
         // thus, deferred to here...
-        ks.keyBindings({
+        actionMap = {
             O: [tps.toggleSummary, 'Toggle ONOS summary pane'],
             I: [toggleInstances, 'Toggle ONOS instances pane'],
             D: [tss.toggleDetails, 'Disable / enable details pane'],
@@ -74,7 +74,9 @@
                 ['X', 'Z', 'L', 'U', 'R' ],
                 ['V', 'rightArrow', 'leftArrow', 'W', 'A', 'F', '-', 'E' ]
             ]
-        });
+        };
+
+        ks.keyBindings(actionMap);
 
         ks.gestureNotes([
             ['click', 'Select the item and show details'],
@@ -132,6 +134,20 @@
         }
     }
 
+    // --- Toolbar Functions ---------------------------------------------
+
+    function getActionEntry(key) {
+        var entry = actionMap[key];
+        return fs.isA(entry) || [entry, ''];
+    }
+
+    function setUpToolbar() {
+        ttbs.init({
+            getActionEntry: getActionEntry
+        });
+        ttbs.createToolbar();
+    }
+
     // --- Glyphs, Icons, and the like -----------------------------------
 
     function setUpDefs() {
@@ -220,11 +236,11 @@
             'WebSocketService',
             'TopoEventService', 'TopoForceService', 'TopoPanelService',
             'TopoInstService', 'TopoSelectService', 'TopoTrafficService',
-            'TopoObliqueService',
+            'TopoObliqueService', 'TopoToolbarService',
 
         function ($scope, _$log_, $loc, $timeout, _fs_, mast,
                   _ks_, _zs_, _gs_, _ms_, _sus_, _flash_, _wss_,
-                  _tes_, _tfs_, _tps_, _tis_, _tss_, _tts_, _tos_) {
+                  _tes_, _tfs_, _tps_, _tis_, _tss_, _tts_, _tos_, _ttbs_) {
             var self = this,
                 projection,
                 dim,
@@ -256,6 +272,7 @@
             tss = _tss_;
             tts = _tts_;
             tos = _tos_;
+            ttbs = _ttbs_;
 
             self.notifyResize = function () {
                 svgResized(fs.windowSize(mast.mastHeight()));
@@ -278,6 +295,7 @@
             dim = [svg.attr('width'), svg.attr('height')];
 
             setUpKeys();
+            setUpToolbar();
             setUpDefs();
             setUpZoom();
             setUpNoDevs();
diff --git a/web/gui/src/main/webapp/app/view/topo/topoToolbar.js b/web/gui/src/main/webapp/app/view/topo/topoToolbar.js
new file mode 100644
index 0000000..80351a3
--- /dev/null
+++ b/web/gui/src/main/webapp/app/view/topo/topoToolbar.js
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ ONOS GUI -- Topology Toolbar Module.
+ Defines functions for manipulating the toolbar.
+ */
+
+(function () {
+
+    // injected references
+    var $log, tbs;
+
+    var api, toolbar;
+
+    // buttons (named for keystroke)
+    var O, I, D, H, M, P, B;
+    var togSummary, togInstances, togDetails,
+        togHosts, togOffline, togPorts, togBackground;
+
+    function init(_api_) {
+        api = _api_;
+    }
+
+    function getActions() {
+        togSummary = api.getActionEntry('O');
+        togInstances = api.getActionEntry('I');
+        togDetails = api.getActionEntry('D');
+
+        togHosts = api.getActionEntry('H');
+        togOffline = api.getActionEntry('M');
+        togPorts = api.getActionEntry('P');
+        togBackground = api.getActionEntry('B');
+    }
+
+    function entryCallback(entry) {
+        return entry[0];
+    }
+
+    function entryToolTip(entry) {
+        return entry[1];
+    }
+
+    function createToolbar() {
+        getActions();
+        // in actions, function reference is entry[0], tooltip is entry[1]
+        toolbar = tbs.createToolbar('topo-tbar');
+        toolbar.addToggle('summary-tog', 'unknown', true,
+            entryCallback(togSummary), entryToolTip(togSummary));
+        toolbar.addToggle('instance-tog', 'unknown', true,
+            entryCallback(togInstances), entryToolTip(togInstances));
+        toolbar.addToggle('details-tog', 'unknown', true,
+            entryCallback(togDetails), entryToolTip(togDetails));
+        toolbar.addSeparator();
+
+        toolbar.addToggle('hosts-tog', 'endstation', false,
+            entryCallback(togHosts), entryToolTip(togHosts));
+        toolbar.addToggle('offline-tog', 'unknown', true,
+            entryCallback(togOffline), entryToolTip(togOffline));
+        toolbar.addToggle('ports-tog', 'unknown', true,
+            entryCallback(togPorts), entryToolTip(togPorts));
+        toolbar.addToggle('bkgrnd-tog', 'unknown', true,
+            entryCallback(togBackground), entryToolTip(togBackground));
+
+        toolbar.hide();
+    }
+
+    angular.module('ovTopo')
+        .factory('TopoToolbarService', ['$log', 'ToolbarService',
+
+        function (_$log_, _tbs_) {
+            $log = _$log_;
+            tbs = _tbs_;
+
+            return {
+                init: init,
+                createToolbar: createToolbar
+            };
+        }]);
+}());
\ No newline at end of file
diff --git a/web/gui/src/main/webapp/index.html b/web/gui/src/main/webapp/index.html
index 05154c7..149ad6e 100644
--- a/web/gui/src/main/webapp/index.html
+++ b/web/gui/src/main/webapp/index.html
@@ -97,6 +97,7 @@
     <script src="app/view/topo/topoPanel.js"></script>
     <script src="app/view/topo/topoSelect.js"></script>
     <script src="app/view/topo/topoTraffic.js"></script>
+    <script src="app/view/topo/topoToolbar.js"></script>
     <script src="app/view/device/device.js"></script>
     <!-- {INJECTED-JAVASCRIPT-END} -->