GUI2 Added selection of background maps

Change-Id: I88ee69fe2ff24bb1b4b3fe633b04f2f1778f3a82
diff --git a/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.html b/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.html
index 4b66bd6..95d5d9e 100644
--- a/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.html
+++ b/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.html
@@ -38,6 +38,7 @@
               [summaryVisible]="prefsState.summary">
 </onos-toolbar>
 <onos-details #details [on]="prefsState.detail"></onos-details>
+<onos-mapselector *ngIf="mapSelShown" (chosenMap)="changeMap($event)"></onos-mapselector>
 
 <div id="ov-topo2">
     <!-- Template explanation -
@@ -62,7 +63,7 @@
                onos-nodeviceconnected />
         <svg:g id="topo-zoomlayer" onosZoomableOf [zoomableOf]="svgZoom">
             <svg:desc>A logical layer that allows the main SVG canvas to be zoomed and panned</svg:desc>
-            <svg:g *ngIf="prefsState.bg" onos-backgroundsvg>
+            <svg:g *ngIf="prefsState.bg" onos-backgroundsvg [map]="mapIdState">
                 <svg:desc>The Background SVG component - contains maps</svg:desc>
             </svg:g>
             <svg:g #force onos-forcesvg
diff --git a/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.spec.ts b/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.spec.ts
index 446d41c..0c0a6dd 100644
--- a/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.spec.ts
+++ b/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.spec.ts
@@ -18,7 +18,7 @@
 import { of } from 'rxjs';
 import { HttpClient } from '@angular/common/http';
 import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
-
+import * as d3 from 'd3';
 import { TopologyComponent } from './topology.component';
 import {
     Instance,
@@ -45,6 +45,10 @@
     LinkSvgComponent, SubRegionNodeSvgComponent
 } from '../layer/forcesvg/visuals';
 import {DraggableDirective} from '../layer/forcesvg/draggable/draggable.directive';
