Topo2 - Animate the position of the details panel based on SummaryPanel visiblity
JIRA Tasks; ONOS-6294

Change-Id: I0aaf71021cadd529cf0f5c591cd91de22b396f7a
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 2913953..1ecd420 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2.js
@@ -224,8 +224,8 @@
 
             // $log.debug('registered overlays...', tov.list());
 
-            summaryPanel.init();
-            detailsPanel.init();
+            summaryPanel.init(detailsPanel);
+            detailsPanel.init(summaryPanel);
 
             // Now that we are initialized, ask the server for what we
             //  need to show.
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2DetailsPanel.js b/web/gui/src/main/webapp/app/view/topo2/topo2DetailsPanel.js
index 29773f8..fd55a08 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2DetailsPanel.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2DetailsPanel.js
@@ -22,39 +22,83 @@
 (function () {
     'use strict';
 
+    // TODO: Topo2Panel - A view that draws the container for Summary and Details Panels
+    // TODO: as well as the show/hide/toggle methods.
+
+    // TODO: Topo2DetailsPanel should extend Topo2Panel and add methods to controller position
+    // TODO: based on the visibility of Topo2Summary
+
+    // TODO: Topo2<Device|Link|Host>Panel should only be concerned with the content displayed
+
     // Injected Services
     var Panel;
 
     // Internal State
-    var detailsPanel;
+    var detailsPanel, summaryPanel;
 
     // configuration
     var id = 'topo2-p-detail',
         className = 'topo2-p',
+        transTime = 750,
+        panelPadding = 64,
+        panelSpacing = 20,
         panelOpts = {
             width: 260          // summary and detail panel width
         };
 
-    function getInstance() {
+    function getInstance(_summaryPanel_) {
         if (detailsPanel) {
             return detailsPanel;
         }
 
+        summaryPanel = _summaryPanel_;
+
         var options = angular.extend({}, panelOpts, {
             class: className
         });
 
+        Panel = Panel.extend({
+            up: function () {
+                detailsPanel.el.el()
+                    .transition()
+                    .duration(transTime)
+                    .style('top', panelPadding + 'px');
+            },
+            down: function (position, callback) {
+                detailsPanel.el.el()
+                    .transition()
+                    .duration(transTime)
+                    .style('top', position + (panelPadding + panelSpacing) + 'px')
+                    .each('end', callback);
+            },
+            show: function () {
+
+                var summaryInstance = summaryPanel.getInstance(),
+                    position = 0;
+
+                if (summaryInstance.isVisible()) {
+                    position = summaryInstance.el.bbox().height;
+                    position = position + panelSpacing;
+                }
+
+                detailsPanel.el.el()
+                    .style('top', panelPadding + position + 'px');
+                detailsPanel.el.show();
+            }
+        });
+
         detailsPanel = new Panel(id, options);
         detailsPanel.el.classed(className, true);
 
         return detailsPanel;
     }
 
+
+
     angular.module('ovTopo2')
     .factory('Topo2DetailsPanelService', [
         'Topo2PanelService',
         function (_ps_) {
-
             Panel = _ps_;
 
             return getInstance;
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2DeviceDetailsPanel.js b/web/gui/src/main/webapp/app/view/topo2/topo2DeviceDetailsPanel.js
index 76893f1..0a60da7 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2DeviceDetailsPanel.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2DeviceDetailsPanel.js
@@ -23,7 +23,7 @@
     'use strict';
 
     // Injected Services
-    var panel, gs, wss, flash, bs, fs, ns, ls, ns;
+    var panel, gs, wss, flash, bs, fs, ns, ls;
 
     // Internal State
     var detailsPanel;
@@ -63,10 +63,10 @@
         }
     };
 
-    function init() {
+    function init(summaryPanel) {
 
         bindHandlers();
-        detailsPanel = panel();
+        detailsPanel = panel(summaryPanel);
     }
 
     function addBtnFooter() {
@@ -185,7 +185,7 @@
     }
 
     function show() {
-        detailsPanel.el.show();
+        detailsPanel.show();
     }
 
     function hide() {
@@ -222,7 +222,8 @@
                 show: show,
                 hide: hide,
                 destroy: destroy,
-                isVisible: function () { return detailsPanel.isVisible(); }
+                isVisible: function () { return detailsPanel.isVisible(); },
+                getInstance: function () { return detailsPanel; }
             };
         }
     ]);
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 8aaf152..fcc3f31 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2HostsPanel.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2HostsPanel.js
@@ -61,7 +61,7 @@
     }
 
     function render() {
-        hostPanel.el.show();
+        hostPanel.show();
         hostPanel.emptyRegions();
 
         var svg = hostPanel.appendToHeader('div')
@@ -77,7 +77,7 @@
     }
 
     function show() {
-        hostPanel.el.show();
+        hostPanel.show();
     }
 
     function hide() {
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2LinkPanel.js b/web/gui/src/main/webapp/app/view/topo2/topo2LinkPanel.js
index ea096b7..b3a7a5b 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2LinkPanel.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2LinkPanel.js
@@ -67,7 +67,7 @@
     }
 
     function render() {
-        linkPanel.el.show();
+        linkPanel.show();
         linkPanel.emptyRegions();
 
         var svg = linkPanel.appendToHeader('div')
@@ -83,7 +83,7 @@
     }
 
     function show() {
-        linkPanel.el.show();
+        linkPanel.show();
     }
 
     function hide() {
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2SubRegionPanel.js b/web/gui/src/main/webapp/app/view/topo2/topo2SubRegionPanel.js
index 0185e89..e084980 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2SubRegionPanel.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2SubRegionPanel.js
@@ -53,7 +53,7 @@
     }
 
     function render() {
-        subRegionPanel.el.show();
+        subRegionPanel.show();
         subRegionPanel.emptyRegions();
 
         var svg = subRegionPanel.appendToHeader('div')
@@ -69,7 +69,7 @@
     }
 
     function show() {
-        subRegionPanel.el.show();
+        subRegionPanel.show();
     }
 
     function hide() {
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2SummaryPanel.js b/web/gui/src/main/webapp/app/view/topo2/topo2SummaryPanel.js
index 07a9562..982cd5d4 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2SummaryPanel.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2SummaryPanel.js
@@ -26,7 +26,7 @@
     var Panel, gs, wss, flash, ls;
 
     // Internal State
-    var summaryPanel, summaryData;
+    var summaryPanel, summaryData, detailsPanel;
 
     // configuration
     var id = 'topo2-p-summary',
@@ -39,7 +39,9 @@
             showSummary: handleSummaryData
         };
 
-    function init() {
+    function init(_detailsPanel_) {
+
+        detailsPanel = _detailsPanel_;
 
         bindHandlers();
         wss.sendEvent('requestSummary');
@@ -76,12 +78,32 @@
         wss.bindHandlers(handlerMap);
     }
 
+    function hide() {
+        summaryPanel.el.hide(detailsPanel.getInstance().up);
+    }
+
+    function show() {
+
+        var _show = function () {
+            summaryPanel.el.show();
+        };
+
+        var summaryHeight = summaryPanel.el.bbox().height;
+        if (detailsPanel.isVisible()) {
+            detailsPanel.getInstance().down(summaryHeight, _show);
+        } else {
+            _show();
+        }
+    }
+
+
     function toggle() {
-        var on = summaryPanel.el.toggle(),
-            verb = on ? 'Show' : 'Hide';
+        var on = summaryPanel.isVisible(),
+            verb = on ? 'Hide' : 'Show';
 
         flash.flash(verb + ' Summary Panel');
         wss.sendEvent(on ? 'requestSummary' : 'cancelSummary');
+        on ? hide(): show();
     }
 
     function destroy() {
@@ -105,7 +127,8 @@
                 init: init,
                 toggle: toggle,
                 destroy: destroy,
-                isVisible: function () { return summaryPanel.isVisible(); }
+                isVisible: function () { return summaryPanel.isVisible(); },
+                getInstance: function () { return summaryPanel; }
             };
         }
     ]);