/*
 * 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: 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 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);
    }

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

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

    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, i) {
            network.linkSrcPort.append('rect').attr({
                id: 'srcPort-' + safeId(d.id),
                class: 'port',
                width: pw,
                height: ph,
                Xx: i * 20,
                Xy: 0,
                rx: 4,
                ry: 4
            }).style('visibility', portVis);

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

            network.linkSrcPort.append('text').attr({
                id: 'srcText-' + safeId(d.id),
                class: 'portText',
                Xx: i * 20,
                Xy: 0
            }).text(d.srcPort)
                .style('visibility', portVis);

            network.linkTgtPort.append('text').attr({
                id: 'tgtText-' + safeId(d.id),
                class: 'portText',
                Xx: i * 20,
                Xy: 20
            }).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));

