GUI -- Added theme listeners, so the instance panel can update the instances on a theme change.

Change-Id: If26d5a6ce9fadc02c7184c5ad4d252fc168300a8
diff --git a/web/gui/src/main/webapp/app/fw/svg/svgUtil.js b/web/gui/src/main/webapp/app/fw/svg/svgUtil.js
index 77c70a6..f8e954d 100644
--- a/web/gui/src/main/webapp/app/fw/svg/svgUtil.js
+++ b/web/gui/src/main/webapp/app/fw/svg/svgUtil.js
@@ -140,8 +140,9 @@
             var lightNorm = ['#3E5780', '#78533B', '#CB4D28', '#018D61', '#8A2979', '#006D73', '#56AF00'],
                 lightMute = ['#A8B8CC', '#CCB3A8', '#FFC2BD', '#96D6BF', '#D19FCE', '#8FCCCA', '#CAEAA4'],
 
-                darkNorm  = ['#3E5780', '#78533B', '#CB4D28', '#018D61', '#8A2979', '#006D73', '#56AF00'],
-                darkMute  = ['#A8B8CC', '#CCB3A8', '#FFC2BD', '#96D6BF', '#D19FCE', '#8FCCCA', '#CAEAA4'];
+                // let's try slightly brigher colors for dark normal..
+                darkNorm  = ['#364D7F', '#7F5236', '#A93114', '#018D61', '#7E116D', '#02747A', '#378300'],
+                darkMute  = ['#1B2645', '#432B1C', '#76220E', '#035433', '#560B4A', '#013A3E', '#2D6D00'];
 
             var colors= {
                 light: {
diff --git a/web/gui/src/main/webapp/app/fw/util/theme.js b/web/gui/src/main/webapp/app/fw/util/theme.js
index 022ac0c..0e0ee64 100644
--- a/web/gui/src/main/webapp/app/fw/util/theme.js
+++ b/web/gui/src/main/webapp/app/fw/util/theme.js
@@ -20,11 +20,13 @@
 (function () {
     'use strict';
 
-    var $log;
+    var $log, fs;
 
     var themes = ['light', 'dark'],
         themeStr = themes.join(' '),
-        thidx;
+        thidx,
+        listeners = {},
+        nextListenerId = 1;
 
     function init() {
         thidx = 0;
@@ -59,16 +61,46 @@
     }
 
     function themeEvent(w) {
-        // TODO: emit a theme-changed event
-        var m = 'Theme-Change-('+w+'): ' + getTheme();
+        var t = getTheme(),
+            m = 'Theme-Change-('+w+'): ' + t;
         $log.debug(m);
+        angular.forEach(listeners, function(value) {
+            value.cb(
+                {
+                    event: 'themeChange',
+                    value: t
+                }
+            );
+        });
     }
 
-    // TODO: add hook for theme-change listener
+    function addListener(callback) {
+        var id = nextListenerId++,
+            cb = fs.isF(callback),
+            o = { id: id, cb: cb };
+
+        if (cb) {
+            listeners[id] = o;
+        } else {
+            $log.error('ThemeService.addListener(): callback not a function');
+            o.error = 'No callback defined';
+        }
+        return o;
+    }
+
+    function removeListener(lsnr) {
+        var id = lsnr && lsnr.id,
+            o = listeners[id];
+        if (o) {
+            delete listeners[id];
+        }
+    }
 
     angular.module('onosUtil')
-        .factory('ThemeService', ['$log', function (_$log_) {
+        .factory('ThemeService', ['$log', 'FnService',
+        function (_$log_, _fs_) {
             $log = _$log_;
+            fs = _fs_;
             thidx = 0;
 
             return {
@@ -80,7 +112,9 @@
                         setTheme(x);
                     }
                 },
-                toggleTheme: toggleTheme
+                toggleTheme: toggleTheme,
+                addListener: addListener,
+                removeListener: removeListener
             };
     }]);
 
diff --git a/web/gui/src/main/webapp/app/view/topo/topoInst.js b/web/gui/src/main/webapp/app/view/topo/topoInst.js
index 7bd74f9..2ff51af 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoInst.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoInst.js
@@ -50,7 +50,8 @@
     var onosInstances,
         onosOrder,
         oiShowMaster,
-        oiBox;
+        oiBox,
+        themeListener;
 
 
     // ==========================
@@ -291,9 +292,15 @@
         onosInstances = {};
         onosOrder = [];
         oiShowMaster = false;
+
+        // we want to update the instances, each time the theme changes
+        themeListener = ts.addListener(updateInstances);
     }
 
     function destroyInst() {
+        ts.removeListener(themeListener);
+        themeListener = null;
+
         ps.destroyPanel(idIns);
         oiBox = null;
     }
diff --git a/web/gui/src/main/webapp/tests/app/fw/svg/svgUtil-spec.js b/web/gui/src/main/webapp/tests/app/fw/svg/svgUtil-spec.js
index 9bee3ec..387b347 100644
--- a/web/gui/src/main/webapp/tests/app/fw/svg/svgUtil-spec.js
+++ b/web/gui/src/main/webapp/tests/app/fw/svg/svgUtil-spec.js
@@ -70,11 +70,11 @@
 
 
     it('should provide an alternate (dark) shade of blue', function () {
-       expect(sus.cat7().getColor('foo', false, 'dark')).toEqual('#3E5780');
+       expect(sus.cat7().getColor('foo', false, 'dark')).toEqual('#364D7F');
     });
 
     it('should provide an alternate (dark) shade of blue for muted', function () {
-        expect(sus.cat7().getColor('foo', true, 'dark')).toEqual('#A8B8CC');
+        expect(sus.cat7().getColor('foo', true, 'dark')).toEqual('#1B2645');
     });
 
     it('should iterate across the colors', function () {
diff --git a/web/gui/src/main/webapp/tests/app/fw/util/theme-spec.js b/web/gui/src/main/webapp/tests/app/fw/util/theme-spec.js
index 026d4ca..cbddc27 100644
--- a/web/gui/src/main/webapp/tests/app/fw/util/theme-spec.js
+++ b/web/gui/src/main/webapp/tests/app/fw/util/theme-spec.js
@@ -18,16 +18,28 @@
  ONOS GUI -- Util -- Theme Service - Unit Tests
  */
 describe('factory: fw/util/theme.js', function() {
-    var ts, $log;
+    var ts, $log, fs;
 
     beforeEach(module('onosUtil'));
 
-    beforeEach(inject(function (ThemeService, _$log_) {
+    beforeEach(inject(function (ThemeService, _$log_, FnService) {
         ts = ThemeService;
         $log = _$log_;
+        fs = FnService;
         ts.init();
     }));
 
+    it('should define MapService', function () {
+        expect(ts).toBeDefined();
+    });
+
+    it('should define api functions', function () {
+        expect(fs.areFunctions(ts, [
+            'init', 'theme', 'toggleTheme', 'addListener', 'removeListener'
+        ])).toBeTruthy();
+    });
+
+
     function verifyBodyClass(yes, no) {
         function bodyHasClass(c) {
             return d3.select('body').classed(c);
@@ -78,4 +90,8 @@
         expect($log.debug).not.toHaveBeenCalled();
         verifyBodyClass('light', 'dark');
     });
+
+
+    // TODO : Unit tests for listeners...
+
 });
diff --git a/web/gui/src/test/_karma/ev/migrate/ev_10_addInstance_F.json b/web/gui/src/test/_karma/ev/migrate/ev_10_addInstance_F.json
new file mode 100644
index 0000000..ce5a2e9
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/migrate/ev_10_addInstance_F.json
@@ -0,0 +1,14 @@
+{
+  "event": "addInstance",
+  "payload": {
+    "id": "instF",
+    "ip": "123.6.6.6",
+    "online": true,
+    "uiAttached": false,
+    "switches": 6,
+    "labels": [
+      "instF",
+      "123.6.6.6"
+    ]
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/migrate/ev_11_addInstance_G.json b/web/gui/src/test/_karma/ev/migrate/ev_11_addInstance_G.json
new file mode 100644
index 0000000..c2a70af
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/migrate/ev_11_addInstance_G.json
@@ -0,0 +1,14 @@
+{
+  "event": "addInstance",
+  "payload": {
+    "id": "instG",
+    "ip": "123.7.7.7",
+    "online": true,
+    "uiAttached": false,
+    "switches": 7,
+    "labels": [
+      "instG",
+      "123.7.7.7"
+    ]
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/migrate/ev_8_addInstance_B.json b/web/gui/src/test/_karma/ev/migrate/ev_8_addInstance_B.json
new file mode 100644
index 0000000..4313116
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/migrate/ev_8_addInstance_B.json
@@ -0,0 +1,14 @@
+{
+  "event": "addInstance",
+  "payload": {
+    "id": "instB",
+    "ip": "123.22.33.241",
+    "online": true,
+    "uiAttached": false,
+    "switches": 14,
+    "labels": [
+      "instB",
+      "123.22.33.241"
+    ]
+  }
+}
diff --git a/web/gui/src/test/_karma/ev/migrate/ev_9_addInstance_E.json b/web/gui/src/test/_karma/ev/migrate/ev_9_addInstance_E.json
new file mode 100644
index 0000000..1800093
--- /dev/null
+++ b/web/gui/src/test/_karma/ev/migrate/ev_9_addInstance_E.json
@@ -0,0 +1,14 @@
+{
+  "event": "addInstance",
+  "payload": {
+    "id": "instE",
+    "ip": "123.5.5.5",
+    "online": true,
+    "uiAttached": false,
+    "switches": 5,
+    "labels": [
+      "instE",
+      "123.5.5.5"
+    ]
+  }
+}