<!DOCTYPE html>
<html>
<head>
    <title>Topology Viewer</title>
    <script src="libs/d3.v3.min.js"></script>
    <script src="libs/jquery-1.11.1.min.js"></script>
    <style>
        .link {
        }

        .node {
            stroke-width: 3px;
        }

        .textClass {
            stroke: #323232;
            font-family: "Lucida Grande", "Droid Sans", Arial, Helvetica, sans-serif;
            font-weight: normal;
            stroke-width: .5;
            font-size: 14px;
        }
    </style>
</head>
<body>
    <script>
        // Adapted from sample code @ ericcoopey’s block #6c602d7cb14b25c179a4
        // by Thomas Vachuska

        var graph,
                topo = {vertexes:{}, edges:{}},
                paths = [],
                currentPath = 0;

        // Set up the canvas
        var w = 2048,
                h = 2048;

        // Allocate colors predictably
        var color = d3.scale.category10(),
                deviceColor = color(2),
                sourceColor = color(0),
                targetColor = color(1),
                dummy1Color = color(9),
                dummy2Color = color(8),
                dummy3Color = color(7),
                dummy4Color = color(6),
                offlineColor = color(5),
                dummy5Color = color(4),
                hostColor = color(3);

        var selectedNode,
                sourceNode,
                targetNode,
                pathRequested;


        function fillColor(d) {
            return ((targetNode && targetNode.id == d.id) ? targetColor :
                    ((sourceNode && sourceNode.id == d.id) ? sourceColor :
                            d.online ? color(d.group) : offlineColor));
        }

        function strokeColor(d) {
            return selectedNode && d.id == selectedNode.id ? "#f00" : "#aaa";
        }

        function linkColor(d) {
            if (!paths || paths.length == 0) {
                return "#666";
            }

            var path = paths[currentPath];
            if (path) {
                for (var i = 0, n = path.length; i < n; i++) {
                    var link = path[i];
                    if ((link.src == d.source.id || link.dst == d.source.id) &&
                            (link.dst == d.target.id || link.src == d.target.id)) {
                        return "#f00";
                    }
                }
            }
            return "#666";
        }

        function linkKey(link) {
            return link.source.id + "-" + link.target.id;

        };

        function toggleNode(node) {
            pathRequested = false;
            return selectedNode && selectedNode != node ? selectedNode : null;

        };

        function refreshPaths() {
            d3.selectAll("line").attr("stroke", linkColor);
        }

        function fetchPaths() {
            if (!pathRequested && sourceNode && targetNode) {
                pathRequested = true;
                d3.json("rs/topology/paths/" + sourceNode.id + "/" + targetNode.id, function(error, data) {
                    currentPath = 0;
                    paths = data.paths;
                    refreshPaths();
                });
            }
        }

        function resetSelections() {
            selectedNode = null;
            sourceNode = null;
            targetNode = null;
            paths = [];
            currentPath = 0;
            refreshPaths();
            d3.selectAll(".nodeStrokeClass").attr("stroke", strokeColor);
        }

        function nextPath() {
            currentPath = paths && currentPath < paths.length - 1 ? currentPath + 1 : 0
            console.log("Showing path: " + currentPath);
            refreshPaths();
        }

        function dblclick(d) {
            d3.select(this).classed("fixed", d.fixed = false);
        }

        function dragstart(d) {
            d3.select(this).classed("fixed", d.fixed = true);
        }


        function topoGraph() {
            // Add and remove elements on the graph object
            this.addNode = function (vertex, stamp) {
                var node = topo.vertexes[vertex.name];
                if (node) {
                    var oldState = node.online;
                    node.online = vertex.online;
                    node.stamp = stamp;
                    if (oldState != node.online) {
                        update();
                        return true;
                    }
                    return false;
                }
                node = {"id": vertex.name, "group": vertex.group,
                    "online": vertex.online, "stamp": stamp};
                nodes.push(node);
                topo.vertexes[vertex.name] = node;
                update();
                return true;
            };

            this.addLink = function (edge, stamp) {
                var key = edge.source + "-" + edge.target;
                var link = topo.edges[key];
                if (link) {
                    var oldValue = link.value;
                    link.value = edge.value;
                    link.stamp = stamp;
                    if (oldValue != link.value) {
                        update();
                        return true;
                    }
                    return false;
                }
                link = {"source": findNode(edge.source), "target": findNode(edge.target),
                        "value": edge.value, "stamp": stamp};
                links.push(link);
                topo.edges[key] = link;
                update();
                return true;
            };

            this.prune = function (stamp) {
                var linksChanged = pruneArray(links, stamp, topo.edges, linkKey);
                var nodesChanged = pruneArray(nodes, stamp, topo.vertexes,
                        function(node) { return node.id; });
                if (linksChanged || nodesChanged) {
                    update();
                    return true;
                }
                return false;
            };

            var pruneArray = function(array, stamp, map, key) {
                var changed = false;
                for (var i = 0; i < array.length; i++) {
                    if (array[i].stamp < stamp) {
                        changed = true;
                        map[key(array[i])] = null;
                        array.splice(i, 1);
                        i--;
                    }
                }
                return changed;
            };

            var findNode = function (id) {
                for (var i in nodes) {
                    if (nodes[i]["id"] === id) return nodes[i];
                }
            };

            var force = d3.layout.force();

            var drag = force.drag()
                    .on("dragstart", dragstart);

            var nodes = force.nodes(),
                    links = force.links();

            var vis = d3.select("body")
                    .append("svg:svg")
                    .attr("width", w)
                    .attr("height", h)
                    .attr("id", "svg")
                    .attr("pointer-events", "all")
                    .attr("viewBox", "0 0 " + w + " " + h)
                    .attr("perserveAspectRatio", "xMinYMid")
                    .append('svg:g');

            d3.select("body")
                    .on("keydown", function(d) {
                        console.log(d3.event.keyCode);
                        if (d3.event.keyCode == 27) {
                            resetSelections();
                        } else if (d3.event.keyCode == 83) {
                            sourceNode = toggleNode(sourceNode);
                        } else if (d3.event.keyCode == 68) {
                            targetNode = toggleNode(targetNode);
                        } else if (d3.event.keyCode == 65) {
                            var aux = sourceNode;
                            sourceNode = targetNode;
                            targetNode = aux;
                        } else if (d3.event.keyCode == 70) {
                            nextPath();
                        }

                        d3.selectAll(".nodeStrokeClass").attr("fill", fillColor);
                        fetchPaths();
                    });


            var update = function () {
                var link = vis.selectAll("line")
                        .data(links, linkKey);

                link.enter().append("line")
                        .attr("id", linkKey)
                        .attr("class", "link")
                        .attr("stroke-width", function (d) { return d.value; })
                        .attr("stroke", linkColor);
                link.append("title").text(function (d) { return d.id; });
                link.exit().remove();

                var node = vis.selectAll("g.node")
                        .data(nodes, function (d) { return d.id; })
                        .on("click", function(d) {
                            selectedNode = d;
                            d3.selectAll(".nodeStrokeClass").attr("stroke", strokeColor);
                        });

                var nodeEnter = node.enter().append("g")
                        .attr("class", "node")
                        .on("dblclick", dblclick)
                        .call(force.drag);

                nodeEnter.append("svg:circle")
                        .attr("r", function(d) { return 28 / 2; })
                        .attr("id", function (d) { return "n-" + d.id.replace(/[.:]/g, ""); })
                        .attr("class", "nodeStrokeClass")
                        .attr("fill", fillColor)
                        .attr("stroke", strokeColor);

                nodeEnter.append("image")
                        .attr("xlink:href", function(d) { return d.group == 2 ? "images/switch.png" : "images/server.png"; })
                        .attr("x", -12)
                        .attr("y", -12)
                        .attr("width", 24)
                        .attr("height", 24);

                nodeEnter.append("svg:text")
                        .attr("class", "textClass")
                        .attr("x", 20)
                        .attr("y", ".31em")
                        .text(function (d) { return d.id; });

                node.exit().remove();

                d3.selectAll("nodeStrokeClass").attr("stroke", strokeColor);

                force.on("tick", function () {
                    node.attr("transform", function (d) {
                        return "translate(" + d.x + "," + d.y + ")";
                    });

                    link.attr("x1", function (d) { return d.source.x; })
                            .attr("y1", function (d) { return d.source.y; })
                            .attr("x2", function (d) { return d.target.x; })
                            .attr("y2", function (d) { return d.target.y; });
                });

                // Restart the force layout.
                force
                        .gravity(0.3)
                        .charge(-15000)
                        .friction(0.1)
                        .linkDistance(function(d) { return d.value * 30; })
                        .linkStrength(function(d) { return d.value * 0.6; })
                        .size([w, h])
                        .start();
            };

            // Make it all go
            update();
        }

        function drawGraph() {
            graph = new topoGraph("#svgdiv");
            bringNodesToFront();
        }

        function bringNodesToFront() {
            $(".nodeStrokeClass").each(function( index ) {
                var gnode = this.parentNode;
                gnode.parentNode.appendChild(gnode);
            });
        }

        function addNodes() {
            d3.select("svg")
                    .remove();
            drawGraph();
        }

        function fetchData() {
            var stamp = new Date().getTime();
                d3.json("rs/topology/graph", function(error, data) {
                var changed = false;
                data.vertexes.forEach(function(vertex) { changed = graph.addNode(vertex, stamp) || changed; });
                data.edges.forEach(function(edge) { changed = graph.addLink(edge, stamp) || changed; });

                changed = graph.prune(stamp) || changed;
                if (changed) {
                    bringNodesToFront();
                    // Update node and links styles
                    d3.selectAll(".nodeStrokeClass").attr("fill", fillColor);
                    d3.selectAll(".line").attr("stroke-width", function (d) { return d.value; })
                }

                setTimeout(fetchData, 1000);
            });
        };

        drawGraph();
        setTimeout(fetchData, 500);

    </script>
</body>
</html>