/*
 * 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.
 */

/*
 ONOS GUI -- Topology Force Module.
 Visualization of the topology in an SVG layer, using a D3 Force Layout.
 */

(function () {
    'use strict';

    // injected refs
    var $log, $timeout, fs, sus, ts, flash, wss, tov,
        tis, tms, td3, tss, tts, tos, fltr, tls, uplink, svg, tpis;

    // function to be replaced by the localization bundle function
    var topoLion = function (x) {
        return '#tfs#' + x + '#';
    };

    // 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
        devIconDim = 36, // node target dimension
        devIconDimMin = 20, // node minimum dimension when zoomed out
        devIconDimMax = 40, // node maximum dimension when zoomed in
        portLabelDim = 30;

    // SVG elements;
    var linkG, linkLabelG, numLinkLblsG, portLabelG, nodeG;

    // D3 selections;
    var link, linkLabel, node;

    // 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,
        },
    };


    // ==========================
    // === EVENT HANDLERS

    function addDevice(data) {
        var id = data.id,
            d;

        uplink.showNoDevs(false);

        // although this is an add device event, if we already have the
        //  device, treat it as an update instead..
        if (lu[id]) {
            updateDevice(data);
            return;
        }

        d = tms.createDeviceNode(data);
        network.nodes.push(d);
        lu[id] = d;
        updateNodes();
        fStart();
    }

    function updateDevice(data) {
        var id = data.id,
            d = lu[id],
            wasOnline;

        if (d) {
            wasOnline = d.online;
            angular.extend(d, data);
            if (tms.positionNode(d, true)) {
                sendUpdateMeta(d);
            }
            updateNodes();
            if (wasOnline !== d.online) {
                tms.findAttachedLinks(d.id).forEach(restyleLinkElement);
                updateOfflineVisibility(d);
            }
        }
    }

    function removeDevice(data) {
        var id = data.id,
            d = lu[id];
        if (d) {
            removeDeviceElement(d);
        }
    }

    function addHost(data) {
        var id = data.id,
            d;

        // although this is an add host event, if we already have the
        //  host, treat it as an update instead..
        if (lu[id]) {
            updateHost(data);
            return;
        }

        d = tms.createHostNode(data);
        network.nodes.push(d);
        lu[id] = d;
        updateNodes();

        // need to handle possible multiple links (multi-homed host)
        createHostLinks(data.allCps, d);

        if (d.links.length) {
            updateLinks();
        }
        fStart();
    }

    function updateHost(data) {
        var id = data.id,
            d = lu[id];
        if (d) {
            angular.extend(d, data);
            if (tms.positionNode(d, true)) {
                sendUpdateMeta(d);
            }
            updateNodes();
        }
    }

    function createHostLinks(cps, model) {
        model.links = [];
        cps.forEach(function (cp) {
            var linkData = {
                key: model.id + '/0-' + cp.device + '/' + cp.port,
                dst: cp.device,
                dstPort: cp.port,
            };
            model.links.push(linkData);

            var lnk = tms.createHostLink(model.id, cp.device, cp.port);
            if (lnk) {
                network.links.push(lnk);
                lu[linkData.key] = lnk;
            }
        });
    }

    function moveHost(data) {
        var id = data.id,
            d = lu[id];

        if (d) {
            removeAllLinkElements(d.links);

            // merge new data
            angular.extend(d, data);
            if (tms.positionNode(d, true)) {
                sendUpdateMeta(d);
            }

            // now create new host link(s)
            createHostLinks(data.allCps, d);

            updateNodes();
            updateLinks();
            fResume();
        }
    }

    function removeHost(data) {
        var id = data.id,
            d = lu[id];
        if (d) {
            removeHostElement(d, true);
        }
    }

    function addLink(data) {
        var result = tms.findLink(data, 'add'),
            bad = result.badLogic,
            d = result.ldata;

        if (bad) {
            $log.debug(bad + ': ' + link.id);
            return;
        }

        if (d) {
            // we already have a backing store link for src/dst nodes
            addLinkUpdate(d, data);
            return;
        }

        // no backing store link yet
        d = tms.createLink(data);
        if (d) {
            network.links.push(d);
            aggregateLink(d, data);
            lu[d.key] = d;
            updateLinks();
            fStart();
        }
    }

    function updateLink(data) {
        var result = tms.findLink(data, 'update'),
            bad = result.badLogic;
        if (bad) {
            $log.debug(bad + ': ' + link.id);
            return;
        }
        result.updateWith(data);
    }

    function removeLink(data) {
        var result = tms.findLink(data, 'remove');

        if (!result.badLogic) {
            result.removeRawLink();
        }
    }

    function topoStartDone(data) {
        // called when the initial barrage of data has been sent from server
        uplink.topoStartDone();
    }

    // ========================

    function nodeById(id) {
        return lu[id];
    }

    function makeNodeKey(node1, node2) {
        return node1 + '-' + node2;
    }

    function findNodePair(key, keyRev) {
        if (network.linksByDevice[key]) {
            return key;
        } else if (network.linksByDevice[keyRev]) {
            return keyRev;
        } else {
            return false;
        }
    }

    function aggregateLink(ldata, link) {
        var key = makeNodeKey(link.src, link.dst),
            keyRev = makeNodeKey(link.dst, link.src),
            found = findNodePair(key, keyRev);

        if (found) {
            network.linksByDevice[found].push(ldata);
            ldata.devicePair = found;
        } else {
            network.linksByDevice[key] = [ldata];
            ldata.devicePair = key;
        }
    }

    function addLinkUpdate(ldata, link) {
        // add link event, but we already have the reverse link installed
        ldata.fromTarget = link;
        rlk[link.id] = ldata.key;
        // possible solution to el being undefined in restyleLinkElement:
        // _updateLinks();
        restyleLinkElement(ldata);
    }


    var widthRatio = 1.4,
        linkScale = d3.scale.linear()
            .domain([1, 12])
            .range([widthRatio, 12 * widthRatio])
            .clamp(true),
        allLinkTypes = 'direct indirect optical tunnel',
        allLinkSubTypes = 'inactive not-permitted';

    function restyleLinkElement(ldata, immediate) {
        // this fn's job is to look at raw links and decide what svg classes
        // need to be applied to the line element in the DOM
        var th = ts.theme(),
            el = ldata.el,
            type = ldata.type(),
            lw = ldata.linkWidth(),
            online = ldata.online(),
            modeCls = ldata.expected() ? 'inactive' : 'not-permitted',
            delay = immediate ? 0 : 1000;

        // NOTE: understand why el is sometimes undefined on addLink events...
        // Investigated:
        // el is undefined when it's a reverse link that is being added.
        // updateLinks (which sets ldata.el) isn't called before this is called.
        // Calling _updateLinks in addLinkUpdate fixes it, but there might be
        // a more efficient way to fix it.
        if (el && !el.empty()) {
            el.classed('link', true);
            el.classed(allLinkSubTypes, false);
            el.classed(modeCls, !online);
            el.classed(allLinkTypes, false);
            if (type) {
                el.classed(type, true);
            }
            el.transition()
                .duration(delay)
                .attr('stroke-width', linkScale(lw))
                .attr('stroke', linkConfig[th].baseColor);
        }
    }

    function removeAllLinkElements(links) {
        links.forEach(function (lnk) {
            removeLinkElement(lnk);
        });
    }

    function removeLinkElement(d) {
        var idx = fs.find(d.key, network.links, 'key'),
            removed;
        if (idx >=0) {
            // remove from links array
            removed = network.links.splice(idx, 1);
            // remove from lookup cache
            delete lu[removed[0].key];
            updateLinks();
            fResume();
        }
    }

    function removeHostElement(d, upd) {
        // first, remove associated hostLink(s)...
        removeAllLinkElements(d.links);

        // remove from lookup cache
        delete lu[d.id];
        // remove from nodes array
        var idx = fs.find(d.id, network.nodes);
        network.nodes.splice(idx, 1);

        // remove from SVG
        // NOTE: upd is false if we were called from removeDeviceElement()
        if (upd) {
            updateNodes();
            fResume();
        }
    }

    function removeDeviceElement(d) {
        var id = d.id,
            idx;
        // first, remove associated hosts and links..
        tms.findAttachedHosts(id).forEach(removeHostElement);
        tms.findAttachedLinks(id).forEach(removeLinkElement);

        // remove from lookup cache
        delete lu[id];
        // remove from nodes array
        idx = fs.find(id, network.nodes);
        if (idx > -1) {
            network.nodes.splice(idx, 1);
        }

        if (!network.nodes.length) {
            uplink.showNoDevs(true);
        }

        // remove from SVG
        updateNodes();
        fResume();
    }

    function updateHostVisibility() {
        sus.visible(nodeG.selectAll('.host'), showHosts);
        sus.visible(linkG.selectAll('.hostLink'), showHosts);
        sus.visible(linkLabelG.selectAll('.hostLinkLabel'), showHosts);
    }

    function updateOfflineVisibility(dev) {
        function updDev(d, show) {
            var b;
            sus.visible(d.el, show);

            tms.findAttachedLinks(d.id).forEach(function (link) {
                b = show && ((link.type() !== 'hostLink') || showHosts);
                sus.visible(link.el, b);
            });
            tms.findAttachedHosts(d.id).forEach(function (host) {
                b = show && showHosts;
                sus.visible(host.el, b);
            });
        }

        if (dev) {
            // updating a specific device that just toggled off/on-line
            updDev(dev, dev.online || showOffline);
        } else {
            // updating all offline devices
            tms.findDevices(true).forEach(function (d) {
                updDev(d, showOffline);
            });
        }
    }


    function sendUpdateMeta(d, clearPos) {
        var metaUi = {},
            ll;

        // if we are not clearing the position data (unpinning),
        // attach the x, y, (and equivalent longitude, latitude)...
        if (!clearPos) {
            ll = tms.lngLatFromCoord([d.x, d.y]);
            metaUi = {
                x: d.x,
                y: d.y,
                equivLoc: {
                    lng: ll[0],
                    lat: ll[1],
                },
            };
        }
        d.metaUi = metaUi;
        wss.sendEvent('updateMeta', {
            id: d.id,
            class: d.class,
            memento: metaUi,
        });
    }


    function mkSvgClass(d) {
        return d.fixed ? d.svgClass + ' fixed' : d.svgClass;
    }

    function vis(b) {
        return topoLion(b ? 'visible' : 'hidden');
    }

    function toggleHosts(x) {
        var kev = (x === 'keyev'),
            on = kev ? !showHosts : !!x;

        showHosts = on;
        updateHostVisibility();
        flash.flash(topoLion('hosts') + ' ' + vis(on));
        return on;
    }

    function toggleOffline(x) {
        var kev = (x === 'keyev'),
            on = kev ? !showOffline : !!x;

        showOffline = on;
        updateOfflineVisibility();
        flash.flash(topoLion('fl_offline_devices') + ' ' + vis(on));
        return on;
    }

    function cycleDeviceLabels() {
        flash.flash(td3.incDevLabIndex());
        tms.findDevices().forEach(function (d) {
            td3.updateDeviceLabel(d);
        });
    }

    function cycleHostLabels() {
        flash.flash(td3.incHostLabIndex());
        tms.findHosts().forEach(function (d) {
            td3.updateHostLabel(d);
        });
    }

    function unpin() {
        var hov = tss.hovered();
        if (hov) {
            sendUpdateMeta(hov, true);
            hov.fixed = false;
            hov.el.classed('fixed', false);
            fResume();
        }
    }

    function showMastership(masterId) {
        if (!masterId) {
            restoreLayerState();
        } else {
            showMastershipFor(masterId);
        }
    }

    function restoreLayerState() {
        // NOTE: this level of indirection required, for when we have
        //          the layer filter functionality re-implemented
        suppressLayers(false);
    }

    function showMastershipFor(id) {
        suppressLayers(true);
        node.each(function (n) {
            if (n.master === id) {
                n.el.classed('suppressedmax', false);
            }
        });
    }

    function supAmt(less) {
        return less ? 'suppressed' : 'suppressedmax';
    }

    function suppressLayers(b, less) {
        var cls = supAmt(less);
        node.classed(cls, b);
        link.classed(cls, b);
    }

    function unsuppressNode(id, less) {
        var cls = supAmt(less);
        node.each(function (n) {
            if (n.id === id) {
                n.el.classed(cls, false);
            }
        });
    }

    function unsuppressLink(key, less) {
        var cls = supAmt(less);
        link.each(function (n) {
            if (n.key === key) {
                n.el.classed(cls, false);
            }
        });
    }

    function showBadLinks() {
        var badLinks = tms.findBadLinks();
        flash.flash(topoLion('fl_bad_links') + ': ' + badLinks.length);
        $log.debug('Bad Link List (' + badLinks.length + '):');
        badLinks.forEach(function (d) {
            $log.debug('bad link: (' + d.bad + ') ' + d.key, d);
            if (d.el) {
                d.el.attr('stroke-width', linkScale(2.8))
                    .attr('stroke', 'red');
            }
        });
        // back to normal after 2 seconds...
        $timeout(updateLinks, 2000);
    }

    function deviceScale() {
        var scale = uplink.zoomer().scale(),
            dim = devIconDim,
            multiplier = 1;

        if (dim * scale < devIconDimMin) {
            multiplier = devIconDimMin / (dim * scale);
        } else if (dim * scale > devIconDimMax) {
            multiplier = devIconDimMax / (dim * scale);
        }

        return multiplier;
    }

    function linkWidthScale(scale) {
        var scale = uplink.zoomer().scale();
        return linkScale(widthRatio) / scale;
    }

    function portLabelScale(scale) {
        var scale = uplink.zoomer().scale();
        return portLabelDim / (portLabelDim * scale);
    }

    function setNodeScale(scale) {
        // Scale the network nodes
        _.each(network.nodes, function (node) {
            if (node.class === 'host') {
                node.el.selectAll('g').style('transform', 'scale(' + deviceScale(scale) + ')');
                node.el.selectAll('text').style('transform', 'scale(' + deviceScale(scale) + ')');
                return;
            }
            node.el.selectAll('*')
                .style('transform', 'scale(' + deviceScale(scale) + ')');
        });

        // Scale the network links
        _.each(network.links, function (link) {
            link.el.style('stroke-width', linkWidthScale(scale) + 'px');
        });

        d3.select('#topo-portLabels')
            .selectAll('.portLabel')
            .selectAll('*')
            .style('transform', 'scale(' + portLabelScale(scale) + ')');
    }

    function resetAllLocations() {
        tms.resetAllLocations();
        updateNodes();
        tick(); // force nodes to be redrawn in their new locations
        flash.flash(topoLion('fl_reset_node_locations'));
    }

    // ==========================================

    function updateNodes() {
        if (fNodesTimer) {
            $timeout.cancel(fNodesTimer);
        }
        fNodesTimer = $timeout(_updateNodes, 150);
    }

    // IMPLEMENTATION NOTE: _updateNodes() should NOT stop, start, or resume
    //  the force layout; that needs to be determined and implemented elsewhere
    function _updateNodes() {
        // select all the nodes in the layout:
        node = nodeG.selectAll('.node')
            .data(network.nodes, function (d) { return d.id; });

        // operate on existing nodes:
        node.filter('.device').each(td3.deviceExisting);
        node.filter('.host').each(td3.hostExisting);

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

        // augment entering nodes:
        entering.filter('.device').each(td3.deviceEnter);
        entering.filter('.host').each(td3.hostEnter);

        // operate on both existing and new nodes:
        td3.updateDeviceColors();

        // operate on exiting nodes:
        // Note that the node is removed after 2 seconds.
        // Sub element animations should be shorter than 2 seconds.
        var exiting = node.exit()
            .transition()
            .duration(2000)
            .style('opacity', 0)
            .remove();

        // exiting node specifics:
        exiting.filter('.host').each(td3.hostExit);
        exiting.filter('.device').each(td3.deviceExit);
    }

    // ==========================

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

    // returns amount of adjustment along the normal for given link
    function amt(numLinks, linkIdx) {
        var gap = 6;
        return (linkIdx - ((numLinks - 1) / 2)) * gap;
    }

    function calcMovement(d, amt, flipped) {
        var pos = getDefaultPos(d),
            mult = flipped ? -amt : amt,
            dx = pos.x2 - pos.x1,
            dy = pos.y2 - pos.y1,
            length = Math.sqrt((dx * dx) + (dy * dy));

        return {
            x1: pos.x1 + (mult * dy / length),
            y1: pos.y1 + (mult * -dx / length),
            x2: pos.x2 + (mult * dy / length),
            y2: pos.y2 + (mult * -dx / length),
        };
    }

    function calcPosition() {
        var lines = this,
            linkSrcId;
        linkNums = [];
        lines.each(function (d) {
            if (d.type() === 'hostLink') {
                d.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;
        }

        angular.forEach(network.linksByDevice, function (linkArr, key) {
            var numLinks = linkArr.length,
                link;

            if (numLinks === 1) {
                link = linkArr[0];
                link.position = getDefaultPos(link);
                link.position.multiLink = false;
            } else if (numLinks >= 5) {
                // this code is inefficient, in the future the way links
                // are modeled will be changed
                angular.forEach(linkArr, function (link) {
                    link.position = getDefaultPos(link);
                    link.position.multiLink = true;
                });
                linkNums.push({
                    id: key,
                    num: numLinks,
                    linkCoords: linkArr[0].position,
                });
            } else {
                linkSrcId = null;
                angular.forEach(linkArr, function (link, index) {
                    var offsetAmt = amt(numLinks, index),
                        needToFlip = normalizeLinkSrc(link);
                    link.position = calcMovement(link, offsetAmt, needToFlip);
                    link.position.multiLink = false;
                });
            }
        });
    }

    function updateLinks() {
        if (fLinksTimer) {
            $timeout.cancel(fLinksTimer);
        }
        fLinksTimer = $timeout(_updateLinks, 150);
    }

    // IMPLEMENTATION NOTE: _updateLinks() should NOT stop, start, or resume
    //  the force layout; that needs to be determined and implemented elsewhere
    function _updateLinks() {
        var th = ts.theme();

        link = linkG.selectAll('.link')
            .data(network.links, function (d) { return d.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.position.x1; },
                y1: function (d) { return d.position.y1; },
                x2: function (d) { return d.position.x2; },
                y2: function (d) { return d.position.y2; },
                stroke: linkConfig[th].inColor,
                'stroke-width': linkConfig.inWidth,
            });

        // augment links
        entering.each(td3.linkEntering);

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

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

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

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


    // ==========================
    // force layout tick function

    function fResume() {
        if (!tos.isOblique()) {
            force.resume();
        }
    }

    function fStart() {
        if (!tos.isOblique()) {
            if (fTimer) {
                $timeout.cancel(fTimer);
            }
            fTimer = $timeout(function () {
                $log.debug('Starting force-layout');
                force.start();
            }, 200);
        }
    }

    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.position.x1; },
            y1: function (d) { return d.position.y1; },
            x2: function (d) { return d.position.x2; },
            y2: function (d) { return d.position.y2; },
        },
        linkLabelAttr: {
            transform: function (d) {
                var lnk = tms.findLinkById(d.key);
                if (lnk) {
                    return td3.transformLabel(lnk.position, d.key);
                }
            },
        },
    };

    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);
            td3.applyNumLinkLabels(linkNums, numLinkLblsG);
        }
        if (linkLabel && linkLabel.size()) {
            linkLabel.attr(tickStuff.linkLabelAttr);
        }
    }


    // ==========================
    // === MOUSE GESTURE HANDLERS

    function zoomingOrPanning(ev) {
        return ev.metaKey || ev.altKey;
    }

    function atDragEnd(d) {
        // once we've finished moving, pin the node in position
        d.fixed = true;
        d3.select(this).classed('fixed', true);
        sendUpdateMeta(d);
        tss.clickConsumed(true);
    }

    // predicate that indicates when dragging is active
    function dragEnabled() {
        var ev = d3.event.sourceEvent;
        // nodeLock means we aren't allowing nodes to be dragged...
        return !nodeLock && !zoomingOrPanning(ev);
    }

    // predicate that indicates when clicking is active
    function clickEnabled() {
        return true;
    }

    // =============================================
    // function entry points for overlay module

    // TODO: find an automatic way of tracking via the "showHighlights" events
    var allTrafficClasses = 'primary secondary optical animated ' +
        'port-traffic-green port-traffic-yellow port-traffic-orange ' +
        'port-traffic-red';

    function clearLinkTrafficStyle() {
        link.style('stroke-width', null)
            .classed(allTrafficClasses, false);
    }

    function removeLinkLabels() {
        network.links.forEach(function (d) {
            d.label = '';
        });
    }

    function clearNodeDeco() {
        node.selectAll('g.badge').remove();
    }

    function removeNodeBadges() {
        network.nodes.forEach(function (d) {
            d.badge = null;
        });
    }

    function updateLinkLabelModel() {
        // create the backing data for showing labels..
        var data = [];
        link.each(function (d) {
            if (d.label) {
                data.push({
                    id: 'lab-' + d.key,
                    key: d.key,
                    label: d.label,
                    ldata: d,
                });
            }
        });

        linkLabel = linkLabelG.selectAll('.linkLabel')
            .data(data, function (d) { return d.id; });
    }

    // ==========================
    // Module definition

    function mkModelApi(uplink) {
        return {
            projection: uplink.projection,
            network: network,
            restyleLinkElement: restyleLinkElement,
            removeLinkElement: removeLinkElement,
        };
    }

    function mkD3Api() {
        return {
            node: function () { return node; },
            link: function () { return link; },
            linkLabel: function () { return linkLabel; },
            instVisible: function () { return tis.isVisible(); },
            posNode: tms.positionNode,
            showHosts: function () { return showHosts; },
            restyleLinkElement: restyleLinkElement,
            updateLinkLabelModel: updateLinkLabelModel,
            linkConfig: function () { return linkConfig; },
            deviceScale: deviceScale,
            linkWidthScale: linkWidthScale,
        };
    }

    function mkSelectApi() {
        return {
            node: function () { return node; },
            zoomingOrPanning: zoomingOrPanning,
            updateDeviceColors: td3.updateDeviceColors,
            deselectAllLinks: tls.deselectAllLinks,
        };
    }

    function mkTrafficApi() {
        return {
            hovered: tss.hovered,
            somethingSelected: tss.somethingSelected,
            selectOrder: tss.selectOrder,
        };
    }

    function mkOverlayApi() {
        return {
            clearNodeDeco: clearNodeDeco,
            removeNodeBadges: removeNodeBadges,
            clearLinkTrafficStyle: clearLinkTrafficStyle,
            removeLinkLabels: removeLinkLabels,
            findLinkById: tms.findLinkById,
            findNodeById: nodeById,
            updateLinks: updateLinks,
            updateNodes: updateNodes,
            supLayers: suppressLayers,
            unsupNode: unsuppressNode,
            unsupLink: unsuppressLink,
        };
    }

    function mkObliqueApi(uplink, fltr) {
        return {
            force: function () { return force; },
            zoomLayer: uplink.zoomLayer,
            nodeGBBox: function () { return nodeG.node().getBBox(); },
            node: function () { return node; },
            link: function () { return link; },
            linkLabel: function () { return linkLabel; },
            nodes: function () { return network.nodes; },
            tickStuff: tickStuff,
            nodeLock: function (b) {
                var old = nodeLock;
                nodeLock = b;
                return old;
            },
            opacifyMap: uplink.opacifyMap,
            inLayer: fltr.inLayer,
            calcLinkPos: calcPosition,
            applyNumLinkLabels: function () {
                td3.applyNumLinkLabels(linkNums, numLinkLblsG);
            },
        };
    }

    function mkFilterApi() {
        return {
            node: function () { return node; },
            link: function () { return link; },
        };
    }

    function mkLinkApi(svg, uplink) {
        return {
            svg: svg,
            zoomer: uplink.zoomer(),
            network: network,
            portLabelG: function () { return portLabelG; },
            showHosts: function () { return showHosts; },
        };
    }

    function updateLinksAndNodes() {
        updateLinks();
        updateNodes();
    }

    // invoked after the localization bundle has been received from the server
    function setLionBundle(bundle) {
        topoLion = bundle;
        td3.setLionBundle(bundle);
        fltr.setLionBundle(bundle);
        tls.setLionBundle(bundle);
        tos.setLionBundle(bundle);
        tov.setLionBundle(bundle);
        tss.setLionBundle(bundle);
    }

    angular.module('ovTopo')
    .factory('TopoForceService',
        ['$log', '$timeout', 'FnService', 'SvgUtilService',
            'ThemeService', 'FlashService', 'WebSocketService',
            'TopoOverlayService', 'TopoInstService', 'TopoModelService',
            'TopoD3Service', 'TopoSelectService', 'TopoTrafficService',
            'TopoObliqueService', 'TopoFilterService', 'TopoLinkService',
            'TopoProtectedIntentsService',

        function (_$log_, _$timeout_, _fs_, _sus_, _ts_, _flash_, _wss_, _tov_,
                  _tis_, _tms_, _td3_, _tss_, _tts_, _tos_, _fltr_, _tls_, _tpis_) {
            $log = _$log_;
            $timeout = _$timeout_;
            fs = _fs_;
            sus = _sus_;
            ts = _ts_;
            flash = _flash_;
            wss = _wss_;
            tov = _tov_;
            tis = _tis_;
            tms = _tms_;
            td3 = _td3_;
            tss = _tss_;
            tts = _tts_;
            tos = _tos_;
            fltr = _fltr_;
            tls = _tls_;
            tpis = _tpis_;

            ts.addListener(updateLinksAndNodes);

            // forceG is the SVG group to display the force layout in
            // uplink is the api from the main topo source file
            // dim is the initial dimensions of the SVG as [w,h]
            // opts are, well, optional :)
            function initForce(_svg_, forceG, _uplink_, _dim_, opts) {
                uplink = _uplink_;
                dim = _dim_;
                svg = _svg_;

                lu = network.lookup;
                rlk = network.revLinkToKey;

                $log.debug('initForce().. dim = ' + dim);

                tov.setApi(mkOverlayApi(), tss);
                tms.initModel(mkModelApi(uplink), dim);
                td3.initD3(mkD3Api(), uplink.zoomer());
                tss.initSelect(mkSelectApi());
                tts.initTraffic(mkTrafficApi());
                tpis.initProtectedIntents(mkTrafficApi());
                tos.initOblique(mkObliqueApi(uplink, fltr));
                fltr.initFilter(mkFilterApi());
                tls.initLink(mkLinkApi(svg, uplink), td3);

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

                linkG = forceG.append('g').attr('id', 'topo-links');
                linkLabelG = forceG.append('g').attr('id', 'topo-linkLabels');
                numLinkLblsG = 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(dim)
                    .nodes(network.nodes)
                    .links(network.links)
                    .gravity(settings.gravity)
                    .friction(settings.friction)
                    .charge(settings.charge._def_)
                    .linkDistance(settings.linkDistance._def_)
                    .linkStrength(settings.linkStrength._def_)
                    .on('tick', tick);

                drag = sus.createDragBehavior(force,
                    tss.selectObject, atDragEnd, dragEnabled, clickEnabled);
            }

            function newDim(_dim_) {
                dim = _dim_;
                force.size(dim);
                tms.newDim(dim);
            }

            function destroyForce() {
                force.stop();

                tls.destroyLink();
                tos.destroyOblique();
                tts.destroyTraffic();
                tpis.destroyProtectedIntents();
                tss.destroySelect();
                td3.destroyD3();
                tms.destroyModel();
                // note: no need to destroy overlay service
                ts.removeListener(updateLinksAndNodes);

                // clean up the DOM
                svg.selectAll('g').remove();
                svg.selectAll('defs').remove();

                // clean up internal state
                network.nodes = [];
                network.links = [];
                network.linksByDevice = {};
                network.lookup = {};
                network.revLinkToKey = {};

                linkNums = [];

                linkG = linkLabelG = numLinkLblsG = nodeG = portLabelG = null;
                link = linkLabel = node = null;
                force = drag = null;

                // clean up $timeout promises
                if (fTimer) {
                    $timeout.cancel(fTimer);
                }
                if (fNodesTimer) {
                    $timeout.cancel(fNodesTimer);
                }
                if (fLinksTimer) {
                    $timeout.cancel(fLinksTimer);
                }
            }

            return {
                initForce: initForce,
                newDim: newDim,
                destroyForce: destroyForce,

                updateDeviceColors: td3.updateDeviceColors,
                toggleHosts: toggleHosts,
                togglePorts: tls.togglePorts,
                toggleOffline: toggleOffline,
                cycleDeviceLabels: cycleDeviceLabels,
                cycleHostLabels: cycleHostLabels,
                unpin: unpin,
                showMastership: showMastership,
                showBadLinks: showBadLinks,
                setNodeScale: setNodeScale,

                resetAllLocations: resetAllLocations,
                addDevice: addDevice,
                updateDevice: updateDevice,
                removeDevice: removeDevice,
                addHost: addHost,
                updateHost: updateHost,
                moveHost: moveHost,
                removeHost: removeHost,
                addLink: addLink,
                updateLink: updateLink,
                removeLink: removeLink,
                topoStartDone: topoStartDone,

                setLionBundle: setLionBundle,
            };
        }]);
}());
