<!DOCTYPE html>
<!--
  ~ 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.
  -->
<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, "label": vertex.label,
                    "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();
                        } else if (d3.event.keyCode == 67 && selectedNode) {
                            selectedNode.fixed = !selectedNode.fixed;
                        }

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

                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>