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

    // reference to the framework api
    var api = onos.api;

    // configuration data
    var config = {
        useLiveData: false,
        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 view = {},
        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', view.width)
            .attr('height', view.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: view.width,
                height: view.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() {
        view.height = window.innerHeight - config.mastHeight;
        view.width = window.innerWidth;
        $('#view')
            .css('height', view.height + 'px')
            .css('width', view.width + 'px');

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

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

    api.addView('network', {
        load: loadNetworkView
    });


}(ONOS));

