Topo2: sprites now use logical colors.

Change-Id: I7033a8ab2bd4a2080ab8095f0d2cc42501abaf88
diff --git a/web/gui/src/main/webapp/app/fw/svg/sprite.js b/web/gui/src/main/webapp/app/fw/svg/sprite.js
index 3799fd5..6eafe66 100644
--- a/web/gui/src/main/webapp/app/fw/svg/sprite.js
+++ b/web/gui/src/main/webapp/app/fw/svg/sprite.js
@@ -31,15 +31,17 @@
                 // none for now
             },
             addRect: {
-                // none for now
+                fill: 'gray1',
+                stroke: 'none'
             },
             addPath: {
-                // none for now
+                fill: 'none',
+                stroke: 'gray1'
             }
         },
         layout: {
             builder: {
-                grid: 10            // grid square size (in layout coord-space
+                grid: 10            // grid square size (in layout coord-space)
             },
             addSprite: {
                 anchor: 'topleft'       // topleft, center
@@ -62,8 +64,8 @@
     // Sample usage:
     //
     //     ss.createSprite('foo', 100, 100)
-    //         .addPath('M40,40h20v20h-20z')
-    //         .addRect(50, 50, 10, 20)
+    //         .addPath('M40,40h20v20h-20z', {fill: 'gold1'})
+    //         .addRect(50, 50, 10, 20, {stroke: 'gold1'})
     //         .register();
 
     function spriteBuilder(id, w, h, opts) {
@@ -79,7 +81,7 @@
             var o = angular.extend({}, optDefaults.sprite.addRect, opts);
 
             rects.push({
-                x: x, y: y, w: w, h: h
+                x: x, y: y, w: w, h: h, o: o
             });
             return builder;
         }
@@ -88,9 +90,9 @@
             var o = angular.extend({}, optDefaults.sprite.addPath, opts);
 
             if (fs.isS(d)) {
-                paths.push(d);
+                paths.push({d: d, o: o});
             } else if (fs.isA(d)) {
-                paths.push(d.join(''));
+                paths.push({d: d.join(''), o: o});
             } else {
                 $log.warn('addPath: path not a string or array', d);
             }
diff --git a/web/gui/src/main/webapp/app/fw/svg/spriteData.js b/web/gui/src/main/webapp/app/fw/svg/spriteData.js
index 756d4b1..b806ae9 100644
--- a/web/gui/src/main/webapp/app/fw/svg/spriteData.js
+++ b/web/gui/src/main/webapp/app/fw/svg/spriteData.js
@@ -55,12 +55,12 @@
         // ----------------------------------------------------------$$$
         // This following code is for initial development of Topo2 sprite layer
         ssApi.createSprite('rack', 40, 50)
-            .addRect(0, 0, 40, 50)
+            .addRect(0, 0, 40, 50, {fill: 'gold1'})
             .addPath([
                 'M5,20h30v5h-30z',
                 'M5,30h30v5h-30z',
                 'M5,40h30v5h-30z'
-            ])
+            ], {stroke: 'gray1'})
             .register();
 
         ssApi.createLayout('segmentRouting', 130, 75)
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 8424850..cc6b767 100644
--- a/web/gui/src/main/webapp/app/fw/util/theme.js
+++ b/web/gui/src/main/webapp/app/fw/util/theme.js
@@ -32,6 +32,39 @@
         currentTheme,
         thidx;
 
+    // TODO: fine tune these colors
+    var spriteColors = {
+        gray1: {
+            fill: {
+                light: '#eeeeee',
+                dark: '#222222'
+            },
+            stroke: {
+                light: '#cccccc',
+                dark: '#333333'
+            }
+        },
+        gold1: {
+            fill: {
+                light: '#eeddaa',
+                dark: '#544714'
+            },
+            stroke: {
+                light: '#ffddaa',
+                dark: '#645724'
+            }
+        },
+        blue1: {
+            fill: {
+                light: '#a2b9ee',
+                dark: '#273059'
+            },
+            stroke: {
+                light: '#92a9de',
+                dark: '#273a63'
+            }
+        }
+    };
 
     function init() {
         thidx = ps.getPrefs('theme', { idx: 0 }).idx;
@@ -93,6 +126,16 @@
         listeners = listeners.filter(function(obj) { return obj === lsnr; });
     }
 
