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

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

    // 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 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 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-Kbps port-traffic-Mbps port-traffic-Gbps ' +
        'port-traffic-Gbps-choked';

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

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

    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',

        function (_$log_, _$timeout_, _fs_, _sus_, _ts_, _flash_, _wss_, _tov_,
                  _tis_, _tms_, _td3_, _tss_, _tts_, _tos_, _fltr_, _tls_) {
            $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_;

            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());
                tss.initSelect(mkSelectApi());
                tts.initTraffic(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();
                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,
                unpin: unpin,
                showMastership: showMastership,
                showBadLinks: showBadLinks,

                resetAllLocations: resetAllLocations,
                addDevice: addDevice,
                updateDevice: updateDevice,
                removeDevice: removeDevice,
                addHost: addHost,
                updateHost: updateHost,
                moveHost: moveHost,
                removeHost: removeHost,
                addLink: addLink,
                updateLink: updateLink,
                removeLink: removeLink,
                topoStartDone: topoStartDone
            };
        }]);
}());
