WIP:: Initial stab at regions demo for Europe.

Change-Id: I80402aea2b3d57bf104db0c0fba68bebda0cae9e
diff --git a/core/api/src/main/java/org/onosproject/ui/model/topo/UiTopoLayoutId.java b/core/api/src/main/java/org/onosproject/ui/model/topo/UiTopoLayoutId.java
index 52056e8..12e57f5 100644
--- a/core/api/src/main/java/org/onosproject/ui/model/topo/UiTopoLayoutId.java
+++ b/core/api/src/main/java/org/onosproject/ui/model/topo/UiTopoLayoutId.java
@@ -23,7 +23,7 @@
  */
 public final class UiTopoLayoutId extends Identifier<String> {
 
-    private static final String DEFAULT_STR = "_default_";
+    private static final String DEFAULT_STR = "root";
 
     /**
      * Default topology layout identifier.
diff --git a/core/api/src/test/java/org/onosproject/net/config/basics/BasicUiTopoLayoutConfigTest.java b/core/api/src/test/java/org/onosproject/net/config/basics/BasicUiTopoLayoutConfigTest.java
index f04dd9e..24b9031 100644
--- a/core/api/src/test/java/org/onosproject/net/config/basics/BasicUiTopoLayoutConfigTest.java
+++ b/core/api/src/test/java/org/onosproject/net/config/basics/BasicUiTopoLayoutConfigTest.java
@@ -42,7 +42,7 @@
 
     private static final String LAYOUT_JSON = "configs.layouts.1.json";
 
-    private static final String L_DEFAULT = "_default_";
+    private static final String L_DEFAULT = "root";
     private static final String L1 = "l1";
     private static final String L2 = "l2";
     private static final String L3 = "l3";
diff --git a/core/api/src/test/resources/org/onosproject/net/config/basics/configs.layouts.1.json b/core/api/src/test/resources/org/onosproject/net/config/basics/configs.layouts.1.json
index 790693b..f2c49aa 100644
--- a/core/api/src/test/resources/org/onosproject/net/config/basics/configs.layouts.1.json
+++ b/core/api/src/test/resources/org/onosproject/net/config/basics/configs.layouts.1.json
@@ -1,6 +1,6 @@
 {
   "layouts": {
-    "_default_": {
+    "root": {
       "basic": {
         "geomap": "uk",
         "scale": 1.2,
diff --git a/tools/test/topos/regions-bayarea-grid.sh b/tools/test/topos/regions-bayarea-grid.sh
index 77a519e..d6267d4 100755
--- a/tools/test/topos/regions-bayarea-grid.sh
+++ b/tools/test/topos/regions-bayarea-grid.sh
@@ -206,7 +206,7 @@
 
 ### Add regions and associate devices with them
 #
-# region-add <region-id> <region-name> <region-type> <region-master>
+# region-add <region-id> <region-name> <region-type> <long/Y> <lat/X> <region-master>
 # region-add-devices <region-id> <device-id>...
 
 onos ${host} <<-EOF
diff --git a/tools/test/topos/regions-europe.sh b/tools/test/topos/regions-europe.sh
new file mode 100755
index 0000000..37f500a
--- /dev/null
+++ b/tools/test/topos/regions-europe.sh
@@ -0,0 +1,94 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Creates a replica of the GEANT topology using ONOS null provider
+# -----------------------------------------------------------------------------
+
+# config
+host=${1:-localhost}
+nports=24
+sleepfor=5
+
+
+### start up null provider
+onos ${host} null-simulation stop custom
+onos ${host} wipe-out please
+onos ${host} null-simulation start custom
+
+
+## unfortunately, it takes a time for the sim to start up
+#  this is not ideal...
+
+echo
+echo "Sleeping while sim starts up... (${sleepfor} seconds)..."
+echo
+sleep ${sleepfor}
+
+
+### Start by adding Country regions
+# Note that Long/Lat places region icon nicely in the country center
+
+# region-add <region-id> <region-name> <region-type> <long/Y> <lat/X> <region-master>
+
+onos ${host} <<-EOF
+
+region-add rUK "United Kingdom" COUNTRY 52.206035 -1.310384 ${host}
+region-add rIT "Italy"   COUNTRY 44.447951  11.093161 ${host}
+region-add rFR "France"  COUNTRY 47.066264  2.711458 ${host}
+region-add rDE "Germany" COUNTRY 50.863152  9.761971 ${host}
+region-add rES "Spain"   COUNTRY 40.416704 -3.7035824 ${host}
+
+EOF
+
+
+###------------------------------------------------------
+###----- TEMPORARY DATA ---------------------------------
+
+#region-add rLON "London"    COUNTRY 51.507321 -0.1276473 ${host}
+#region-add rMIL "Milan"     COUNTRY 45.466797  9.1904984 ${host}
+#region-add rPAR "Paris"     COUNTRY 48.856610  2.3514992 ${host}
+#region-add rFRA "Frankfurt" COUNTRY 50.110652  8.6820934 ${host}
+#region-add rMAD "Madrid"    COUNTRY 40.416704 -3.7035824 ${host}
+
+# null-create-device switch LON ${nports} 51.507321 -0.1276473
+# null-create-device switch PAR ${nports} 48.856610 2.3514992
+# null-create-device switch MIL ${nports} 45.466797 9.1904984
+# null-create-device switch FRA ${nports} 50.110652 8.6820934
+# null-create-device switch MAD ${nports} 40.416704 -3.7035824
+
+###------------------------------------------------------
+
+
+### Add layouts, associating backing regions, and optional parent.
+# layout-add <layout-id> <bg-ref> \
+#   [ <region-id> <parent-layout-id> <scale> <offset-x> <offset-y> ]
+#
+
+onos ${host} <<-EOF
+
+# -- root layout
+layout-add root @europe . . 6.664 -2992.552 -2473.084
+
+# -- layouts for top level regions
+layout-add lUK @europe rUK root 13.99 -6233.775 -5111.723
+layout-add lIT @europe rIT root 14.72 -7793.210 -6623.814
+layout-add lFR @europe rFR root 16.91 -8225.716 -7198.134
+layout-add lDE @europe rDE root 17.63 -9119.646 -7044.949
+layout-add lES @europe rES root 21.41 -9994.596 -10135.655
+
+# -- layouts for country sub-regions
+# TODO
+
+# -- summary of installed layouts
+layouts
+
+EOF
+
+
+### Set up debug log messages for classes we care about
+onos ${host} <<-EOF
+log:set DEBUG org.onosproject.ui.impl.topo.Topo2ViewMessageHandler
+log:set DEBUG org.onosproject.ui.impl.topo.Topo2Jsonifier
+log:set DEBUG org.onosproject.ui.impl.UiWebSocket
+log:set DEBUG org.onosproject.ui.impl.UiTopoSession
+log:list
+EOF
diff --git a/tools/test/topos/uk-region.json b/tools/test/topos/uk-region.json
index 7b42fa7..2f52e7d 100644
--- a/tools/test/topos/uk-region.json
+++ b/tools/test/topos/uk-region.json
@@ -63,7 +63,7 @@
   },
 
   "layouts": {
-    "_default_": {
+    "root": {
       "basic": {
         "geomap": "uk",
         "scale": 1.2,
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2-theme.css b/web/gui/src/main/webapp/app/view/topo2/topo2-theme.css
index 6523a66..bb26930 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2-theme.css
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2-theme.css
@@ -170,15 +170,12 @@
 
 /* note: device without the 'online' class is offline */
 #ov-topo2 svg .node.device rect {
-    /* TODO: theme */
     fill: #f0f0f0;
 }
 #ov-topo2 svg .node.device text {