+import {MapSelectorComponent} from '../panel/mapselector/mapselector.component';
+import {BackgroundSvgComponent} from '../layer/backgroundsvg/backgroundsvg.component';
+import {FormsModule, ReactiveFormsModule} from '@angular/forms';
+import {MapSvgComponent} from '../layer/mapsvg/mapsvg.component';
 
 
 class MockActivatedRoute extends ActivatedRoute {
@@ -156,7 +160,12 @@
         fs = new FnService(ar, logSpy, windowMock);
 
         TestBed.configureTestingModule({
-            imports: [ BrowserAnimationsModule, RouterTestingModule ],
+            imports: [
+                BrowserAnimationsModule,
+                RouterTestingModule,
+                FormsModule,
+                ReactiveFormsModule
+            ],
             declarations: [
                 TopologyComponent,
                 InstanceComponent,
@@ -173,7 +182,10 @@
                 HostNodeSvgComponent,
                 DraggableDirective,
                 ZoomableDirective,
-                SubRegionNodeSvgComponent
+                SubRegionNodeSvgComponent,
+                MapSelectorComponent,
+                BackgroundSvgComponent,
+                MapSvgComponent
             ],
             providers: [
                 { provide: FnService, useValue: fs },
@@ -201,6 +213,7 @@
     beforeEach(() => {
         fixture = TestBed.createComponent(TopologyComponent);
         component = fixture.componentInstance;
+
         fixture.detectChanges();
     });
 
diff --git a/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.ts b/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.ts
index ff8a050..750162f 100644
--- a/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.ts
+++ b/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.ts
@@ -28,7 +28,6 @@
     PrefsService,
     SvgUtilService,
     WebSocketService,
-    ZoomService
 } from 'gui2-fw-lib';
 import {InstanceComponent} from '../panel/instance/instance.component';
 import {DetailsComponent} from '../panel/details/details.component';
@@ -45,12 +44,15 @@
     HOSTS_TOGGLE, OFFLINE_TOGGLE, PORTS_TOGGLE,
     BKGRND_TOGGLE, CYCLELABELS_BTN, CYCLEHOSTLABEL_BTN,
     RESETZOOM_BTN, EQMASTER_BTN,
-    CANCEL_TRAFFIC, ALL_TRAFFIC, QUICKHELP_BTN
+    CANCEL_TRAFFIC, ALL_TRAFFIC, QUICKHELP_BTN, BKGRND_SELECT
 } from '../panel/toolbar/toolbar.component';
 import {TrafficService} from '../traffic.service';
 import {ZoomableDirective} from '../layer/zoomable.directive';
+import {MapObject} from '../layer/maputils';
 
 const TOPO2_PREFS = 'topo2_prefs';
+const TOPO_MAPID_PREFS = 'topo_mapid';
+
 const PREF_BG = 'bg';
 const PREF_DETAIL = 'detail';
 const PREF_DLBLS = 'dlbls';
@@ -63,7 +65,7 @@
 const PREF_TOOLBAR = 'toolbar';
 
 /**
- * model of the topo2_prefs object - this is a subset of the overall Prefs returned
+ * Model of the topo2_prefs object - this is a subset of the overall Prefs returned
  * by the server
  */
 export interface Topo2Prefs {
@@ -134,6 +136,12 @@
         summary: 1,
         toolbar: 0,
     };
+
+    mapIdState: MapObject = <MapObject>{
+        id: undefined,
+        scale: 1.0
+    };
+    mapSelShown: boolean = false;
     lionFn; // Function
 
     constructor(
@@ -167,6 +175,7 @@
         this.is.loadIconDef('m_summary');
         this.is.loadIconDef('m_details');
         this.is.loadIconDef('m_map');
+        this.is.loadIconDef('m_selectMap');
         this.is.loadIconDef('m_cycleLabels');
         this.is.loadIconDef('m_resetZoom');
         this.is.loadIconDef('m_eqMaster');
@@ -217,6 +226,7 @@
 
         this.ps.addListener((data) => this.prefsUpdateHandler(data));
         this.prefsState = this.ps.getPrefs(TOPO2_PREFS, this.prefsState);
+        this.mapIdState = this.ps.getPrefs(TOPO_MAPID_PREFS, this.mapIdState);
         this.log.debug('Topology component initialized');
     }
 
@@ -228,8 +238,13 @@
      */
     prefsUpdateHandler(data: any): void {
         // Extract the TOPO2 prefs from it
-        this.prefsState = data[TOPO2_PREFS];
-        this.log.debug('Updated topo2 prefs', this.prefsState);
+        if (data[TOPO2_PREFS]) {
+            this.prefsState = data[TOPO2_PREFS];
+        }
+        if (data[TOPO_MAPID_PREFS]) {
+            this.mapIdState = data[TOPO_MAPID_PREFS];
+        }
+        this.log.debug('Updated topo2 prefs', this.prefsState, this.mapIdState);
     }
 
     /**
@@ -270,6 +285,9 @@
             case BKGRND_TOGGLE:
                 this.toggleBackground();
                 break;
+            case BKGRND_SELECT:
+                this.mapSelShown = !this.mapSelShown;
+                break;
             case CYCLELABELS_BTN:
                 this.cycleDeviceLabels();
                 break;
@@ -309,6 +327,7 @@
             B: [(token) => {this.toggleBackground(token); }, 'Toggle background'],
             D: [(token) => {this.toggleDetails(token); }, 'Toggle details panel'],
             I: [(token) => {this.toggleInstancePanel(token); }, 'Toggle ONOS Instance Panel'],
+            G: [() => {this.mapSelShown = !this.mapSelShown; }, 'Show map selection dialog'],
             O: [() => {this.toggleSummary(); }, 'Toggle the Summary Panel'],
             R: [() => {this.resetZoom(); }, 'Reset pan / zoom'],
             P: [(token) => {this.togglePorts(token); }, 'Toggle Port Highlighting'],
@@ -572,6 +591,13 @@
         this.trs.destroy();
     }
 
+    changeMap(map: MapObject) {
+        this.mapSelShown = false; // Hide the MapSelector component
+        this.mapIdState = map;
+        this.ps.setPrefs(TOPO_MAPID_PREFS, this.mapIdState);
+        this.log.debug('Map has been changed to ', map);
+    }
+
     /**
      * Read the LION bundle for Toolbar and set up the lionFn
      */