/*
 * Copyright 2016-present Open Networking Laboratory
 *
 * 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 Layout Module.
 Module that contains the d3.force.layout logic
 */

(function () {
    'use strict';

    var $log, sus, t2rs, t2d3, t2vs;

    var linkG, linkLabelG, numLinkLabelsG, nodeG, portLabelG;
    var link, linkLabel, node;

    var nodes, links;

    var force;

    // default settings for force layout
    var defaultSettings = {
        gravity: 0.4,
        friction: 0.7,
        charge: {
            // note: key is node.class
            device: -8000,
            host: -5000,
            _def_: -12000
        },
        linkDistance: {
            // note: key is link.type
            direct: 100,
            optical: 120,
            hostLink: 3,
            _def_: 50
        },
        linkStrength: {
            // note: key is link.type
            // range: {0.0 ... 1.0}
            //direct: 1.0,
            //optical: 1.0,
            //hostLink: 1.0,
            _def_: 1.0
        }
    };

    // configuration
    var linkConfig = {
        light: {
            baseColor: '#939598',
            inColor: '#66f',
            outColor: '#f00'
        },
        dark: {
            // TODO : theme
            baseColor: '#939598',
            inColor: '#66f',
            outColor: '#f00'
        },
        inWidth: 12,
        outWidth: 10
    };

    // internal state
    var settings,   // merged default settings and options
        force,      // force layout object
        drag,       // drag behavior handler
        network = {
            nodes: [],
            links: [],
            linksByDevice: {},
            lookup: {},
            revLinkToKey: {}
        },
        lu,                     // shorthand for lookup
        rlk,                    // shorthand for revLinktoKey
        showHosts = false,      // whether hosts are displayed
        showOffline = true,     // whether offline devices are displayed
        nodeLock = false,       // whether nodes can be dragged or not (locked)
        fTimer,                 // timer for delayed force layout
        fNodesTimer,            // timer for delayed nodes update
        fLinksTimer,            // timer for delayed links update
        dim,                    // the dimensions of the force layout [w,h]
        linkNums = [];          // array of link number labels

    var tickStuff = {
        nodeAttr: {
            transform: function (d) {
                var dx = isNaN(d.x) ? 0 : d.x,
                    dy = isNaN(d.y) ? 0 : d.y;
                return sus.translate(dx, dy);
            }
        },
        linkAttr: {
            x1: function (d) { return d.get('position').x1; },
            y1: function (d) { return d.get('position').y1; },
            x2: function (d) { return d.get('position').x2; },
            y2: function (d) { return d.get('position').y2; }
        },
        linkLabelAttr: {
            transform: function (d) {
                var lnk = tms.findLinkById(d.get('key'));
                if (lnk) {
                    return t2d3.transformLabel(lnk.get('position'));
                }
            }
        }
    };

    function init(_svg_, forceG, _uplink_, _dim_, opts) {

        $log.debug("Initialising Topology Layout");

        settings = angular.extend({}, defaultSettings, opts);

        linkG = forceG.append('g').attr('id', 'topo-links');
        linkLabelG = forceG.append('g').attr('id', 'topo-linkLabels');
        numLinkLabelsG = forceG.append('g').attr('id', 'topo-numLinkLabels');
        nodeG = forceG.append('g').attr('id', 'topo-nodes');
        portLabelG = forceG.append('g').attr('id', 'topo-portLabels');

        link = linkG.selectAll('.link');
        linkLabel = linkLabelG.selectAll('.linkLabel');
        node = nodeG.selectAll('.node');

        force = d3.layout.force()
            .size(t2vs.getDimensions())
            .nodes(t2rs.regionNodes())
            .links(t2rs.regionLinks())
            .gravity(settings.gravity)
            .friction(settings.friction)
            .charge(settings.charge._def_)
            .linkDistance(settings.linkDistance._def_)
            .linkStrength(settings.linkStrength._def_)
            .on('tick', tick);
    }

    function tick() {
        // guard against null (which can happen when our view pages out)...
        if (node && node.size()) {
            node.attr(tickStuff.nodeAttr);
        }
        if (link && link.size()) {
            link.call(calcPosition)
                .attr(tickStuff.linkAttr);
            // t2d3.applyNumLinkLabels(linkNums, numLinkLabelsG);
        }
        if (linkLabel && linkLabel.size()) {
            linkLabel.attr(tickStuff.linkLabelAttr);
        }
    }

    function update() {
        _updateNodes();
        _updateLinks();
    }

    function _updateNodes() {

        var regionNodes = t2rs.regionNodes();

        // select all the nodes in the layout:
        node = nodeG.selectAll('.node')
            .data(regionNodes, function (d) { return d.get('id'); });

        var entering = node.enter()
            .append('g')
            .attr({
                id: function (d) { return sus.safeId(d.get('id')); },
                class: function (d) { return d.svgClassName() },
                transform: function (d) {
                    // Need to guard against NaN here ??
                    return sus.translate(d.node.x, d.node.y);
                },
                opacity: 0
            })
            // .on('mouseover', tss.nodeMouseOver)
            // .on('mouseout', tss.nodeMouseOut)
            .transition()
            .attr('opacity', 1);

        entering.filter('.device').each(t2d3.nodeEnter);
        entering.filter('.sub-region').each(t2d3.nodeEnter);
        entering.filter('.host').each(t2d3.hostEnter);

        // operate on both existing and new nodes:
        // node.filter('.device').each(function (device) {
        //     t2d3.updateDeviceColors(device);
        // });
    }

    function _updateLinks() {

        // var th = ts.theme();
        var regionLinks = t2rs.regionLinks();

        link = linkG.selectAll('.link')
            .data(regionLinks, function (d) { return d.get('key'); });

        // operate on existing links:
        link.each(function (d) {
            // this is supposed to be an existing link, but we have observed
            //  occasions (where links are deleted and added rapidly?) where
            //  the DOM element has not been defined. So protect against that...
            if (d.el) {
                restyleLinkElement(d, true);
            }
        });

        // operate on entering links:
        var entering = link.enter()
            .append('line')
            .call(calcPosition)
            .attr({
                x1: function (d) { return d.get('position').x1; },
                y1: function (d) { return d.get('position').y1; },
                x2: function (d) { return d.get('position').x2; },
                y2: function (d) { return d.get('position').y2; },
                stroke: linkConfig['light'].inColor,
                'stroke-width': linkConfig.inWidth
            });

        entering.each(t2d3.linkEntering);

        // operate on both existing and new links:
        //link.each(...)

        // add labels for how many links are in a thick line
        // t2d3.applyNumLinkLabels(linkNums, numLinkLabelsG);

        // apply or remove labels
        // t2d3.applyLinkLabels();

        // operate on exiting links:
        link.exit()
            .attr('stroke-dasharray', '3 3')
            .attr('stroke', linkConfig['light'].outColor)
            .style('opacity', 0.5)
            .transition()
            .duration(1500)
            .attr({
                'stroke-dasharray': '3 12',
                'stroke-width': linkConfig.outWidth
            })
            .style('opacity', 0.0)
            .remove();
    }

    function calcPosition() {
        var lines = this,
            linkSrcId,
            linkNums = [];

		lines.each(function (d) {
            if (d.get('type') === 'hostLink') {
                d.set('position', getDefaultPos(d));
            }
        });

        function normalizeLinkSrc(link) {
            // ensure source device is consistent across set of links
            // temporary measure until link modeling is refactored
            if (!linkSrcId) {
                linkSrcId = link.source.id;
                return false;
            }

            return link.source.id !== linkSrcId;
        }

        lines.each(function (d) {
            d.set('position', getDefaultPos(d));
        });
    }

	function getDefaultPos(link) {

        return {
            x1: link.get('source').x,
            y1: link.get('source').y,
            x2: link.get('target').x,
            y2: link.get('target').y
        };
    }

    function setDimensions() {
        if (force) {
            force.size(t2vs.getDimensions());
        }
    }


    function start() {
        force.start();
    }

    angular.module('ovTopo2')
    .factory('Topo2LayoutService',
        [
            '$log', 'SvgUtilService', 'Topo2RegionService',
            'Topo2D3Service', 'Topo2ViewService',

            function (_$log_, _sus_, _t2rs_, _t2d3_, _t2vs_) {

                $log = _$log_;
                t2rs = _t2rs_;
                t2d3 = _t2d3_;
                t2vs = _t2vs_;
                sus = _sus_;

                return {
                    init: init,
                    update: update,
                    start: start,

                    setDimensions: setDimensions
                }
            }
        ]
    );
})();
