/*
 * Copyright 2018-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 {
    Component, EventEmitter,
    Input,
    OnChanges, Output,
    SimpleChanges
} from '@angular/core';
import { MapObject } from '../maputils';
import {LogService, MapBounds} from 'gui2-fw-lib';
import {HttpClient} from '@angular/common/http';
import * as d3 from 'd3';
import * as topojson from 'topojson-client';

const BUNDLED_URL_PREFIX = 'data/map/';

/**
 * Model of the transform attribute of a topojson file
 */
interface TopoDataTransform {
    scale: number[];
    translate: number[];
}

/**
 * Model of the Feature returned prom topojson library
 */
interface Feature {
    geometry: Object;
    id: string;
    properties: Object;
    type: string;
}

/**
 * Model of the Features Collection returned by the topojson.features function
 */
interface FeatureCollection {
    type: string;
    features: Feature[];
}

/**
 * Model of the topojson file
 */
interface TopoData {
    type: string; // Usually "Topology"
    objects: Object; // Can be a list of countries or individual countries
    arcs: number[][][]; // Coordinates
    bbox: number[]; // Bounding box
    transform: TopoDataTransform; // scale and translate
}

@Component({
    selector: '[onos-mapsvg]',
    templateUrl: './mapsvg.component.html',
    styleUrls: ['./mapsvg.component.css']
})
export class MapSvgComponent implements  OnChanges {
    @Input() map: MapObject = <MapObject>{id: 'none'};
    @Output() mapBounds = new EventEmitter<MapBounds>();

    geodata: FeatureCollection;
    pathgen: any; // (Feature) => string; have to leave it general, as there is the bounds method used below
    // testPath: string;
    // testFeature = <Feature>{
    //     id: 'test',
    //     type: 'Feature',
    //     geometry: {
    //         coordinates: [
    //             [[-15, 60], [45, 60], [45, 45], [-15, 45], [-15, 60]],
    //             [[-10, 55], [45, 55], [45, 50], [-10, 50], [-10, 55]],
    //         ],
    //         type: 'Polygon'
    //     },
    //     properties: { name: 'Test'}
    // };

    constructor(
        private log: LogService,
        private httpClient: HttpClient,
    ) {
        // Scale everything to 360 degrees wide and 150 high
        // See background.component.html for more details
        this.pathgen = d3.geoPath().projection(d3.geoIdentity().reflectY(true)
            // MapSvgComponent.scale()
        );

        // this.log.debug('Feature Test',this.testFeature);
        // this.testPath = this.pathgen(this.testFeature);
        // this.log.debug('Feature Path', this.testPath);
        this.log.debug('MapSvgComponent constructed');
    }

    static getUrl(id: string): string {
        if (id && id[0] === '*') {
            return BUNDLED_URL_PREFIX + id.slice(1) + '.topojson';
        }
        return id + '.topojson';
    }

    /**
     * Wrapper for the path generator function
     * @param feature The county or state within the map
     */
    pathGenerator(feature: Feature): string {
        return this.pathgen(feature);
    }

    ngOnChanges(changes: SimpleChanges): void {
        this.log.debug('Change detected', changes);
        if (changes['map']) {
            const map: MapObject = <MapObject>(changes['map'].currentValue);
            if (map.id) {
                this.httpClient
                    .get(MapSvgComponent.getUrl(map.filePath))
                    .subscribe((topoData: TopoData) => {
                        // this.mapPathGenerator =
                        this.handleTopoJson(map, topoData);
                        this.log.debug('Path Generated for', map.id,
                            'from', MapSvgComponent.getUrl(map.filePath));
                    });
            }
        }
    }

    /**
     * Handle the topojson file stream as it arrives back from the server
     *
     * The topojson library converts the topojson file in to a FeatureCollection
     * d3.geo then further converts this in to a Path
     *
     * @param map The Map chosen in the GUI
     * @param topoData The data in the TopoJson file
     */
    handleTopoJson(map: MapObject, topoData: TopoData): void {

        let topoObject = topoData.objects[map.id];
        if (!topoObject) {
            topoObject = topoData.objects['states'];
        }
        this.log.debug('Topo obj', topoObject, 'topodata', topoData);
        this.geodata = <FeatureCollection>topojson.feature(topoData, topoObject);
        const bounds = this.pathgen.bounds(this.geodata);
        this.mapBounds.emit(<MapBounds>{
            lngMin: bounds[0][0],
            latMin: -bounds[0][1], // Y was inverted in the transform
            lngMax: bounds[1][0],
            latMax: -bounds[1][1] // Y was inverted in the transform
        });
        this.log.debug('Map retrieved', topoData, this.geodata);

    }
}
