/*
 * Copyright 2015-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 { Injectable } from '@angular/core';
import { GlyphService } from './glyph.service';
import { LogService } from '../../log.service';
import { SvgUtilService } from './svgutil.service';
import * as d3 from 'd3';

const vboxSize = 50;
const cornerSize = vboxSize / 10;
const viewBox = '0 0 ' + vboxSize + ' ' + vboxSize;

export const glyphMapping = new Map<string, string>([
    // Maps icon ID to the glyph ID it uses.
    // NOTE: icon ID maps to a CSS class for styling that icon
    ['active', 'checkMark'],
    ['inactive', 'xMark'],

    ['plus', 'plus'],
    ['minus', 'minus'],
    ['play', 'play'],
    ['stop', 'stop'],

    ['upload', 'upload'],
    ['download', 'download'],
    ['delta', 'delta'],
    ['nonzero', 'nonzero'],
    ['close', 'xClose'],

    ['topo', 'topo'],

    ['refresh', 'refresh'],
    ['query', 'query'],
    ['garbage', 'garbage'],


    ['upArrow', 'triangleUp'],
    ['downArrow', 'triangleDown'],

    ['appInactive', 'unknown'],

    ['node', 'node'],
    ['devIcon_SWITCH', 'switch'],
    ['devIcon_ROADM', 'roadm'],
    ['devIcon_OTN', 'otn'],

    ['portIcon_DEFAULT', 'm_ports'],

    ['meter', 'meterTable'], // TODO: m_meter icon?

    ['deviceTable', 'switch'],
    ['flowTable', 'flowTable'],
    ['portTable', 'portTable'],
    ['groupTable', 'groupTable'],
    ['meterTable', 'meterTable'],
    ['pipeconfTable', 'pipeconfTable'],

    ['hostIcon_endstation', 'endstation'],
    ['hostIcon_router', 'router'],
    ['hostIcon_bgpSpeaker', 'bgpSpeaker'],

    // navigation menu icons...
    ['nav_apps', 'bird'],
    ['nav_settings', 'cog'],
    ['nav_cluster', 'node'],
    ['nav_processors', 'allTraffic'],

    ['nav_topo', 'topo'],
    ['nav_topo2', 'm_cloud'],
    ['nav_devs', 'switch'],
    ['nav_links', 'ports'],
    ['nav_hosts', 'endstation'],
    ['nav_intents', 'relatedIntents'],
    ['nav_tunnels', 'ports'], // TODO: use tunnel glyph, when available
    ['nav_yang', 'yang'],
]);

/**
 * ONOS GUI -- SVG -- Icon Service
 */
@Injectable()
export class IconService {

    constructor(
        private gs: GlyphService,
        private log: LogService,
        private sus: SvgUtilService
    ) {

        this.log.debug('IconService constructed');
    }

    ensureIconLibDefs() {
        const body = d3.select('body');
        let svg = body.select('svg#IconLibDefs');
        if (svg.empty()) {
            svg = body.append('svg').attr('id', 'IconLibDefs');
            svg.append('defs');
        }
        return svg.select('defs');
    }

    /**
     * Load an icon
     *
     * @param div A D3 selection of the '&lt;div&gt;' element into which icon should load
     * @param glyphId Identifies the glyph to use
     * @param size The dimension of icon in pixels. Defaults to 20.
     * @param installGlyph If truthy, will cause the glyph to be added to
     *      well-known defs element. Defaults to false.
     * @param svgClass The CSS class used to identify the SVG layer.
     *      Defaults to 'embeddedIcon'.
     */
    loadIcon(div, glyphId: string = 'unknown', size: number = 20, installGlyph: boolean = true, svgClass: string = 'embeddedIcon') {
        const dim = size || 20;
        const svgCls = svgClass || 'embeddedIcon';
        const gid = glyphId || 'unknown';
        let g;
        let svgIcon: any;

        if (installGlyph) {
            this.gs.loadDefs(this.ensureIconLibDefs(), [gid], true);
        }
        this.log.warn('loadEmbeddedIcon. install done');

        svgIcon = div
            .append('svg')
            .attr('class', svgCls)
            .attr('width', dim)
            .attr('height', dim)
            .attr('viewBox', viewBox);

        g = svgIcon.append('g')
            .attr('class', 'icon');

        g.append('rect')
            .attr('width', vboxSize)
            .attr('height', vboxSize)
            .attr('rx', cornerSize);

        g.append('use')
            .attr('width', vboxSize)
            .attr('height', vboxSize)
            .attr('class', 'glyph')
            .attr('xlink:href', '#' + gid);
    }

    /**
     * Load an icon by class.
     * @param div A D3 selection of the <DIV> element into which icon should load
     * @param iconCls The CSS class used to identify the icon
     * @param {number} size The dimension of icon in pixels. Defaults to 20.
     * @param {boolean} installGlyph If truthy, will cause the glyph to be added to
     *      well-known defs element. Defaults to false.
     * @param svgClass The CSS class used to identify the SVG layer.
     *      Defaults to 'embeddedIcon'.
     */
    loadIconByClass(div, iconCls: string, size: number, installGlyph: boolean, svgClass= 'embeddedIcon') {
        this.loadIcon(div, glyphMapping.get(iconCls), size, installGlyph, svgClass);
        div.select('svg g').classed(iconCls, true);
    }

    /**
     * Load an embedded icon.
     */
    loadEmbeddedIcon(div, iconCls: string, size: number) {
        this.loadIconByClass(div, iconCls, size, true);
    }

    /**
     * Load an icon only to the svg defs collection
     *
     * Note: This is added for use with IconComponent, where the icon's
     * svg element is defined in the component template (and not built
     * inline using d3 manipulation
     *
     * @param iconCls The icon class as a string
     */
    loadIconDef(iconCls: string): void {
        this.gs.loadDefs(this.ensureIconLibDefs(), [glyphMapping.get(iconCls)], true);
        this.log.debug('icon definition', iconCls, 'added to defs');
    }


    /**
     * Add a device icon
     *
     * Adds a device glyph to the specified element.
     * Returns the D3 selection of the glyph (use) element.
     */
    addDeviceIcon(elem, glyphId, iconDim) {
        const gid = this.gs.glyphDefined(glyphId) ? glyphId : 'query';
        return elem.append('use').attr({
            'xlink:href': '#' + gid,
            width: iconDim,
            height: iconDim,
        });
    }

    addHostIcon(elem, radius, glyphId) {
        const dim = radius * 1.5;
        const xlate = -dim / 2;
        const g = elem.append('g')
                .attr('class', 'svgIcon hostIcon');

        g.append('circle').attr('r', radius);

        g.append('use').attr({
            'xlink:href': '#' + glyphId,
            width: dim,
            height: dim,
            transform: this.sus.translate([xlate], xlate),
        });
        return g;
    }

    registerIconMapping(iconId, glyphId) {
        if (glyphMapping[iconId]) {
            this.log.warn('Icon with id', iconId, 'already mapped. Ignoring.');
        } else {
            // map icon-->glyph
            glyphMapping[iconId] = glyphId;
            // make sure definition is installed
            this.gs.loadDefs(this.ensureIconLibDefs(), [glyphId], true);
        }
    }
}
