GUI -- Augment sprite definitions to include subpaths and fills.
- Added sample segment routing sprite layer.

Change-Id: I531992754632255ca9156b536cb08386816add16
diff --git a/web/gui/src/main/webapp/app/view/topo/topo.css b/web/gui/src/main/webapp/app/view/topo/topo.css
index a618e5a..d3cd66d 100644
--- a/web/gui/src/main/webapp/app/view/topo/topo.css
+++ b/web/gui/src/main/webapp/app/view/topo/topo.css
@@ -586,3 +586,18 @@
     fill: #444;
 }
 
+/* fills */
+.light #ov-topo svg #topo-sprites use.fill-gray2 {
+    fill: #eee;
+}
+.dark #ov-topo svg #topo-sprites use.fill-gray2 {
+    fill: #444;
+}
+
+.light #ov-topo svg #topo-sprites use.fill-blue2 {
+    fill: #bce;
+}
+.dark #ov-topo svg #topo-sprites use.fill-blue2 {
+    fill: #447;
+}
+
diff --git a/web/gui/src/main/webapp/app/view/topo/topoSprite.js b/web/gui/src/main/webapp/app/view/topo/topoSprite.js
index 9b5dbab..1c95741 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoSprite.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoSprite.js
@@ -58,9 +58,24 @@
         gs.loadDefs(defsElement, ids, true);
     }
 
+    function applyStrokeStyle(s, use) {
+        var style;
+        if (s) {
+            style = {};
+            angular.forEach(s, function (value, key) {
+                style['stroke-' + key] = value;
+            });
+            use.style(style);
+        }
+    }
 
-    function doSprite(spr, def, pmeta) {
-        var c = spr.class || 'gray1',
+    function applyFillClass(f, use) {
+        use.classed('fill-' + f, true);
+    }
+
+    function doSprite(spr, def, pathmeta) {
+        var pmeta = pathmeta[def.path],
+            c = spr.class || 'gray1',
             p = spr.pos || [0,0],
             lab = spr.label,
             dim = def.dim || [40,40],
@@ -69,7 +84,7 @@
             dy = def.labelyoff || 1,
             sc = def.scale,
             xfm = sus.translate(p),
-            g, attr, use, style;
+            g, attr, use;
 
         if (sc) {
             xfm += sus.scale(sc, sc);
@@ -86,13 +101,24 @@
         };
 
         use = g.append('use').attr(attr);
+        applyStrokeStyle(pmeta.s, use);
+        applyFillClass(def.fill, use);
 
-        if (pmeta.s) {
-            style = {};
-            angular.forEach(pmeta.s, function (value, key) {
-                style['stroke-' + key] = value;
+
+        // add subpaths if they have been defined
+        if (fs.isA(def.subpaths)) {
+            def.subpaths.forEach(function (v) {
+                pmeta = pathmeta[v.path];
+                attr = {
+                    width: w,
+                    height: h,
+                    'xlink:href': '#' + pmeta.u,
+                    transform: sus.translate(v.pos)
+                };
+                use = g.append('use').attr(attr);
+                applyStrokeStyle(pmeta.s, use);
+                applyFillClass(def.subpathfill, use);
             });
-            use.style(style);
         }
 
         if (lab) {
@@ -188,9 +214,8 @@
 
         if (sprites) {
             sprites.forEach(function (spr) {
-                var def = defs[spr.id],
-                    pmeta = pathmeta[def.path];
-                doSprite(spr, def, pmeta);
+                var def = defs[spr.id];
+                doSprite(spr, def, pathmeta);
             });
         }
 
diff --git a/web/gui/src/main/webapp/data/sprites/segmentRouting.json b/web/gui/src/main/webapp/data/sprites/segmentRouting.json
new file mode 100644
index 0000000..39dd70b
--- /dev/null
+++ b/web/gui/src/main/webapp/data/sprites/segmentRouting.json
@@ -0,0 +1,51 @@
+{
+  "defn_name": "segmentRouting",
+  "defn_desc": "Schematic of Data Center",
+
+  "paths": [
+    {
+      "tag": "chassis",
+      "stroke": {
+        "width": 3.5
+      },
+      "viewbox": "0 0 120 170",
+      "d": "M10,10h80v150h-80z"
+    },
+    {
+      "tag": "module",
+      "stroke": {
+        "width": 2
+      },
+      "viewbox": "0 0 120 20",
+      "d": "M15,5h70v12h-70z"
+    }
+  ],
+
+  "defn": [
+    {
+      "id": "rack",
+      "path": "chassis",
+      "fill": "gray2",
+      "subpathfill": "blue2",
+      "subpaths": [
+        { "path": "module", "pos": [0, 0]},
+        { "path": "module", "pos": [0, 20]},
+        { "path": "module", "pos": [0, 40]},
+        { "path": "module", "pos": [0, 60]}
+      ],
+      "dim":[120,170]
+    }
+  ],
+
+  "load": {
+    "alpha": 0.9,
+    "sprites": [
+      { "id": "rack", "pos":[300,600], "class":"blue1" },
+      { "id": "rack", "pos":[500,600], "class":"blue1" },
+      { "id": "rack", "pos":[700,600], "class":"blue1" }
+    ],
+    "labels": [
+      { "pos":[550,80], "text":"Segment Routing Demo", "class":"blue1", "size":1.4 }
+    ]
+  }
+}