Topo2: Refactored NavigateToRegion events

There was duplicated logic in Topo2Breadcrumb|SubRegion|PeerRegion. This has been refactored out so
all the logic for navigating to a new region is handled in a single place (Topo2RegionNavigationService).

Topo2RegionNavigationService is a pub/sub class. There are two reasons for this choice;
1. Topo2Layout needs to create the new force layout simulation for the region that is about to enter.   Then it creates a transition between the old and new.
2. This will allow application developers to hook into the region:navigation event incase they need
   to update the topology for the new region displayed.

Change-Id: Ie8dad531b50afe2e4735086395c1285fb982122e
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2Layout.js b/web/gui/src/main/webapp/app/view/topo2/topo2Layout.js
index 2a8e95d..c5e8251 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2Layout.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2Layout.js
@@ -80,14 +80,17 @@
         [
             '$log', '$timeout', 'WebSocketService', 'SvgUtilService', 'Topo2RegionService',
             'Topo2ViewService', 'Topo2SelectService', 'Topo2ZoomService',
-            'Topo2ViewController',
+            'Topo2ViewController', 'Topo2RegionNavigationService',
             function ($log, $timeout, wss, sus, t2rs, t2vs, t2ss, t2zs,
-                      ViewController) {
+                      ViewController, t2rns) {
 
                 var Layout = ViewController.extend({
                     init: function (svg, forceG, uplink, dim, zoomer, opts) {
                         instance = this;
 
+                        var navToRegion = this.navigateToRegionHandler.bind(this);
+                        t2rns.addListener('region:navigation-start', navToRegion);
+
                         this.svg = svg;
 
                         // Append all the SVG Group elements to the forceG object
@@ -318,7 +321,10 @@
                             .transition()
                             .delay(500)
                             .duration(500)
-                            .style('opacity', 1);
+                            .style('opacity', 1)
+                            .each('end', function () {
+                                t2rns.navigateToRegionComplete();
+                            });
                     },
                     transitionUpRegion: function () {
                         this.prevForce.transition()
@@ -331,7 +337,14 @@
                             .transition()
                             .delay(500)
                             .duration(500)
-                            .style('opacity', 1);
+                            .style('opacity', 1)
+                            .each('end', function () {
+                                t2rns.navigateToRegionComplete();
+                            });;
+                    },
+                    navigateToRegionHandler: function () {
+                        this.createForceElements();
+                        this.transitionDownRegion();
                     }
                 });