GUI2 Added selection of background maps

Change-Id: I88ee69fe2ff24bb1b4b3fe633b04f2f1778f3a82
diff --git a/web/gui2/src/main/webapp/app/view/topology/panel/mapselector/mapselector.component.css b/web/gui2/src/main/webapp/app/view/topology/panel/mapselector/mapselector.component.css
new file mode 100644
index 0000000..59c0d78
--- /dev/null
+++ b/web/gui2/src/main/webapp/app/view/topology/panel/mapselector/mapselector.component.css
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * ONOS GUI -- Topology Map Selector -- CSS file
+ */
+.dialog h2 {
+    margin: 0;
+    word-wrap: break-word;
+    display: inline-block;
+    width: 210px;
+    vertical-align: middle;
+}
+
+.dialog .dialog-button {
+    display: inline-block;
+    cursor: pointer;
+    height: 20px;
+    padding: 6px 8px 2px 8px;
+    margin: 4px;
+    float: right;
+}
diff --git a/web/gui2/src/main/webapp/app/view/topology/panel/mapselector/mapselector.component.html b/web/gui2/src/main/webapp/app/view/topology/panel/mapselector/mapselector.component.html
new file mode 100644
index 0000000..b3a4224
--- /dev/null
+++ b/web/gui2/src/main/webapp/app/view/topology/panel/mapselector/mapselector.component.html
@@ -0,0 +1,33 @@
+<!--
+~ Copyright 2019-present Open Networking Foundation
+~
+~ Licensed under the Apache License, Version 2.0 (the "License");
+~ you may not use this file except in compliance with the License.
+~ You may obtain a copy of the License at
+~
+~     http://www.apache.org/licenses/LICENSE-2.0
+~
+~ Unless required by applicable law or agreed to in writing, software
+~ distributed under the License is distributed on an "AS IS" BASIS,
+~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+~ See the License for the specific language governing permissions and
+~ limitations under the License.
+-->
+<div id="topo-p-dialog"
+     class="floatpanel dialog topo-p"
+     style="opacity: 1; left: 20px; width: 300px;">
+    <div class="header">
+        <h2>{{ lionFn('title_select_map') }}</h2>
+    </div>
+    <div class="map-list">
+        <form [formGroup]="form">
+            <select formControlName="mapid">
+                <option *ngFor="let o of mapSelectorResponse.order" [ngValue]="o">{{ mapSelectorResponse.maps[o].description }}</option>
+            </select>
+        </form>
+    </div>
+    <div class="footer">
+        <div class="dialog-button" (click)="choice(form.value)">{{ lionFn('ok') }}</div>
+        <div class="dialog-button" (click)="choice(undefined)">{{ lionFn('close') }}</div>
+    </div>
+</div>
diff --git a/web/gui2/src/main/webapp/app/view/topology/panel/mapselector/mapselector.component.spec.ts b/web/gui2/src/main/webapp/app/view/topology/panel/mapselector/mapselector.component.spec.ts
new file mode 100644
index 0000000..4d95361
--- /dev/null
+++ b/web/gui2/src/main/webapp/app/view/topology/panel/mapselector/mapselector.component.spec.ts
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { MapSelectorComponent } from './mapselector.component';
+import {FormsModule, ReactiveFormsModule} from '@angular/forms';
+import {ActivatedRoute, Params} from '@angular/router';
+import {of} from 'rxjs';
+import {FnService, LogService} from 'gui2-fw-lib';
+
+class MockActivatedRoute extends ActivatedRoute {
+    constructor(params: Params) {
+        super();
+        this.queryParams = of(params);
+    }
+}
+
+describe('MapSelectorComponent', () => {
+    let fs: FnService;
+    let ar: MockActivatedRoute;
+    let windowMock: Window;
+    let logServiceSpy: jasmine.SpyObj<LogService>;
+    let component: MapSelectorComponent;
+    let fixture: ComponentFixture<MapSelectorComponent>;
+
+    beforeEach(async(() => {
+        const logSpy = jasmine.createSpyObj('LogService', ['info', 'debug', 'warn', 'error']);
+        ar = new MockActivatedRoute({ 'debug': 'txrx' });
+
+        windowMock = <any>{
+            location: <any>{
+                hostname: 'foo',
+                host: 'foo',
+                port: '80',
+                protocol: 'http',
+                search: { debug: 'true' },
+                href: 'ws://foo:123/onos/ui/websock/path',
+                absUrl: 'ws://foo:123/onos/ui/websock/path'
+            }
+        };
+        fs = new FnService(ar, logSpy, windowMock);
+
+        TestBed.configureTestingModule({
+            imports: [
+                FormsModule,
+                ReactiveFormsModule
+            ],
+            declarations: [ MapSelectorComponent ],
+            providers: [
+                { provide: FnService, useValue: fs },
+                { provide: LogService, useValue: logSpy },
+                { provide: 'Window', useValue: windowMock },
+            ]
+        })
+        .compileComponents();
+        logServiceSpy = TestBed.get(LogService);
+    }));
+
+    beforeEach(() => {
+        fixture = TestBed.createComponent(MapSelectorComponent);
+        component = fixture.componentInstance;
+        fixture.detectChanges();
+    });
+
+    it('should create', () => {
+        expect(component).toBeTruthy();
+    });
+});
+
+// Expecting WebSocket request and response similar to:
+//
+// {"event":"mapSelectorRequest","payload":{}}
+//
+// {
+//     "event": "mapSelectorResponse",
+//     "payload": {
+//     "order": ["australia", "americas", "n_america", "s_america", "usa", "bayareaGEO",
+//     "europe", "italy", "uk", "japan", "s_korea", "taiwan", "africa", "oceania", "asia"],
+//         "maps": {
+//         "australia": {
+//             "id": "australia",
+//             "description": "Australia",
+//             "filePath": "*australia",
+//             "scale": 1.0
+//         },
diff --git a/web/gui2/src/main/webapp/app/view/topology/panel/mapselector/mapselector.component.ts b/web/gui2/src/main/webapp/app/view/topology/panel/mapselector/mapselector.component.ts
new file mode 100644
index 0000000..c97e0ca
--- /dev/null
+++ b/web/gui2/src/main/webapp/app/view/topology/panel/mapselector/mapselector.component.ts
@@ -0,0 +1,87 @@
+
+import {
+    Component, EventEmitter, OnChanges,
+    OnDestroy,
+    OnInit, Output, SimpleChanges,
+} from '@angular/core';
+import {
+    DetailsPanelBaseImpl,
+    FnService,
+    LionService, LoadingService,
+    LogService,
+    WebSocketService
+} from 'gui2-fw-lib';
+import {FormControl, FormGroup} from '@angular/forms';
+import { MapObject } from '../../layer/maputils';
+
+interface MapSelection {
+    order: string[];
+    maps: Object[];
+}
+
+@Component({
+    selector: 'onos-mapselector',
+    templateUrl: './mapselector.component.html',
+    styleUrls: ['./mapselector.component.css', './mapselector.theme.css', '../../topology.common.css']
+})
+export class MapSelectorComponent extends DetailsPanelBaseImpl implements OnInit, OnDestroy {
+    @Output() chosenMap = new EventEmitter<MapObject>();
+    lionFn; // Function
+    mapSelectorResponse: MapSelection = <MapSelection>{
+        order: [],
+        maps: []
+    };
+    form = new FormGroup({
+        mapid: new FormControl(this.mapSelectorResponse.order[0]),
+    });
+
+    constructor(
+        protected fs: FnService,
+        protected log: LogService,
+        protected ls: LoadingService,
+        protected wss: WebSocketService,
+        private lion: LionService
+    ) {
+        super(fs, ls, log, wss, 'topo');
+
+        if (this.lion.ubercache.length === 0) {
+            this.lionFn = this.dummyLion;
+            this.lion.loadCbs.set('topoms', () => this.doLion());
+        } else {
+            this.doLion();
+        }
+
+        this.log.debug('Topo MapSelectorComponent constructed');
+    }
+
+    ngOnInit() {
+        this.wss.bindHandlers(new Map<string, (data) => void>([
+            ['mapSelectorResponse', (data) => {
+                this.mapSelectorResponse = data;
+                this.form.setValue({'mapid': this.mapSelectorResponse.order[0]});
+            }
+            ]
+        ]));
+        this.wss.sendEvent('mapSelectorRequest', {});
+        this.log.debug('Topo MapSelectorComponent initialized');
+    }
+
+    /**
+     * When the component is being unloaded then unbind the WSS handler.
+     */
+    ngOnDestroy(): void {
+        this.wss.unbindHandlers(['mapSelectorResponse']);
+        this.log.debug('Topo MapSelectorComponent destroyed');
+    }
+
+    /**
+     * Read the LION bundle for Details panel and set up the lionFn
+     */
+    doLion() {
+        this.lionFn = this.lion.bundle('core.view.Topo');
+    }
+
+    choice(mapid: Object): void {
+        this.chosenMap.emit(<MapObject>this.mapSelectorResponse.maps[mapid['mapid']]);
+    }
+}
diff --git a/web/gui2/src/main/webapp/app/view/topology/panel/mapselector/mapselector.theme.css b/web/gui2/src/main/webapp/app/view/topology/panel/mapselector/mapselector.theme.css
new file mode 100644
index 0000000..0ef1538
--- /dev/null
+++ b/web/gui2/src/main/webapp/app/view/topology/panel/mapselector/mapselector.theme.css
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * ONOS GUI -- Topology Map Selector theme -- CSS file
+ */
+
+/*.light */
+.dialog .dialog-button {
+    background-color: #518ecc;
+    color: white;
+}
+
+
+/* ========== DARK Theme ========== */
+
+.dark .dialog .dialog-button {
+    background-color: #345e85;
+    color: #cccccd;
+}