-    /*TODO: theme*/
     fill: #bbb;
 }
 #ov-topo2 svg .node.device use {
-    /*TODO: theme*/
     fill: #777;
 }
 
@@ -198,6 +195,10 @@
     fill: #ffffff;
 }
 
+#ov-topo2 svg .node.sub-region text {
+    stroke: #000000;
+}
+
 #ov-topo2 svg .node.sub-region use {
     /* NOTE: this gets overridden programatically */
     fill: #454545;
@@ -605,6 +606,10 @@
     fill: #525660;
 }
 
+.dark #ov-topo2 svg .node.sub-region text {
+    stroke: #eeeeee;
+}
+
 .dark #ov-topo2 svg .node.sub-region use {
     /* NOTE: this gets overridden programatically */
     fill: #eeeeee;
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 06e0a8d..fc7d9ae 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2.js
@@ -32,7 +32,7 @@
 
     // Internal state
     var zoomer,
-        currentLayoutId = '_default_';  // NOTE: see UiTopoLayoutId.DEFAULT_STR
+        currentLayoutId = 'root';  // NOTE: see UiTopoLayoutId.DEFAULT_STR
 
 
     // --- Glyphs, Icons, and the like -----------------------------------
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2Background.js b/web/gui/src/main/webapp/app/view/topo2/topo2Background.js
index f83d921..7aee3ed 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2Background.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2Background.js
@@ -65,14 +65,26 @@
                     },
                     addLayout: function (data) {
 
+                        var oldBgType = this.bgType,
+                            oldBgId = this.bgId;
+
                         this.background = data;
                         this.bgType = data.bgType;
+                        this.bgId = data.bgId;
                         this.zoomData = data.bgZoom;
 
                         var _this = this,
                             pan = zoomPan(this.zoomData),
                             scale = zoomScale(this.zoomData);
 
+                        // TODO: test for same background... avoid reload on same
+
+                        //  Avoid re-loading the background / sprite layer
+                        //  if the type and ID are same as last time.
+
+                        //  For example, europe map can be panned/zoomed to
+                        //   focus on different countries
+
                         if (this.bgType === 'geo') {
 
                             // Hide Sprite Layer and show Map
@@ -101,6 +113,8 @@
                             // No background type - Tell the region the background is ready for placing nodes
                             t2ms.hide();
                             t2sls.hide();
+
+                            // TODO: don't just use previous layout's pan/zoom settings!
                             // _this.region.loaded('bgRendered', true);
                             // t2zs.panAndZoom(pan, _this.background.bgZoomScale, 1000);
                         }
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2D3.js b/web/gui/src/main/webapp/app/view/topo2/topo2D3.js
index e036020..6a3964a 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2D3.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2D3.js
@@ -36,7 +36,7 @@
         function (_is_) {
             return {
                 nodeEnter: nodeEnter,
-                nodeExit: nodeExit,
+                nodeExit: nodeExit
             };
         }
     ]
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2NodeModel.js b/web/gui/src/main/webapp/app/view/topo2/topo2NodeModel.js
index 94a4ef9..ccedaff 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2NodeModel.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2NodeModel.js
@@ -33,16 +33,21 @@
 
     // note: these are the device icon colors without affinity (no master)
     var dColTheme = {
-        light: {
-            online: '#444444',
-            offline: '#cccccc'
+            light: {
+                online: '#444444',
+                offline: '#cccccc'
+            },
+            dark: {
+                // TODO: theme
+                online: '#444444',
+                offline: '#cccccc'
+            }
         },
-        dark: {
-            // TODO: theme
-            online: '#444444',
-            offline: '#cccccc'
-        }
-    };
+        // and here are the stroke colors of the glyph, per theme
+        dUseTheme = {
+            light: 'white',
+            dark: 'black'
+        };
 
     angular.module('ovTopo2')
     .factory('Topo2NodeModel', [
@@ -258,7 +263,7 @@
                     // Icon
                     glyph = is.addDeviceIcon(node, glyphId, devIconDim);
                     glyph.attr(this.iconBox(devIconDim, 0));
-                    glyph.style('fill', 'white');
+                    glyph.style('fill', dUseTheme[ts.theme()]);
 
                     node.attr('transform',
                         sus.translate(-halfDevIcon, -halfDevIcon));