/*
 * 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 { EventEmitter } from '@angular/core';
import { Link } from './link';
import { Node } from './node';
import * as d3 from 'd3-force';
import {LogService} from 'gui2-fw-lib/public_api';

const FORCES = {
    COLLISION: 1,
    GRAVITY: 0.4,
    FRICTION: 0.7
};

const CHARGES = {
    device: -800,
    host: -2000,
    region: -800,
    _def_: -1200
};

const LINK_DISTANCE = {
    // note: key is link.type
    direct: 100,
    optical: 120,
    UiEdgeLink: 3,
    UiDeviceLink: 100,
    _def_: 50,
};

/**
 * note: key is link.type
 * range: {0.0 ... 1.0}
 */
const LINK_STRENGTH = {
    _def_: 0.5
};

export interface Options {
    width: number;
    height: number;
}

/**
 * The inspiration for this approach comes from
 * https://medium.com/netscape/visualizing-data-with-angular-and-d3-209dde784aeb
 *
 * Do yourself a favour and read https://d3indepth.com/force-layout/
 */
export class ForceDirectedGraph {
    public ticker: EventEmitter<d3.Simulation<Node, Link>> = new EventEmitter();
    public simulation: d3.Simulation<any, any>;
    public canvasOptions: Options;
    public nodes: Node[] = [];
    public links: Link[] = [];

    constructor(options: Options, public log: LogService) {
        this.canvasOptions = options;
        const ticker = this.ticker;

        // Creating the force simulation and defining the charges
        this.simulation = d3.forceSimulation()
            .force('charge',
                d3.forceManyBody().strength(this.charges.bind(this)))
            // .distanceMin(100).distanceMax(500))
            .force('gravity',
                d3.forceManyBody().strength(FORCES.GRAVITY))
            .force('friction',
                d3.forceManyBody().strength(FORCES.FRICTION))
            .force('center',
                d3.forceCenter(this.canvasOptions.width / 2, this.canvasOptions.height / 2))
            .force('x', d3.forceX())
            .force('y', d3.forceY())
            .on('tick', () => {
                ticker.emit(this.simulation); // ForceSvgComponent.ngOnInit listens
            });

    }

    /**
     * Assigning updated node and restarting the simulation
     * Setting alpha to 0.3 and it will count down to alphaTarget=0
     */
    public reinitSimulation() {
        this.simulation.nodes(this.nodes);
        this.simulation.force('link',
            d3.forceLink(this.links)
                .strength(LINK_STRENGTH._def_)
                .distance(this.distance.bind(this))
        );
        this.simulation.alpha(0.3).restart();
    }

    charges(node: Node) {
        const nodeType = node.nodeType;
        return CHARGES[nodeType] || CHARGES._def_;
    }

    distance(link: Link) {
        const linkType = link.type;
        return LINK_DISTANCE[linkType] || LINK_DISTANCE._def_;
    }

    stopSimulation() {
        this.simulation.stop();
        this.log.debug('Simulation stopped');
    }

    public restartSimulation(alpha: number = 0.3) {
        this.simulation.alpha(alpha).restart();
        this.log.debug('Simulation restarted. Alpha:', alpha);
    }
}
