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

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

        // 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();

        lnk = tms.createHostLink(data);
        if (lnk) {
            d.linkData = lnk; // cache ref on its host
            network.links.push(lnk);
            lu[d.ingress] = lnk;
            lu[d.egress] = lnk;
            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 moveHost(data) {
        var id = data.id,
            d = lu[id],
            lnk;
        if (d) {
            // first remove the old host link
            removeLinkElement(d.linkData);

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

            // now create a new host link
            lnk = tms.createHostLink(data);
            if (lnk) {
                d.linkData = lnk;
                network.links.push(lnk);
                lu[d.ingress] = lnk;
                lu[d.egress] = lnk;
            }

            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 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...
        removeLinkElement(d.linkData);

        // remove hostLink bindings
        delete lu[d.ingress];
        delete lu[d.egress];

        // 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 b ? 'visible' : 'hidden';
    }

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

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

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

        showOffline = on;
        updateOfflineVisibility();
        flash.flash('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('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('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();
    }

    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,
            };
        }]);
}());