+    // color = logical color name
+    // what  = fill or stroke
+    function spriteColor(color, what) {
+        var c = color || 'none',
+            w = what || 'stroke',
+            t = getTheme();
+
+        return c === 'none' ? c : spriteColors[c][w][t];
+    }
+
     angular.module('onosUtil')
         .factory('ThemeService', ['$log', 'FnService', 'PrefsService',
         function (_$log_, _fs_, _ps_) {
@@ -113,7 +156,8 @@
                 },
                 toggleTheme: toggleTheme,
                 addListener: addListener,
-                removeListener: removeListener
+                removeListener: removeListener,
+                spriteColor: spriteColor
             };
     }]);
 
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2SpriteLayer.js b/web/gui/src/main/webapp/app/view/topo2/topo2SpriteLayer.js
index b3452c2..98e890b 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2SpriteLayer.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2SpriteLayer.js
@@ -31,9 +31,9 @@
 
     angular.module('ovTopo2')
         .factory('Topo2SpriteLayerService', [
-            'FnService', 'Topo2ViewController', 'SpriteService',
+            'FnService', 'Topo2ViewController', 'SpriteService', 'ThemeService',
 
-            function (fs, ViewController, ss) {
+            function (fs, ViewController, ss, ts) {
 
                 var SpriteLayer = ViewController.extend({
 
@@ -78,6 +78,7 @@
 
                         var id = spriteData.sprite.data.id,
                             definition = d3.select('#' + id);
+                            // is '#<id>' sufficient? namespace? '#t2spr-<id>' ?
 
                         if (definition.empty()) {
 
@@ -86,24 +87,33 @@
                                     .attr('viewBox', vbox(data.w, data.h))
                                     .attr('id', id);
 
-                            _.each(spriteData.sprite.paths, function (path) {
-                                spriteEl.append('path')
-                                    .attr('d', path)
-                                    .style('fill', 'none')
-                                    .style('stroke', 'black');
-                            });
+                            // TODO: add elements to sprite in the order defined
+                            //   when the sprite was created (layered bottom up)
+                            //   e.g. (1) rect, (2) path, (3) rect...
+                            //   not in groups by type.
+                            //   For now, assume rectangles are behind paths...
 
+                            // draw rectangles before paths
                             _.each(spriteData.sprite.rects, function (rect) {
                                 spriteEl.append('rect')
                                     .attr('width', rect.w)
                                     .attr('height', rect.h)
                                     .attr('x', rect.x)
                                     .attr('y', rect.y)
-                                    .style('fill', 'rgba(0,0,0,0.5)')
+                                    .style('fill', ts.spriteColor(rect.o.fill, 'fill'))
+                                    .style('stroke', ts.spriteColor(rect.o.stroke, 'stroke'));
+                            });
+
+                            // draw paths after rectangles
+                            _.each(spriteData.sprite.paths, function (path) {
+                                spriteEl.append('path')
+                                    .attr('d', path.d)
+                                    .style('fill', ts.spriteColor(path.o.fill, 'fill'))
+                                    .style('stroke', ts.spriteColor(path.o.stroke, 'stroke'));
                             });
                         }
 
-                        return spriteEl
+                        return spriteEl;
                     },
                     renderLayout: function () {
 
@@ -127,27 +137,27 @@
                     },
                     renderGrid: function () {
 
-
                         var layout = this.container.select('svg').append('g');
 
                         var gridSpacing = 5,
                             x = this.width / gridSpacing,
-                            y = this.height / gridSpacing;
+                            y = this.height / gridSpacing,
+                            i, l;
 
-                        for (var i = 0, l = x; i < l; i++) {
+                        for (i = 0, l = x; i < l; i++) {
                             layout.append('rect')
                                 .attr('width', 0.1)
                                 .attr('height', this.height)
                                 .attr('x', i * gridSpacing)
-                                .attr('y', 0)
+                                .attr('y', 0);
                         }
 
-                        for (var i = 0, l = y; i < l; i++) {
+                        for (i = 0, l = y; i < l; i++) {
                             layout.append('rect')
                                 .attr('height', 0.1)
                                 .attr('width', this.width)
                                 .attr('y', i * gridSpacing)
-                                .attr('x', 0)
+                                .attr('x', 0);
                         }
                     }
                 });
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 a777728..066aa33 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
@@ -35,7 +35,8 @@
 
     it('should define api functions', function () {
         expect(fs.areFunctions(ts, [
-            'init', 'theme', 'toggleTheme', 'addListener', 'removeListener'
+            'init', 'theme', 'toggleTheme', 'addListener', 'removeListener',
+            'spriteColor'
         ])).toBeTruthy();
     });