/*
 * Copyright 2014 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 network topology viewer - PoC version 1.0

 @author Simon Hunt
 */

(function (onos) {
    'use strict';

    // configuration data
    var config = {
        useLiveData: true,
        debugOn: false,
        debug: {
            showNodeXY: false,
            showKeyHandler: true
        },
        options: {
            layering: true,
            collisionPrevention: true,
            loadBackground: true
        },
        backgroundUrl: 'img/us-map.png',
        data: {
            live: {
                jsonUrl: 'rs/topology/graph',
                detailPrefix: 'rs/topology/graph/',
                detailSuffix: ''
            },
            fake: {
                jsonUrl: 'json/network2.json',
                detailPrefix: 'json/',
                detailSuffix: '.json'
            }
        },
        iconUrl: {
            device: 'img/device.png',
            host: 'img/host.png',
            pkt: 'img/pkt.png',
            opt: 'img/opt.png'
        },
        mastHeight: 36,
        force: {
            note: 'node.class or link.class is used to differentiate',
            linkDistance: {
                infra: 200,
                host: 40
            },
            linkStrength: {
                infra: 1.0,
                host: 1.0
            },
            charge: {
                device: -800,
                host: -1000
            },
            ticksWithoutCollisions: 50,
            marginLR: 20,
            marginTB: 20,
            translate: function() {
                return 'translate(' +
                    config.force.marginLR + ',' +
                    config.force.marginTB + ')';
            }
        },
        labels: {
            imgPad: 16,
            padLR: 8,
            padTB: 6,
            marginLR: 3,
            marginTB: 2,
            port: {
                gap: 3,
                width: 18,
                height: 14
            }
        },
        icons: {
            w: 32,
            h: 32,
            xoff: -12,
            yoff: -8
        },
        constraints: {
            ypos: {
                host: 0.05,
                switch: 0.3,
                roadm: 0.7
            }
        },
        hostLinkWidth: 1.0,
        hostRadius: 7,
        mouseOutTimerDelayMs: 120
    };

    // state variables
    var netView = {},
        network = {},
        selected = {},
        highlighted = null,
        hovered = null,
        viewMode = 'showAll',
        portLabelsOn = false;


    function debug(what) {
        return config.debugOn && config.debug[what];
    }

    function urlData() {
        return config.data[config.useLiveData ? 'live' : 'fake'];
    }

    function networkJsonUrl() {
        return urlData().jsonUrl;
    }

    function safeId(id) {
        return id.replace(/[^a-z0-9]/gi, '_');
    }

    function detailJsonUrl(id) {
        var u = urlData(),
            encId = config.useLiveData ? encodeURIComponent(id) : safeId(id);
        return u.detailPrefix + encId + u.detailSuffix;
    }


    // load the topology view of the network
    function loadNetworkView() {
        // Hey, here I am, calling something on the ONOS api:
        api.printTime();

        resize();

        // go get our network data from the server...
        var url = networkJsonUrl();
        d3.json(url , function (err, data) {
            if (err) {
                alert('Oops! Error reading JSON...\n\n' +
                    'URL: ' + url + '\n\n' +
                    'Error: ' + err.message);
                return;
            }
//            console.log("here is the JSON data...");
//            console.log(data);

            network.data = data;
            drawNetwork();
        });

        // while we wait for the data, set up the handlers...
        setUpClickHandler();
        setUpRadioButtonHandler();
        setUpKeyHandler();
        $(window).on('resize', resize);
    }

    function setUpClickHandler() {
        // click handler for "selectable" objects
        $(document).on('click', '.select-object', function () {
            // when any object of class "select-object" is clicked...
            var obj = network.lookup[$(this).data('id')];
            if (obj) {
                selectObject(obj);
            }
            // stop propagation of event (I think) ...
            return false;
        });
    }

    function setUpRadioButtonHandler() {
        d3.selectAll('#displayModes .radio').on('click', function () {
            var id = d3.select(this).attr('id');
            if (id !== viewMode) {
                radioButton('displayModes', id);
                viewMode = id;
                doRadioAction(id);
            }
        });
    }

    function doRadioAction(id) {
        showAllLayers();
        if (id === 'showPkt') {
            showPacketLayer();
        } else if (id === 'showOpt') {
            showOpticalLayer();
        }
    }

    function showAllLayers() {
        network.node.classed('inactive', false);
        network.link.classed('inactive', false);
        d3.selectAll('svg .port').classed('inactive', false);
        d3.selectAll('svg .portText').classed('inactive', false);
    }

    function showPacketLayer() {
        network.node.each(function(d) {
            // deactivate nodes that are not hosts or switches
            if (d.class === 'device' && d.type !== 'switch') {
                d3.select(this).classed('inactive', true);
            }
        });

        network.link.each(function(lnk) {
            // deactivate infrastructure links that have opt's as endpoints
            if (lnk.source.type === 'roadm' || lnk.target.type === 'roadm') {
                d3.select(this).classed('inactive', true);
            }
        });

        // deactivate non-packet ports
        d3.selectAll('svg .optPort').classed('inactive', true)
    }

    function showOpticalLayer() {
        network.node.each(function(d) {
            // deactivate nodes that are not optical devices
            if (d.type !== 'roadm') {
                d3.select(this).classed('inactive', true);
            }
        });

        network.link.each(function(lnk) {
            // deactivate infrastructure links that have opt's as endpoints
            if (lnk.source.type !== 'roadm' || lnk.target.type !== 'roadm') {
                d3.select(this).classed('inactive', true);
            }
        });

        // deactivate non-packet ports
        d3.selectAll('svg .pktPort').classed('inactive', true)
    }

    function setUpKeyHandler() {
        d3.select('body')
            .on('keydown', function () {
                processKeyEvent();
                if (debug('showKeyHandler')) {
                    network.svg.append('text')
                        .attr('x', 5)
                        .attr('y', 15)
                        .style('font-size', '20pt')
                        .text('keyCode: ' + d3.event.keyCode +
                            ' applied to : ' + contextLabel())
                        .transition().duration(2000)
                        .style('font-size', '2pt')
                        .style('fill-opacity', 0.01)
                        .remove();
                }
            });
    }

    function contextLabel() {
        return hovered === null ? "(nothing)" : hovered.id;
    }

    function radioButton(group, id) {
        d3.selectAll("#" + group + " .radio").classed("active", false);
        d3.select("#" + group + " #" + id).classed("active", true);
    }

    function processKeyEvent() {
        var code = d3.event.keyCode;
        switch (code) {
            case 66:    // B
                toggleBackground();
                break;
            case 71:    // G
                cycleLayout();
                break;
            case 76:    // L
                cycleLabels();
                break;
            case 80:    // P
                togglePorts();
                break;
            case 85:    // U
                unpin();
                break;
        }

    }

    function toggleBackground() {
        var bg = d3.select('#bg'),
            vis = bg.style('visibility'),
            newvis = (vis === 'hidden') ? 'visible' : 'hidden';
        bg.style('visibility', newvis);
    }

    function cycleLayout() {
        config.options.layering = !config.options.layering;
        network.force.resume();
    }

    function cycleLabels() {
        console.log('Cycle Labels - context = ' + contextLabel());
    }

    function togglePorts() {
        portLabelsOn = !portLabelsOn;
        var portVis = portLabelsOn ? 'visible' : 'hidden';
        d3.selectAll('.port').style('visibility', portVis);
        d3.selectAll('.portText').style('visibility', portVis);
    }

    function unpin() {
        if (hovered) {
            hovered.fixed = false;
            findNodeFromData(hovered).classed('fixed', false);
            network.force.resume();
        }
        console.log('Unpin - context = ' + contextLabel());
    }


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

    function drawNetwork() {
        $('#view').empty();

        prepareNodesAndLinks();
        createLayout();
        console.log("\n\nHere is the augmented network object...");
        console.log(network);
    }

    function prepareNodesAndLinks() {
        network.lookup = {};
        network.nodes = [];
        network.links = [];

        var nw = network.forceWidth,
            nh = network.forceHeight;

        function yPosConstraintForNode(n) {
            return config.constraints.ypos[n.type || 'host'];
        }

        // Note that both 'devices' and 'hosts' get mapped into the nodes array

        // first, the devices...
        network.data.devices.forEach(function(n) {
            var ypc = yPosConstraintForNode(n),
                ix = Math.random() * 0.6 * nw + 0.2 * nw,
                iy = ypc * nh,
                node = {
                    id: n.id,
                    labels: n.labels,
                    class: 'device',
                    icon: 'device',
                    type: n.type,
                    x: ix,
                    y: iy,
                    constraint: {
                        weight: 0.7,
                        y: iy
                    }
                };
            network.lookup[n.id] = node;
            network.nodes.push(node);
        });

        // then, the hosts...
        network.data.hosts.forEach(function(n) {
            var ypc = yPosConstraintForNode(n),
                ix = Math.random() * 0.6 * nw + 0.2 * nw,
                iy = ypc * nh,
                node = {
                    id: n.id,
                    labels: n.labels,
                    class: 'host',
                    icon: 'host',
                    type: n.type,
                    x: ix,
                    y: iy,
                    constraint: {
                        weight: 0.7,
                        y: iy
                    }
                };
            network.lookup[n.id] = node;
            network.nodes.push(node);
        });


        // now, process the explicit links...
        network.data.links.forEach(function(lnk) {
            var src = network.lookup[lnk.src],
                dst = network.lookup[lnk.dst],
                id = src.id + "-" + dst.id;

            var link = {
                class: 'infra',
                id: id,
                type: lnk.type,
                width: lnk.linkWidth,
                source: src,
                srcPort: lnk.srcPort,
                target: dst,
                tgtPort: lnk.dstPort,
                strength: config.force.linkStrength.infra
            };
            network.links.push(link);
        });

        // finally, infer host links...
        network.data.hosts.forEach(function(n) {
            var src = network.lookup[n.id],
                dst = network.lookup[n.cp.device],
                id = src.id + "-" + dst.id;

            var link = {
                class: 'host',
                id: id,
                type: 'hostLink',
                width: config.hostLinkWidth,
                source: src,
                target: dst,
                strength: config.force.linkStrength.host
            };
            network.links.push(link);
        });
    }

    function createLayout() {

        var cfg = config.force;

        network.force = d3.layout.force()
            .size([network.forceWidth, network.forceHeight])
            .nodes(network.nodes)
            .links(network.links)
            .linkStrength(function(d) { return cfg.linkStrength[d.class]; })
            .linkDistance(function(d) { return cfg.linkDistance[d.class]; })
            .charge(function(d) { return cfg.charge[d.class]; })
            .on('tick', tick);

        network.svg = d3.select('#view').append('svg')
            .attr('width', netView.width)
            .attr('height', netView.height)
            .append('g')
            .attr('transform', config.force.translate());
//            .attr('id', 'zoomable')
//            .call(d3.behavior.zoom().on("zoom", zoomRedraw));

        network.svg.append('svg:image')
            .attr({
                id: 'bg',
                width: netView.width,
                height: netView.height,
                'xlink:href': config.backgroundUrl
            })
            .style('visibility',
                    config.options.loadBackground ? 'visible' : 'hidden');

//        function zoomRedraw() {
//            d3.select("#zoomable").attr("transform",
//                    "translate(" + d3.event.translate + ")"
//                    + " scale(" + d3.event.scale + ")");
//        }

        // TODO: move glow/blur stuff to util script
        var glow = network.svg.append('filter')
            .attr('x', '-50%')
            .attr('y', '-50%')
            .attr('width', '200%')
            .attr('height', '200%')
            .attr('id', 'blue-glow');

        glow.append('feColorMatrix')
            .attr('type', 'matrix')
            .attr('values', '0 0 0 0  0 ' +
                '0 0 0 0  0 ' +
                '0 0 0 0  .7 ' +
                '0 0 0 1  0 ');

        glow.append('feGaussianBlur')
            .attr('stdDeviation', 3)
            .attr('result', 'coloredBlur');

        glow.append('feMerge').selectAll('feMergeNode')
            .data(['coloredBlur', 'SourceGraphic'])
            .enter().append('feMergeNode')
            .attr('in', String);

        // TODO: legend (and auto adjust on scroll)
//        $('#view').on('scroll', function() {
//
//        });


        // TODO: move drag behavior into separate method.
        // == define node drag behavior...
        network.draggedThreshold = d3.scale.linear()
            .domain([0, 0.1])
            .range([5, 20])
            .clamp(true);

        function dragged(d) {
            var threshold = network.draggedThreshold(network.force.alpha()),
                dx = d.oldX - d.px,
                dy = d.oldY - d.py;
            if (Math.abs(dx) >= threshold || Math.abs(dy) >= threshold) {
                d.dragged = true;
            }
            return d.dragged;
        }

        network.drag = d3.behavior.drag()
            .origin(function(d) { return d; })
            .on('dragstart', function(d) {
                d.oldX = d.x;
                d.oldY = d.y;
                d.dragged = false;
                d.fixed |= 2;
            })
            .on('drag', function(d) {
                d.px = d3.event.x;
                d.py = d3.event.y;
                if (dragged(d)) {
                    if (!network.force.alpha()) {
                        network.force.alpha(.025);
                    }
                }
            })
            .on('dragend', function(d) {
                if (!dragged(d)) {
                    selectObject(d, this);
                }
                d.fixed &= ~6;

                // once we've finished moving, pin the node in position,
                // if it is a device (not a host)
                if (d.class === 'device') {
                    d.fixed = true;
                    d3.select(this).classed('fixed', true)
                }
            });

        $('#view').on('click', function(e) {
            if (!$(e.target).closest('.node').length) {
                deselectObject();
            }
        });

        // ...............................................................

        // add links to the display
        network.link = network.svg.append('g').attr('id', 'links')
            .selectAll('.link')
            .data(network.force.links(), function(d) {return d.id})
            .enter().append('line')
            .attr('class', function(d) {return 'link ' + d.class});

        network.linkSrcPort = network.svg.append('g')
            .attr({
                id: 'srcPorts',
                class: 'portLayer'
            });
        network.linkTgtPort = network.svg.append('g')
            .attr({
                id: 'tgtPorts',
                class: 'portLayer'
            });

        var portVis = portLabelsOn ? 'visible' : 'hidden',
            pw = config.labels.port.width,
            ph = config.labels.port.height;

        network.link.filter('.infra').each(function(d) {
            var srcType = d.source.type === 'roadm' ? 'optPort' : 'pktPort',
                tgtType = d.target.type === 'roadm' ? 'optPort' : 'pktPort';

            if (d.source.type)

            network.linkSrcPort.append('rect').attr({
                id: 'srcPort-' + safeId(d.id),
                class: 'port ' + srcType,
                width: pw,
                height: ph,
                rx: 4,
                ry: 4
            }).style('visibility', portVis);

            network.linkTgtPort.append('rect').attr({
                id: 'tgtPort-' + safeId(d.id),
                class: 'port ' + tgtType,
                width: pw,
                height: ph,
                rx: 4,
                ry: 4
            }).style('visibility', portVis);

            network.linkSrcPort.append('text').attr({
                id: 'srcText-' + safeId(d.id),
                class: 'portText ' + srcType
            }).text(d.srcPort)
                .style('visibility', portVis);

            network.linkTgtPort.append('text').attr({
                id: 'tgtText-' + safeId(d.id),
                class: 'portText ' + tgtType
            }).text(d.tgtPort)
                .style('visibility', portVis);
        });

        // ...............................................................

        // add nodes to the display
        network.node = network.svg.selectAll('.node')
            .data(network.force.nodes(), function(d) {return d.id})
            .enter().append('g')
            .attr('class', function(d) {
                var cls = 'node ' + d.class;
                if (d.type) {
                    cls += ' ' + d.type;
                }
                return cls;
            })
            .attr('transform', function(d) {
                return translate(d.x, d.y);
            })
            .call(network.drag)
            .on('mouseover', function(d) {
                // TODO: show tooltip
                if (network.mouseoutTimeout) {
                    clearTimeout(network.mouseoutTimeout);
                    network.mouseoutTimeout = null;
                }
                hoverObject(d);
            })
            .on('mouseout', function(d) {
                // TODO: hide tooltip
                if (network.mouseoutTimeout) {
                    clearTimeout(network.mouseoutTimeout);
                    network.mouseoutTimeout = null;
                }
                network.mouseoutTimeout = setTimeout(function() {
                    hoverObject(null);
                }, config.mouseOutTimerDelayMs);
            });


        // deal with device nodes first
        network.nodeRect = network.node.filter('.device')
            .append('rect')
            .attr({
                rx: 5,
                ry: 5,
                width: 100,
                height: 12
            });
            // note that width/height are adjusted to fit the label text
            // then padded, and space made for the icon.

        network.node.filter('.device').each(function(d) {
            var node = d3.select(this),
                icon = iconUrl(d);

            node.append('text')
            // TODO: add label cycle behavior
                .text(d.id)
                .attr('dy', '1.1em');

            if (icon) {
                var cfg = config.icons;
                node.append('svg:image')
                    .attr({
                        width: cfg.w,
                        height: cfg.h,
                        'xlink:href': icon
                    });
                // note, icon relative positioning (x,y) is done after we have
                // adjusted the bounds of the rectangle...
            }

            // debug function to show the modelled x,y coordinates of nodes...
            if (debug('showNodeXY')) {
                node.select('rect').attr('fill-opacity', 0.5);
                node.append('circle')
                    .attr({
                        class: 'debug',
                        cx: 0,
                        cy: 0,
                        r: '3px'
                    });
            }
        });

        // now process host nodes
        network.nodeCircle = network.node.filter('.host')
            .append('circle')
            .attr({
                r: config.hostRadius
            });

        network.node.filter('.host').each(function(d) {
            var node = d3.select(this),
                icon = iconUrl(d);

            // debug function to show the modelled x,y coordinates of nodes...
            if (debug('showNodeXY')) {
                node.select('circle').attr('fill-opacity', 0.5);
                node.append('circle')
                    .attr({
                        class: 'debug',
                        cx: 0,
                        cy: 0,
                        r: '3px'
                    });
            }
        });

        // this function is scheduled to happen soon after the given thread ends
        setTimeout(function() {
            var lab = config.labels,
                portGap = lab.port.gap,
                midW = portGap + lab.port.width/ 2,
                midH = portGap + lab.port.height / 2;

            // post process the device nodes, to pad their size to fit the
            // label text and attach the icon to the right location.
            network.node.filter('.device').each(function(d) {
                // for every node, recompute size, padding, etc. so text fits
                var node = d3.select(this),
                    text = node.select('text'),
                    box = adjustRectToFitText(node);

                // now make the computed adjustment
                node.select('rect')
                    .attr(box);

                node.select('image')
                    .attr('x', box.x + config.icons.xoff)
                    .attr('y', box.y + config.icons.yoff);

                var bounds = boundsFromBox(box),
                    portBounds = {
                        x1: bounds.x1 - midW,
                        x2: bounds.x2 + midW,
                        y1: bounds.y1 - midH,
                        y2: bounds.y2 + midH
                    };

                // todo: clean up extent and edge work..
                d.extent = {
                    left: bounds.x1 - lab.marginLR,
                    right: bounds.x2 + lab.marginLR,
                    top: bounds.y1 - lab.marginTB,
                    bottom: bounds.y2 + lab.marginTB
                };

                d.edge = {
                    left   : new geo.LineSegment(bounds.x1, bounds.y1, bounds.x1, bounds.y2),
                    right  : new geo.LineSegment(bounds.x2, bounds.y1, bounds.x2, bounds.y2),
                    top    : new geo.LineSegment(bounds.x1, bounds.y1, bounds.x2, bounds.y1),
                    bottom : new geo.LineSegment(bounds.x1, bounds.y2, bounds.x2, bounds.y2)
                };

                d.portEdge = {
                    left   : new geo.LineSegment(
                        portBounds.x1, portBounds.y1, portBounds.x1, portBounds.y2
                    ),
                    right  : new geo.LineSegment(
                        portBounds.x2, portBounds.y1, portBounds.x2, portBounds.y2
                    ),
                    top    : new geo.LineSegment(
                        portBounds.x1, portBounds.y1, portBounds.x2, portBounds.y1
                    ),
                    bottom : new geo.LineSegment(
                        portBounds.x1, portBounds.y2, portBounds.x2, portBounds.y2
                    )
                };

            });

            network.numTicks = 0;
            network.preventCollisions = false;
            network.force.start();
            for (var i = 0; i < config.force.ticksWithoutCollisions; i++) {
                network.force.tick();
            }
            network.preventCollisions = true;
            $('#view').css('visibility', 'visible');
        });


        // returns the newly computed bounding box of the rectangle
        function adjustRectToFitText(n) {
            var text = n.select('text'),
                box = text.node().getBBox(),
                lab = config.labels;

            // not sure why n.data() returns an array of 1 element...
            var data = n.data()[0];

            text.attr('text-anchor', 'middle')
                .attr('y', '-0.8em')
                .attr('x', lab.imgPad/2)
            ;

            // translate the bbox so that it is centered on [x,y]
            box.x = -box.width / 2;
            box.y = -box.height / 2;

            // add padding
            box.x -= (lab.padLR + lab.imgPad/2);
            box.width += lab.padLR * 2 + lab.imgPad;
            box.y -= lab.padTB;
            box.height += lab.padTB * 2;

            return box;
        }

        function boundsFromBox(box) {
            return {
                x1: box.x,
                y1: box.y,
                x2: box.x + box.width,
                y2: box.y + box.height
            };
        }

    }

    function iconUrl(d) {
        return 'img/' + d.type + '.png';
//        return config.iconUrl[d.icon];
    }

    function translate(x, y) {
        return 'translate(' + x + ',' + y + ')';
    }

    // prevents collisions amongst device nodes
    function preventCollisions() {
        var quadtree = d3.geom.quadtree(network.nodes),
            hrad = config.hostRadius;

        network.nodes.forEach(function(n) {
            var nx1, nx2, ny1, ny2;

            if (n.class === 'device') {
                nx1 = n.x + n.extent.left;
                nx2 = n.x + n.extent.right;
                ny1 = n.y + n.extent.top;
                ny2 = n.y + n.extent.bottom;

            } else {
                nx1 = n.x - hrad;
                nx2 = n.x + hrad;
                ny1 = n.y - hrad;
                ny2 = n.y + hrad;
            }

            quadtree.visit(function(quad, x1, y1, x2, y2) {
                if (quad.point && quad.point !== n) {
                    // check if the rectangles/circles intersect
                    var p = quad.point,
                        px1, px2, py1, py2, ix;

                    if (p.class === 'device') {
                        px1 = p.x + p.extent.left;
                        px2 = p.x + p.extent.right;
                        py1 = p.y + p.extent.top;
                        py2 = p.y + p.extent.bottom;

                    } else {
                        px1 = p.x - hrad;
                        px2 = p.x + hrad;
                        py1 = p.y - hrad;
                        py2 = p.y + hrad;
                    }

                    ix = (px1 <= nx2 && nx1 <= px2 && py1 <= ny2 && ny1 <= py2);

                    if (ix) {
                        var xa1 = nx2 - px1, // shift n left , p right
                            xa2 = px2 - nx1, // shift n right, p left
                            ya1 = ny2 - py1, // shift n up   , p down
                            ya2 = py2 - ny1, // shift n down , p up
                            adj = Math.min(xa1, xa2, ya1, ya2);

                        if (adj == xa1) {
                            n.x -= adj / 2;
                            p.x += adj / 2;
                        } else if (adj == xa2) {
                            n.x += adj / 2;
                            p.x -= adj / 2;
                        } else if (adj == ya1) {
                            n.y -= adj / 2;
                            p.y += adj / 2;
                        } else if (adj == ya2) {
                            n.y += adj / 2;
                            p.y -= adj / 2;
                        }
                    }
                    return ix;
                }
            });

        });
    }

    function tick(e) {
        network.numTicks++;

        if (config.options.layering) {
            // adjust the y-coord of each node, based on y-pos constraints
            network.nodes.forEach(function (n) {
                var z = e.alpha * n.constraint.weight;
                if (!isNaN(n.constraint.y)) {
                    n.y = (n.constraint.y * z + n.y * (1 - z));
                }
            });
        }

        if (config.options.collisionPrevention && network.preventCollisions) {
            preventCollisions();
        }

        var portHalfW = config.labels.port.width / 2,
            portHalfH = config.labels.port.height / 2;

        // clip visualization of links at bounds of nodes...
        network.link.each(function(d) {
            var xs = d.source.x,
                ys = d.source.y,
                xt = d.target.x,
                yt = d.target.y,
                line = new geo.LineSegment(xs, ys, xt, yt),
                e, ix,
                exs, eys, ext, eyt,
                pxs, pys, pxt, pyt;

            if (d.class === 'host') {
                // no adjustment for source end of link, since hosts are dots
                exs = xs;
                eys = ys;

            } else {
                for (e in d.source.edge) {
                    ix = line.intersect(d.source.edge[e].offset(xs, ys));
                    if (ix.in1 && ix.in2) {
                        exs = ix.x;
                        eys = ix.y;

                        // also pick off the port label intersection
                        ix = line.intersect(d.source.portEdge[e].offset(xs, ys));
                        pxs = ix.x;
                        pys = ix.y;
                        break;
                    }
                }
            }

            for (e in d.target.edge) {
                ix = line.intersect(d.target.edge[e].offset(xt, yt));
                if (ix.in1 && ix.in2) {
                    ext = ix.x;
                    eyt = ix.y;

                    // also pick off the port label intersection
                    ix = line.intersect(d.target.portEdge[e].offset(xt, yt));
                    pxt = ix.x;
                    pyt = ix.y;
                    break;
                }
            }

            // adjust the endpoints of the link's line to match rectangles
            var sid = safeId(d.id);
            d3.select(this)
                .attr('x1', exs)
                .attr('y1', eys)
                .attr('x2', ext)
                .attr('y2', eyt);

            d3.select('#srcPort-' + sid)
                .attr('x', pxs - portHalfW)
                .attr('y', pys - portHalfH);

            d3.select('#tgtPort-' + sid)
                .attr('x', pxt - portHalfW)
                .attr('y', pyt - portHalfH);

            // TODO: fit label rect to size of port number.
            d3.select('#srcText-' + sid)
                .attr('x', pxs - 5)
                .attr('y', pys + 3);

            d3.select('#tgtText-' + sid)
                .attr('x', pxt - 5)
                .attr('y', pyt + 3);

        });

        // position each node by translating the node (group) by x,y
        network.node
            .attr('transform', function(d) {
                return translate(d.x, d.y);
            });

    }

    //    $('#docs-close').on('click', function() {
    //        deselectObject();
    //        return false;
    //    });

    //    $(document).on('click', '.select-object', function() {
    //        var obj = graph.data[$(this).data('name')];
    //        if (obj) {
    //            selectObject(obj);
    //        }
    //        return false;
    //    });

    function findNodeFromData(d) {
        var el = null;
        network.node.filter('.' + d.class).each(function(n) {
            if (n.id === d.id) {
                el = d3.select(this);
            }
        });
        return el;
    }

    function selectObject(obj, el) {
        var node;
        if (el) {
            node = d3.select(el);
        } else {
            network.node.each(function(d) {
                if (d == obj) {
                    node = d3.select(el = this);
                }
            });
        }
        if (!node) return;

        if (node.classed('selected')) {
            deselectObject();
            flyinPane(null);
            return;
        }
        deselectObject(false);

        selected = {
            obj : obj,
            el  : el
        };

        node.classed('selected', true);
        flyinPane(obj);
    }

    function deselectObject(doResize) {
        // Review: logic of 'resize(...)' function.
        if (doResize || typeof doResize == 'undefined') {
            resize(false);
        }

        // deselect all nodes in the network...
        network.node.classed('selected', false);
        selected = {};
        flyinPane(null);
    }

    function flyinPane(obj) {
        var pane = d3.select('#flyout'),
            url;

        if (obj) {
            // go get details of the selected object from the server...
            url = detailJsonUrl(obj.id);
            d3.json(url, function (err, data) {
                if (err) {
                    alert('Oops! Error reading JSON...\n\n' +
                        'URL: ' + url + '\n\n' +
                        'Error: ' + err.message);
                    return;
                }
//                console.log("JSON data... " + url);
//                console.log(data);

                displayDetails(data, pane);
            });

        } else {
            // hide pane
            pane.transition().duration(750)
                .style('right', '-320px')
                .style('opacity', 0.0);
        }
    }

    function displayDetails(data, pane) {
        $('#flyout').empty();

        var title = pane.append("h2"),
            table = pane.append("table"),
            tbody = table.append("tbody");

        $('<img src="img/' + data.type + '.png">').appendTo(title);
        $('<span>').attr('class', 'icon').text(data.id).appendTo(title);


        // TODO: consider using d3 data bind to TR/TD

        data.propOrder.forEach(function(p) {
            if (p === '-') {
                addSep(tbody);
            } else {
                addProp(tbody, p, data.props[p]);
            }
        });

        function addSep(tbody) {
            var tr = tbody.append('tr');
            $('<hr>').appendTo(tr.append('td').attr('colspan', 2));
        }

        function addProp(tbody, label, value) {
            var tr = tbody.append('tr');

            tr.append('td')
                .attr('class', 'label')
                .text(label + ' :');

            tr.append('td')
                .attr('class', 'value')
                .text(value);
        }

        // show pane
        pane.transition().duration(750)
            .style('right', '20px')
            .style('opacity', 1.0);
    }

    function highlightObject(obj) {
        if (obj) {
            if (obj != highlighted) {
                // TODO set or clear "inactive" class on nodes, based on criteria
                network.node.classed('inactive', function(d) {
                    //                return (obj !== d &&
                    //                    d.relation(obj.id));
                    return (obj !== d);
                });
                // TODO: same with links
                network.link.classed('inactive', function(d) {
                    return (obj !== d.source && obj !== d.target);
                });
            }
            highlighted = obj;
        } else {
            if (highlighted) {
                // clear the inactive flag (no longer suppressed visually)
                network.node.classed('inactive', false);
                network.link.classed('inactive', false);
            }
            highlighted = null;

        }
    }

    function hoverObject(obj) {
        if (obj) {
            hovered = obj;
        } else {
            if (hovered) {
                hovered = null;
            }
        }
    }


    function resize() {
        netView.height = window.innerHeight - config.mastHeight;
        netView.width = window.innerWidth;
        $('#view')
            .css('height', netView.height + 'px')
            .css('width', netView.width + 'px');

        network.forceWidth = netView.width - config.force.marginLR;
        network.forceHeight = netView.height - config.force.marginTB;
    }

    // ======================================================================
    // register with the UI framework

    onos.ui.addView('topo', {
        load: loadNetworkView
    });


}(ONOS));

