/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you 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.
*/
/**
 * @module QDR
 */
var QDR = (function (QDR) {


	QDR.module.controller('QDR.TopologyFormController', function ($scope, QDRService) {

		$scope.attributes = []
        var nameTemplate = '<div title="{{row.entity.description}}" class="ngCellText"><span>{{row.entity.attributeName}}</span></div>';
        var valueTemplate = '<div title="{{row.entity.attributeValue}}" class="ngCellText"><span>{{row.entity.attributeValue}}</span></div>';
        $scope.topoGridOptions = {
            data: 'attributes',
			enableColumnResize: true,
			multiSelect: false,
            columnDefs: [
            {
                field: 'attributeName',
                displayName: 'Attribute',
                cellTemplate: nameTemplate
            },
            {
                field: 'attributeValue',
                displayName: 'Value',
				cellTemplate: valueTemplate
            }
            ]
        };
		$scope.form = ''
		$scope.$on('showEntityForm', function (event, args) {
			var attributes = args.attributes;
			var entityTypes = QDRService.schema.entityTypes[args.entity].attributes;
			attributes.forEach( function (attr) {
				if (entityTypes[attr.attributeName] && entityTypes[attr.attributeName].description)
					attr.description = entityTypes[attr.attributeName].description
			})
			$scope.attributes = attributes;
			$scope.form = args.entity;
		})
		$scope.$on('showAddForm', function (event) {
			$scope.form = 'add';
		})
	})


  /**
   * @method TopologyController
   *
   * Controller that handles the QDR topology page
   */
    QDR.module.controller("QDR.TopologyController", ['$scope', '$rootScope', 'QDRService', '$location', '$timeout', '$dialog',
    function($scope, $rootScope, QDRService, $location, $timeout, $dialog) {

        $scope.multiData = []
        $scope.selectedClient = [];
        $scope.quiesceState = {}
        var dontHide = false;
		$scope.quiesceConnection = function (row) {
			var entity = row.entity;
			var state = $scope.quiesceState[entity.connectionId].state;
			if (state === 'enabled') {
				// start quiescing all links
				$scope.quiesceState[entity.connectionId].state = 'quiescing';
			} else if (state === 'quiesced') {
				// start reviving all links
				$scope.quiesceState[entity.connectionId].state = 'reviving';
			}
			$scope.multiDetails.updateState(entity);
			dontHide = true;
			$scope.multiDetails.selectRow(row.rowIndex, true);
			$scope.multiDetails.showLinksList(row)
		}
		$scope.quiesceDisabled = function (row) {
			return $scope.quiesceState[row.entity.connectionId].buttonDisabled;
		}
		$scope.quiesceText = function (row) {
			return $scope.quiesceState[row.entity.connectionId].buttonText;
		}
		$scope.quiesceClass = function (row) {
			var stateClassMap = {
				enabled: 'btn-primary',
				quiescing: 'btn-warning',
				reviving: 'btn-warning',
				quiesced: 'btn-danger'
			}
			return stateClassMap[$scope.quiesceState[row.entity.connectionId].state];
		}
        $scope.multiDetails = {
            data: 'multiData',
			selectedItems: $scope.selectedClient,
			multiSelect: false,
			afterSelectionChange: function (obj) {
				if (obj.selected && obj.orig) {
					var detailsDiv = d3.select('#link_details')
					var isVis = detailsDiv.style('display') === 'block';
					if (!dontHide && isVis && $scope.connectionId === obj.entity.connectionId) {
						hideLinkDetails();
						return;
					}
					dontHide = false;
					$scope.multiDetails.showLinksList(obj)
				}
			},
			showLinksList: function (obj) {
				$scope.linkData = obj.entity.linkData;
				$scope.connectionId = obj.entity.connectionId;
				var visibleLen = Math.min(obj.entity.linkData.length, 10)
				var left = parseInt(d3.select('#multiple_details').style("left"))
				var detailsDiv = d3.select('#link_details')
	            detailsDiv
	                .style({
	                    display: 'block',
	                    opacity: 1,
	                    left: (left + 20) + "px",
	                    top:  (mouseY + 20 + $(document).scrollTop()) + "px",
	                    height: (visibleLen + 1) * 30 + "px", // +1 for the header row
	                    'overflow-y': obj.entity.linkData > 10 ? 'scroll' : 'hidden'})
			},
			updateState: function (entity) {
				var state = $scope.quiesceState[entity.connectionId].state

				// count enabled and disabled links for this connection
				var enabled = 0, disabled = 0;
				entity.linkData.forEach ( function (link) {
					if (link.adminStatus === 'enabled')
						++enabled;
					if (link.adminStatus === 'disabled')
						++disabled;
				})

				var linkCount = entity.linkData.length;
				// if state is quiescing and any links are enabled, button should say 'Quiescing' and be disabled
				if (state === 'quiescing' && (enabled > 0)) {
					$scope.quiesceState[entity.connectionId].buttonText = 'Quiescing';
					$scope.quiesceState[entity.connectionId].buttonDisabled = true;
				} else
				// if state is enabled and all links are disabled, button should say Revive and be enabled. set state to quisced
				// if state is quiescing and all links are disabled, button should say 'Revive' and be enabled. set state to quiesced
				if ((state === 'quiescing' || state === 'enabled') && (disabled === linkCount)) {
					$scope.quiesceState[entity.connectionId].buttonText = 'Revive';
					$scope.quiesceState[entity.connectionId].buttonDisabled = false;
					$scope.quiesceState[entity.connectionId].state = 'quiesced'
				} else
				// if state is reviving and any links are disabled, button should say 'Reviving' and be disabled
				if (state === 'reviving' && (disabled > 0)) {
					$scope.quiesceState[entity.connectionId].buttonText = 'Reviving';
					$scope.quiesceState[entity.connectionId].buttonDisabled = true;
				} else
				// if state is reviving or quiesced and all links are enabled, button should say 'Quiesce' and be enabled. set state to enabled
				if ((state === 'reviving' || state === 'quiesced') && (enabled === linkCount)) {
					$scope.quiesceState[entity.connectionId].buttonText = 'Quiesce';
					$scope.quiesceState[entity.connectionId].buttonDisabled = false;
					$scope.quiesceState[entity.connectionId].state = 'enabled'
				}
			},
            columnDefs: [
            {
                field: 'host',
                cellTemplate: "titleCellTemplate.html",
				headerCellTemplate: 'titleHeaderCellTemplate.html',
                displayName: 'Connection host'
            },
            {
                field: 'user',
                cellTemplate: "titleCellTemplate.html",
				headerCellTemplate: 'titleHeaderCellTemplate.html',
                displayName: 'User'
            },
			{
				field: 'properties',
                cellTemplate: "titleCellTemplate.html",
				headerCellTemplate: 'titleHeaderCellTemplate.html',
				displayName: 'Properties'
			}/*,
			{
				cellClass: 'gridCellButton',
				cellTemplate: '<button title="{{quiesceText(row)}} the links" type="button" ng-class="quiesceClass(row)" class="btn" ng-click="$event.stopPropagation();quiesceConnection(row)" ng-disabled="quiesceDisabled(row)">{{quiesceText(row)}}</button>'
			}*/
            ]
        };
		$scope.linkData = [];
		$scope.quiesceLinkClass = function (row) {
			var stateClassMap = {
				enabled: 'btn-primary',
				disabled: 'btn-danger'
			}
			return stateClassMap[row.entity.adminStatus]
			//return stateClassMap[$scope.quiesceState[row.entity.connectionId].linkStates[row.entity.identity]];
		}
		$scope.quiesceLink = function (row) {
			var state = row.entity.adminStatus === 'enabled' ? 'disabled' : 'enabled';
			$scope.quiesceState[row.entity.connectionId].linkStates[row.entity.identity] = state;
		}
		$scope.quiesceLinkDisabled = function (row) {
			return false;
		}
		$scope.quiesceLinkText = function (row) {
			return row.entity.adminStatus === 'disabled' ? "Revive" : "Quiesce";
		}
		$scope.linkDetails = {
			data: 'linkData',
            columnDefs: [
			{
				field: 'adminStatus',
                cellTemplate: "titleCellTemplate.html",
				headerCellTemplate: 'titleHeaderCellTemplate.html',
				displayName: 'Admin stat'
			},
			{
				field: 'dir',
                cellTemplate: "titleCellTemplate.html",
				headerCellTemplate: 'titleHeaderCellTemplate.html',
				displayName: 'dir'
			},
			{
				field: 'owningAddr',
                cellTemplate: "titleCellTemplate.html",
				headerCellTemplate: 'titleHeaderCellTemplate.html',
				displayName: 'Address'
			},
			{
				field: 'deliveryCount',
				displayName: 'Delivered',
				headerCellTemplate: 'titleHeaderCellTemplate.html',
				cellClass: 'grid-values'

			},
			{
				field: 'undeliveredCount',
				displayName: 'Undelivered',
				headerCellTemplate: 'titleHeaderCellTemplate.html',
				cellClass: 'grid-values'
			},
			{
				field: 'unsettledCount',
				displayName: 'Unsettled',
				headerCellTemplate: 'titleHeaderCellTemplate.html',
				cellClass: 'grid-values'
			}/*,

			{
				cellClass: 'gridCellButton',
				cellTemplate: '<button title="{{quiesceLinkText(row)}} this link" type="button" ng-class="quiesceLinkClass(row)" class="btn" ng-click="quiesceLink(row)" ng-disabled="quiesceLinkDisabled(row)">{{quiesceLinkText(row)}}</button>'
			}*/
			]
		}

		if (!QDRService.connected) {
			// we are not connected. we probably got here from a bookmark or manual page reload
			QDRService.redirectWhenConnected("topology");
			return;
		}
		// we are currently connected. setup a handler to get notified if we are ever disconnected
		QDRService.addDisconnectAction( function () {
			QDRService.redirectWhenConnected("topology");
			$scope.$apply();
		})

		QDR.log.debug("started QDR.TopologyController with urlPrefix: " + $location.absUrl());
		var urlPrefix = $location.absUrl();

		$scope.addingNode = {
			step: 0,
			hasLink: false,
			trigger: ''
		};

        $scope.cancel = function () {
            $scope.addingNode.step = 0;
        }
		$scope.editNewRouter = function () {
			$scope.addingNode.trigger = 'editNode';
		}

		var NewRouterName = "__NEW__";
	    // mouse event vars
	    var selected_node = null,
	        selected_link = null,
	        mousedown_link = null,
	        mousedown_node = null,
	        mouseup_node = null,
	        initial_mouse_down_position = null;

        $scope.schema = "Not connected";

	    $scope.modes = [
	    	{title: 'Topology view', name: 'Diagram', right: false},
	    	/* {title: 'Add a new router node', name: 'Add Router', right: true} */
	    	];
		$scope.mode = "Diagram";
		$scope.contextNode = null; // node that is associated with the current context menu

		$scope.isModeActive = function (name) {
			if ((name == 'Add Router' || name == 'Diagram') && $scope.addingNode.step > 0)
				return true;
			return ($scope.mode == name);
		}
		$scope.selectMode = function (name) {
			if (name == "Add Router") {
				name = 'Diagram';
				if ($scope.addingNode.step > 0) {
					$scope.addingNode.step = 0;
				} else {
					// start adding node mode
					$scope.addingNode.step = 1;
				}
			} else {
				$scope.addingNode.step = 0;
			}

			$scope.mode = name;
		}
		$scope.$watch(function () {return $scope.addingNode.step}, function (newValue, oldValue) {
			if (newValue == 0 && oldValue != 0) {
				// we are cancelling the add

				// find the New node
				nodes.every(function (n, i) {
					// for the placeholder node, the key will be __internal__
					if (QDRService.nameFromId(n.key) == '__internal__') {
						var newLinks = links.filter(function (e, i) {
							return e.source.id == n.id || e.target.id == n.id;
						})
						// newLinks is an array of links to remove
						newLinks.map(function (e) {
							links.splice(links.indexOf(e), 1);
						})
						// i is the index of the node to remove
						nodes.splice(i, 1);
						force.nodes(nodes).links(links).start();
		                restart(false);
						return false; // stop looping
					}
					return true;
				})
				updateForm(Object.keys(QDRService.topology.nodeInfo())[0], 'router', 0);

			} else if (newValue > 0) {
				// we are starting the add mode
				$scope.$broadcast('showAddForm')

				resetMouseVars();
                selected_node = null;
                selected_link = null;
                // add a new node
                var id = "amqp:/_topo/0/__internal__/$management";
                var x = radiusNormal * 4;
                var y = x;;
                if (newValue > 1) {   // add at current mouse position
                    var offset = jQuery('#topology').offset();
                    x = mouseX - offset.left + $(document).scrollLeft();
                    y = mouseY - offset.top + $(document).scrollTop();;
                }
                NewRouterName = genNewName();
                nodes.push( aNode(id, NewRouterName, "inter-router", undefined, nodes.length, x, y, undefined, true) );
                force.nodes(nodes).links(links).start();
                restart(false);
			}

		})
		$scope.isRight = function (mode) {
			return mode.right;
		}

		// for ng-grid that shows details for multiple consoles/clients
		// generate unique name for router and containerName
		var genNewName = function () {
			var nodeInfo = QDRService.topology.nodeInfo();
			var nameIndex = 1;
			var newName = "R." + nameIndex;

			var names = [];
			for (key in nodeInfo) {
				var node = nodeInfo[key];
				var router = node['.router'];
				var attrNames = router.attributeNames;
				var name = QDRService.valFor(attrNames, router.results[0], 'routerId')
				if (!name)
					name = QDRService.valFor(attrNames, router.results[0], 'name')
				names.push(name);
			}

			while (names.indexOf(newName) >= 0) {
				newName = "R." + nameIndex++;
			}
			return newName;
		}

		$scope.$watch(function () {return $scope.addingNode.trigger}, function (newValue, oldValue) {
			if (newValue == 'editNode') {
				$scope.addingNode.trigger = "";
				editNode();
			}
		})

	    function editNode() {
	        doAddDialog(NewRouterName);
	    };
		$scope.reverseLink = function () {
			if (!mousedown_link)
				return;
			var d = mousedown_link;
			var tmp = d.left;
			d.left = d.right;;
			d.right = tmp;
		    restart(false);
		    tick();
		}
		$scope.removeLink = function () {
			if (!mousedown_link)
				return;
			var d = mousedown_link;
			 links.every( function (l, i) {
				if (l.source.id == d.source.id && l.target.id == d.target.id) {
			        links.splice(i, 1);
					force.links(links).start();
					return false; // exit the 'every' loop
				}
				return true;
			});
		    restart(false);
		    tick();
		}
		$scope.setFixed = function (b) {
			if ($scope.contextNode) {
				$scope.contextNode.fixed = b;
			}
			restart();
		}
		$scope.isFixed = function () {
			if (!$scope.contextNode)
				return false;
			return ($scope.contextNode.fixed & 0b1);
		}

		var mouseX, mouseY;
		// event handlers for popup context menu
		$(document).mousemove(function (e) {
		    mouseX = e.clientX;
		    mouseY = e.clientY;
		});
		$(document).mousemove();
		$(document).click(function (e) {
			$scope.contextNode = null;
            $(".contextMenu").fadeOut(200);
        });


		// set up SVG for D3
	    var width, height;
	    var tpdiv = $('#topology');
	    var colors = {'inter-router': "#EAEAEA", 'normal': "#F0F000", 'on-demand': '#00F000'};
	    var gap = 5;
	    var radii = {'inter-router': 25, 'normal': 15, 'on-demand': 15};
	    var radius = 25;
	    var radiusNormal = 15;
	    width = tpdiv.width() - gap;
	    height = $('#main').height() - $('#topology').position().top - gap;

	    var svg, lsvg;
		var force;
		var animate = false; // should the force graph organize itself when it is displayed
		var path, circle;
		var savedKeys = {};
		var dblckickPos = [0,0];

	    // set up initial nodes and links
	    //  - nodes are known by 'id', not by index in array.
	    //  - selected edges are indicated on the node (as a bold red circle).
	    //  - links are always source < target; edge directions are set by 'left' and 'right'.
		var nodes = [];
		var links = [];

		var aNode = function (id, name, nodeType, nodeInfo, nodeIndex, x, y, resultIndex, fixed, properties) {
			properties = properties || {};
			var routerId;
			if (nodeInfo) {
				var node = nodeInfo[id];
				if (node) {
					var router = node['.router'];
					routerId = QDRService.valFor(router.attributeNames, router.results[0], 'id')
					if (!routerId)
						routerId = QDRService.valFor(router.attributeNames, router.results[0], 'routerId')
				}
			}
			return {   key: id,
				name: name,
				nodeType: nodeType,
				properties: properties,
				routerId: routerId,
				x: x,
				y: y,
				id: nodeIndex,
				resultIndex: resultIndex,
				fixed: fixed,
				cls: name == NewRouterName ? 'temp' : ''
			};
		};


        var initForm = function (attributes, results, entityType, formFields) {
        
            while(formFields.length > 0) {
                // remove all existing attributes
                    formFields.pop();
            }

            for (var i=0; i<attributes.length; ++i) {
                var name = attributes[i];
                var val = results[i];
                var desc = "";
                if (entityType.attributes[name])
                    if (entityType.attributes[name].description)
                        desc = entityType.attributes[name].description;

                formFields.push({'attributeName': name, 'attributeValue': val, 'description': desc});
            }
        }

		// initialize the nodes and links array from the QDRService.topology._nodeInfo object
		var initForceGraph = function () {
            //QDR.log.debug("initForceGraph called");
			nodes = [];
			links = [];

			svg = d3.select('#topology')
				.append('svg')
				.attr("id", "SVG_ID")
				.attr('width', width)
				.attr('height', height)
	            .on("contextmenu", function(d) {
	                if (d3.event.defaultPrevented)
	                    return;
                    d3.event.preventDefault();
					if ($scope.addingNode.step != 0)
						return;
					if (d3.select('#svg_context_menu').style('display') !== 'block')
	                    $(document).click();
                    d3.select('#svg_context_menu')
                      .style('left', (mouseX + $(document).scrollLeft()) + "px")
                      .style('top', (mouseY + $(document).scrollTop()) + "px")
                      .style('display', 'block');
                })
                .on('click', function (d) {
                    removeCrosssection()
                });

                $(document).keyup(function(e) {
                  if (e.keyCode === 27) {
                    removeCrosssection()
                  }
                });

			// the legend
			lsvg = d3.select("#svg_legend")
			 	.append('svg')
				.attr('id', 'svglegend')
			lsvg = lsvg.append('svg:g')
				.attr('transform', 'translate('+(radii['inter-router']+2)+','+(radii['inter-router']+2)+')')
				.selectAll('g');

			// mouse event vars
			selected_node = null;
			selected_link = null;
			mousedown_link = null;
			mousedown_node = null;
			mouseup_node = null;

			// initialize the list of nodes
			var yInit = 10;
			var nodeInfo = QDRService.topology.nodeInfo();
			var nodeCount = Object.keys(nodeInfo).length;
			for (var id in nodeInfo) {
				var name = QDRService.nameFromId(id);
                // if we have any new nodes, animate the force graph to position them
				var position = angular.fromJson(localStorage[name]);
				if (!angular.isDefined(position)) {
				    animate = true;
				    position = {x: width / 4 + ((width / 2)/nodeCount) * nodes.length,
                				y: 200 + yInit,
                				fixed: false};
				}
				if (position.y > height)
					position.y = 200 - yInit;
				nodes.push( aNode(id, name, "inter-router", nodeInfo, nodes.length, position.x, position.y, undefined, position.fixed) );
				yInit *= -1;
				//QDR.log.debug("adding node " + nodes.length-1);
			}

			// initialize the list of links
			var source = 0;
			var client = 1;
			for (var id in nodeInfo) {
				var onode = nodeInfo[id];
				var conns = onode['.connection'].results;
				var attrs = onode['.connection'].attributeNames;
				var parent = getNodeIndex(QDRService.nameFromId(id));
				//QDR.log.debug("external client parent is " + parent);
				var normalsParent = {console: undefined, client: undefined}; // 1st normal node for this parent

				for (var j = 0; j < conns.length; j++) {
                    var role = QDRService.valFor(attrs, conns[j], "role");
                    var properties = QDRService.valFor(attrs, conns[j], "properties") || {};
                    var dir = QDRService.valFor(attrs, conns[j], "dir");
					if (role == "inter-router") {
						var connId = QDRService.valFor(attrs, conns[j], "container");
						var target = getContainerIndex(connId);
						if (target >= 0)
							getLink(source, target, dir);
					} else if (role == "normal" || role == "on-demand") {
						// not a router, but an external client
						//QDR.log.debug("found an external client for " + id);
						var name = QDRService.nameFromId(id) + "." + client;
						//QDR.log.debug("external client name is  " + name + " and the role is " + role);

                        // if we have any new clients, animate the force graph to position them
                        var position = angular.fromJson(localStorage[name]);
                        if (!angular.isDefined(position)) {
                            animate = true;
                            position = {x: nodes[parent].x + 40 + Math.sin(Math.PI/2 * client),
                                        y: nodes[parent].y + 40 + Math.cos(Math.PI/2 * client),
                                        fixed: false};
                        }
						if (position.y > height)
							position.y = nodes[parent].y + 40 + Math.cos(Math.PI/2 * client)
						var node = aNode(id, name, role, nodeInfo, nodes.length, position.x, position.y, j, position.fixed, properties)
						var nodeType = QDRService.isAConsole(properties, QDRService.valFor(attrs, conns[j], "identity"), role, node.key)

						if (role === 'normal') {
							node.user = QDRService.valFor(attrs, conns[j], "user")
							node.isEncrypted = QDRService.valFor(attrs, conns[j], "isEncrypted")
							node.host = QDRService.valFor(attrs, conns[j], "host")
							node.connectionId = QDRService.valFor(attrs, conns[j], "identity")

							if (!normalsParent[nodeType]) {
								normalsParent[nodeType] = node;
								nodes.push(	node );
								node.normals = [node];
								// now add a link
								getLink(parent, nodes.length-1, dir);
								client++;
							} else {
								normalsParent[nodeType].normals.push(node)
							}
						} else {
							nodes.push( node)
							// now add a link
							getLink(parent, nodes.length-1, dir);
							client++;
						}
					}
				}
				source++;
			}

            $scope.schema = QDRService.schema;
			// init D3 force layout
			force = d3.layout.force()
				.nodes(nodes)
				.links(links)
				.size([width, height])
				.linkDistance(function(d) { return d.target.nodeType === 'inter-router' ? 150 : 65 })
				.charge(-1800)
				.friction(.10)
				.gravity(0.0001)
				.on('tick', tick)
				.start()

			svg.append("svg:defs").selectAll('marker')
				.data(["end-arrow", "end-arrow-selected"])      // Different link/path types can be defined here
				.enter().append("svg:marker")    // This section adds in the arrows
				.attr("id", String)
				.attr("viewBox", "0 -5 10 10")
				//.attr("refX", 25)
				.attr("markerWidth", 4)
				.attr("markerHeight", 4)
				.attr("orient", "auto")
				.append("svg:path")
				.attr('d', 'M 0 -5 L 10 0 L 0 5 z')

			svg.append("svg:defs").selectAll('marker')
				.data(["start-arrow", "start-arrow-selected"])      // Different link/path types can be defined here
				.enter().append("svg:marker")    // This section adds in the arrows
				.attr("id", String)
				.attr("viewBox", "0 -5 10 10")
				.attr("refX", 5)
				.attr("markerWidth", 4)
				.attr("markerHeight", 4)
				.attr("orient", "auto")
				.append("svg:path")
				.attr('d', 'M 10 -5 L 0 0 L 10 5 z');

			// handles to link and node element groups
			path = svg.append('svg:g').selectAll('path'),
			circle = svg.append('svg:g').selectAll('g');
            
			force.on('end', function() {
				//QDR.log.debug("force end called");
				circle
					.attr('cx', function(d) {
						localStorage[d.name] = angular.toJson({x: d.x, y: d.y, fixed: d.fixed});
						return d.x; });
			});

			// app starts here
			restart(false);
    	    force.start();
			setTimeout(function () {
	    	    updateForm(Object.keys(QDRService.topology.nodeInfo())[0], 'router', 0);
			}, 10)

		}

		function updateForm (key, entity, resultIndex) {
			var nodeInfo = QDRService.topology.nodeInfo();
			var onode = nodeInfo[key]
			if (onode) {
				var nodeResults = onode['.' + entity].results[resultIndex]
				var nodeAttributes = onode['.' + entity].attributeNames
				var attributes = nodeResults.map( function (row, i) {
					return {
						attributeName: nodeAttributes[i],
						attributeValue: row
					}
				})
				// sort by attributeName
				attributes.sort( function (a, b) { return a.attributeName.localeCompare(b.attributeName) })

				// move the Name first
				var nameIndex = attributes.findIndex ( function (attr) {
					return attr.attributeName === 'name'
				})
				if (nameIndex >= 0)
					attributes.splice(0, 0, attributes.splice(nameIndex, 1)[0]);
				// get the list of ports this router is listening on
				if (entity === 'router') {
					var listeners = onode['.listener'].results;
					var listenerAttributes = onode['.listener'].attributeNames;
					var normals = listeners.filter ( function (listener) {
						return QDRService.valFor( listenerAttributes, listener, 'role') === 'normal';
					})
					var ports = []
					normals.forEach (function (normalListener) {
						ports.push(QDRService.valFor( listenerAttributes, normalListener, 'port'))
					})
					// add as 2nd row
					if (ports.length)
						attributes.splice(1, 0, {attributeName: 'Listening on', attributeValue: ports, description: 'The port on which this router is listening for connections'});
				}

				$scope.$broadcast('showEntityForm', {entity: entity, attributes: attributes})
			}
			if (!$scope.$$phase) $scope.$apply()
		}

        function getContainerIndex(_id) {
            var nodeIndex = 0;
            var nodeInfo = QDRService.topology.nodeInfo();
            for (var id in nodeInfo) {
                var node = nodeInfo[id]['.router'];
                // there should be only one router entity for each node, so using results[0] should be fine
                if (QDRService.valFor( node.attributeNames, node.results[0], "id") === _id)
                    return nodeIndex;
                if (QDRService.valFor( node.attributeNames, node.results[0], "routerId") === _id)
                    return nodeIndex;
                nodeIndex++
            }
			// there was no router.id that matched, check deprecated router.routerId
            nodeIndex = 0;
            for (var id in nodeInfo) {
                var node = nodeInfo[id]['.container'];
				if (node) {
					if (QDRService.valFor ( node.attributeNames, node.results[0], "containerName") === _id)
						return nodeIndex;
				}
				nodeIndex++
			}
            //QDR.log.warn("unable to find containerIndex for " + _id);
            return -1;
        }

        function getNodeIndex (_id) {
            var nodeIndex = 0;
            var nodeInfo = QDRService.topology.nodeInfo();
            for (var id in nodeInfo) {
                if (QDRService.nameFromId(id) == _id) return nodeIndex;
                nodeIndex++
            }
            QDR.log.warn("unable to find nodeIndex for " + _id);
            return -1;
        }

        function getLink (_source, _target, dir, cls) {
            for (var i=0; i < links.length; i++) {
                var s = links[i].source, t = links[i].target;
                if (typeof links[i].source == "object") {
                    s = s.id;
                    t = t.id;
				}
                if (s == _source && t == _target) {
                    return i;
                }
				// same link, just reversed
                if (s == _target && t == _source) {
                    return -i;
				}
            }

            //QDR.log.debug("creating new link (" + (links.length) + ") between " + nodes[_source].name + " and " + nodes[_target].name);
            var link = {
                source: _source,
                target: _target,
                left: dir != "out",
                right: dir == "out",
                cls: cls
            };
            return links.push(link) - 1;
        }


	    function resetMouseVars() {
	        mousedown_node = null;
	        mouseup_node = null;
	        mousedown_link = null;
	    }

	    // update force layout (called automatically each iteration)
	    function tick() {
	        // draw directed edges with proper padding from node centers
	        path.attr('d', function (d) {
				//QDR.log.debug("in tick for d");
				//console.dump(d);
				var dtx = Math.max(0, Math.min(width, d.target.x)),
				    dty = Math.max(0, Math.min(height, d.target.y)),
				    dsx = Math.max(0, Math.min(width, d.source.x)),
					dsy = Math.max(0, Math.min(height, d.source.y));

	            var deltaX = dtx - dsx,
	                deltaY = dty - dsy,
	                dist = Math.sqrt(deltaX * deltaX + deltaY * deltaY),
	                normX = deltaX / dist,
	                normY = deltaY / dist;
	                var sourcePadding, targetPadding;
	                if (d.target.nodeType == "inter-router") {
						//                       right arrow  left line start
						sourcePadding = d.left ? radius + 8  : radius;
						//                      left arrow      right line start
						targetPadding = d.right ? radius + 16 : radius;
	                } else {
						sourcePadding = d.left ? radiusNormal + 18  : radiusNormal;
						targetPadding = d.right ? radiusNormal + 16 : radiusNormal;
	                }
	                var sourceX = dsx + (sourcePadding * normX),
	                sourceY = dsy + (sourcePadding * normY),
	                targetX = dtx - (targetPadding * normX),
	                targetY = dty - (targetPadding * normY);
					sourceX = Math.max(0, Math.min(width, sourceX))
					sourceY = Math.max(0, Math.min(width, sourceY))
					targetX = Math.max(0, Math.min(width, targetX))
					targetY = Math.max(0, Math.min(width, targetY))

	            return 'M' + sourceX + ',' + sourceY + 'L' + targetX + ',' + targetY;
	        });

	        circle.attr('transform', function (d) {
	            d.x = Math.max(d.x, radiusNormal * 2);
	            d.y = Math.max(d.y, radiusNormal * 2);
				d.x = Math.max(0, Math.min(width, d.x))
				d.y = Math.max(0, Math.min(height, d.y))
	            return 'translate(' + d.x + ',' + d.y + ')';
	        });
	        if (!animate) {
	            animate = true;
	            force.stop();
	        }
	    }

        // highlight the paths between the selected node and the hovered node
        function findNextHopNode(from, d) {
            // d is the node that the mouse is over
            // from is the selected_node ....
            if (!from)
                return null;

            if (from == d)
                return selected_node;

            //QDR.log.debug("finding nextHop from: " + from.name + " to " + d.name);
            var sInfo = QDRService.topology.nodeInfo()[from.key];

            if (!sInfo) {
                QDR.log.warn("unable to find topology node info for " + from.key);
                return null;
            }

            // find the hovered name in the selected name's .router.node results
            if (!sInfo['.router.node'])
                return null;
            var aAr = sInfo['.router.node'].attributeNames;
            var vAr = sInfo['.router.node'].results;
            for (var hIdx=0; hIdx<vAr.length; ++hIdx) {
                var addrT = QDRService.valFor(aAr, vAr[hIdx], "id" );
                if (addrT == d.name) {
                    //QDR.log.debug("found " + d.name + " at " + hIdx);
                    var nextHop = QDRService.valFor(aAr, vAr[hIdx], "nextHop");
                    //QDR.log.debug("nextHop was " + nextHop);
                    return (nextHop == null) ? nodeFor(addrT) : nodeFor(nextHop);
                }
            }
            return null;
        }

        function nodeFor(name) {
            for (var i=0; i<nodes.length; ++i) {
                if (nodes[i].name == name)
                    return nodes[i];
            }
            return null;
        }

        function linkFor(source, target) {
            for (var i=0; i<links.length; ++i) {
                if ((links[i].source == source) && (links[i].target == target))
                    return links[i];
                if ((links[i].source == target) && (links[i].target == source))
                    return links[i];
            }
            // the selected node was a client/broker
            //QDR.log.debug("failed to find a link between ");
            //console.dump(source);
            //QDR.log.debug(" and ");
            //console.dump(target);
            return null;
        }

		function clearPopups() {
            d3.select("#crosssection").style("display", "none");
			$('.hastip').empty();
            d3.select("#multiple_details").style("display", "none")
            d3.select("#link_details").style("display", "none")
			d3.select('#node_context_menu').style('display', 'none');

		}
		function removeCrosssection() {
			setTimeout(function () {
				d3.select("[id^=tooltipsy]").remove()
				$('.hastip').empty();
			}, 1010);
			d3.select("#crosssection svg g").transition()
                .duration(1000)
				.attr("transform", "translate("+(dblckickPos[0]-140) + "," + (dblckickPos[1]-100) + ") scale(0)")
                .style("opacity", 0)
                .each("end", function (d) {
                    d3.select("#crosssection svg").remove();
                    d3.select("#crosssection").style("display","none");
                });
            d3.select("#multiple_details").transition()
                .duration(500)
                .style("opacity", 0)
                .each("end", function (d) {
                    d3.select("#multiple_details").style("display", "none")
                    stopUpdateConnectionsGrid();
                })
			hideLinkDetails();
		}
		function hideLinkDetails() {
            d3.select("#link_details").transition()
                .duration(500)
                .style("opacity", 0)
                .each("end", function (d) {
                    d3.select("#link_details").style("display", "none")
                })
		}

	    // takes the nodes and links array of objects and adds svg elements for everything that hasn't already
	    // been added
	    function restart(start) {
	        circle.call(force.drag);

	        // path (link) group
	        path = path.data(links);

			// update existing links
  			path.classed('selected', function(d) { return d === selected_link; })
  			    .classed('highlighted', function(d) { return d.highlighted; } )
  			    .classed('temp', function(d) { return d.cls == 'temp'; } )
                .attr('marker-start', function(d) {
                    var sel = d===selected_link ? '-selected' : '';
                    return d.left ? 'url('+urlPrefix+'#start-arrow' + sel + ')' : ''; })
                .attr('marker-end', function(d) {
                    var sel = d===selected_link ? '-selected' : '';
                    return d.right ? 'url('+urlPrefix+'#end-arrow' + sel +')' : ''; })


			// add new links. if links[] is longer than the existing paths, add a new path for each new element
			path.enter().append('svg:path')
				.attr('class', 'link')
                .attr('marker-start', function(d) {
                        var sel = d===selected_link ? '-selected' : '';
						return d.left ? 'url('+urlPrefix+'#start-arrow' + sel + ')' : ''; })
                .attr('marker-end', function(d) {
					var sel = d===selected_link ? '-selected' : '';
                    return d.right ? 'url('+urlPrefix+'#end-arrow' + sel + ')' : ''; })
  			    .classed('temp', function(d) { return d.cls == 'temp'; } )
	            .on('mouseover', function (d) {
				  if($scope.addingNode.step > 0) {
				    if (d.cls == 'temp') {
				        d3.select(this).classed('over', true);
				    }
				    return;
				  }
			        //QDR.log.debug("showing connections form");
					var resultIndex = 0; // the connection to use
                    var left = d.left ? d.target : d.source;
					// right is the node that the arrow points to, left is the other node
					var right = d.left ? d.source : d.target;
					var onode = QDRService.topology.nodeInfo()[left.key];
					// loop through all the connections for left, and find the one for right
					if (!onode || !onode['.connection'])
						return;
                    // update the info dialog for the link the mouse is over
                    if (!selected_node && !selected_link) {
                        for (resultIndex=0; resultIndex < onode['.connection'].results.length; ++resultIndex) {
                            var conn = onode['.connection'].results[resultIndex];
                            /// find the connection whose container is the right's name
                            var name = QDRService.valFor(onode['.connection'].attributeNames, conn, "container");
                            if (name == right.routerId) {
                                break;
                            }
                        }
                        // did not find connection. this is a connection to a non-interrouter node
                        if (resultIndex === onode['.connection'].results.length) {
                            // use the non-interrouter node's connection info
                            left = d.target;
                            resultIndex = left.resultIndex;
                        }
						if (resultIndex)
                            updateForm(left.key, 'connection', resultIndex);
                    }

					mousedown_link = d;
					selected_link = mousedown_link;
					restart();
				})
	            .on('mouseout', function (d) {
				  if($scope.addingNode.step > 0) {
				    if (d.cls == 'temp') {
				        d3.select(this).classed('over', false);
				    }
				    return;
				  }
			        //QDR.log.debug("showing connections form");
					selected_link = null;
					restart();
				})
	            .on("contextmenu", function(d) {
	                $(document).click();
                    d3.event.preventDefault();
	                if (d.cls !== "temp")
	                    return;

					mousedown_link = d;
                    d3.select('#link_context_menu')
                      .style('left', (mouseX + $(document).scrollLeft()) + "px")
                      .style('top', (mouseY + $(document).scrollTop()) + "px")
                      .style('display', 'block');
                })
                .on("click", function (d) {
                    dblckickPos = d3.mouse(this);
                    QDR.log.debug("dblckickPos is [" + dblckickPos[0] + ", " + dblckickPos[1] + "]")
                    d3.event.stopPropagation();
                    clearPopups();
                    var diameter = 400;
                    var format = d3.format(",d");
                    var pack = d3.layout.pack()
                        .size([diameter - 4, diameter - 4])
                        .padding(-10)
                        .value(function(d) { return d.size; });

                    d3.select("#crosssection svg").remove();
                    var svg = d3.select("#crosssection").append("svg")
                        .attr("width", diameter)
                        .attr("height", diameter)
                    var svgg = svg.append("g")
                        .attr("transform", "translate(2,2)");

					var root = {
						name: "links between " + d.source.name + " and " + d.target.name,
						children: []
					}
					var nodeInfo = QDRService.topology.nodeInfo();
					var connections = nodeInfo[d.source.key]['.connection'];
					var containerIndex = connections.attributeNames.indexOf('container');
					connections.results.some ( function (connection) {
                        if (connection[containerIndex] == d.target.routerId) {
                            root.attributeNames = connections.attributeNames;
                            root.obj = connection;
                            root.desc = "Connection";
                            return true;    // stop looping after 1 match
                        }
                        return false;
                    })

					// find router.links where link.remoteContainer is d.source.name
					var links = nodeInfo[d.source.key]['.router.link'];
					var identityIndex = connections.attributeNames.indexOf('identity')
					var roleIndex = connections.attributeNames.indexOf('role')
					var connectionIdIndex = links.attributeNames.indexOf('connectionId');
					var linkTypeIndex = links.attributeNames.indexOf('linkType');
					var nameIndex = links.attributeNames.indexOf('name');
					var linkDirIndex = links.attributeNames.indexOf('linkDir');

					if (roleIndex < 0 || identityIndex < 0 || connectionIdIndex < 0
						|| linkTypeIndex < 0 || nameIndex < 0 || linkDirIndex < 0)
						return;
					links.results.forEach ( function (link) {
						if (root.obj && link[connectionIdIndex] == root.obj[identityIndex] && link[linkTypeIndex] == root.obj[roleIndex])
							root.children.push (
								{ name: "(" + link[linkDirIndex] + ") " + link[nameIndex],
								size: 100,
								obj: link,
	                            desc: "Link",
								attributeNames: links.attributeNames
							})
					})
					if (root.children.length == 0)
						return;
	                var node = svgg.datum(root).selectAll(".node")
	                      .data(pack.nodes)
	                    .enter().append("g")
	                      .attr("class", function(d) { return d.children ? "parent node hastip" : "leaf node hastip"; })
	                      .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")" + (!d.children ? "scale(0.9)" : ""); })
	                      .attr("title", function (d) {
	                          var title = "<h4>" + d.desc + "</h4><table class='tiptable'><tbody>";
	                          if (d.attributeNames)
		                            d.attributeNames.forEach( function (n, i) {
		                                title += "<tr><td>" + n + "</td><td>";
		                                title += d.obj[i] != null ? d.obj[i] : '';
		                                title += '</td></tr>';
		                            })
		                      title += "</tbody></table>"
	                          return title
	                      })

	                node.append("circle")
	                      .attr("r", function(d) { return d.r; });

//	                node.filter(function(d) { return !d.children; }).append("text")
	                node.append("text")
	                      .attr("dy", function (d) { return d.children ? "-10em" : ".3em"})
	                      .style("text-anchor", "middle")
	                      .text(function(d) {
	                          return d.name.substring(0, d.r / 3);
	                      });

					$('.hastip').tooltipsy({ alignTo: 'cursor'});
					svgg.attr("transform", "translate("+(dblckickPos[0]-140) + "," + (dblckickPos[1]-100) + ") scale(0.01)")
	                d3.select("#crosssection").style("display","block");

					svgg.transition().attr("transform", "translate(2,2) scale(1)")
                })


	        // remove old links
	        path.exit().remove();


	        // circle (node) group
	        // nodes are known by id
	        circle = circle.data(nodes, function (d) {
	            return d.id;
	        });

	        // update existing nodes visual states
	        circle.selectAll('circle')
	            .classed('selected', function (d) { return (d === selected_node) })
	            .classed('fixed', function (d) { return (d.fixed & 0b1) })

			// add new circle nodes. if nodes[] is longer than the existing paths, add a new path for each new element
	        var g = circle.enter().append('svg:g')
  			    .classed('multiple', function(d) { return (d.normals && d.normals.length > 1)  } )

			var appendCircle = function (g) {
				// add new circles and set their attr/class/behavior
		        return g.append('svg:circle')
		            .attr('class', 'node')
		            .attr('r', function (d) { return radii[d.nodeType] } )
		            .classed('fixed', function (d) {return d.fixed})
	                .classed('temp', function(d) { return QDRService.nameFromId(d.key) == '__internal__'; } )
	                .classed('normal', function(d) { return d.nodeType == 'normal' } )
	                .classed('inter-router', function(d) { return d.nodeType == 'inter-router' } )
	                .classed('on-demand', function(d) { return d.nodeType == 'on-demand' } )
	                .classed('console', function(d) { return QDRService.isConsole(d) } )
	                .classed('artemis', function(d) { return QDRService.isArtemis(d) } )
	                .classed('qpid-cpp', function(d) { return QDRService.isQpid(d) } )
	                .classed('client', function(d) { return d.nodeType === 'normal' && !d.properties.console_identifier } )
			}
			appendCircle(g).on('mouseover', function (d) {
	                if ($scope.addingNode.step > 0) {
		                d3.select(this).attr('transform', 'scale(1.1)');
						return;
	                }
					if (!selected_node) {
                        if (d.nodeType === 'inter-router') {
                            //QDR.log.debug("showing general form");
                            updateForm(d.key, 'router', 0);
                        } else if (d.nodeType === 'normal' || d.nodeType === 'on-demand') {
                            //QDR.log.debug("showing connections form");
                            updateForm(d.key, 'connection', d.resultIndex);
                        }
					}

	                if (d === mousedown_node) 
	                    return;
	                //if (d === selected_node)
	                //    return;
	                // enlarge target node
	                d3.select(this).attr('transform', 'scale(1.1)');
                    // highlight the next-hop route from the selected node to this node
                    mousedown_node = null;

	                if (!selected_node) {
	                    return;
	                }
                    setTimeout(nextHop, 1, selected_node, d);
	            })
	            .on('mouseout', function (d) {
	                // unenlarge target node
	                d3.select(this).attr('transform', '');
                    for (var i=0; i<links.length; ++i) {
                        links[i]['highlighted'] = false;
                    }
                    restart();
	            })
	            .on('mousedown', function (d) {
	                if (d3.event.button !== 0) {   // ignore all but left button
	                    return;
	                }
	                mousedown_node = d;
	                // mouse position relative to svg
	                initial_mouse_down_position = d3.mouse(this.parentElement.parentElement.parentElement).slice();
	            })
	            .on('mouseup', function (d) {
	                if (!mousedown_node)
	                    return;

                    selected_link = null;
	                // unenlarge target node
	                d3.select(this).attr('transform', '');

	                // check for drag
	                mouseup_node = d;
	                var mySvg = this.parentElement.parentElement.parentElement;
                    // if we dragged the node, make it fixed
                    var cur_mouse = d3.mouse(mySvg);
                    if (cur_mouse[0] != initial_mouse_down_position[0] ||
                        cur_mouse[1] != initial_mouse_down_position[1]) {
						console.log("mouse pos changed. making this node fixed")
						d3.select(this).classed("fixed", d.fixed = true);
                        resetMouseVars();
                        return;
	                }

					// we didn't drag, we just clicked on the node
	                if ($scope.addingNode.step > 0) {
                        if (d.nodeType !== 'inter-router')
                            return;
						if (QDRService.nameFromId(d.key) == '__internal__')
							return;

						// add a link from the clicked node to the new node
						getLink(d.id, nodes.length-1, "in", "temp");
						$scope.addingNode.hasLink = true;
						if (!$scope.$$phase) $scope.$apply()
						// add new elements to the svg
						force.links(links).start();
						restart();
						return;

	                }

					// if this node was selected, unselect it
                    if (mousedown_node === selected_node) {
                        selected_node = null;
                    }
                    else {
                        if (d.nodeType !== 'normal' && d.nodeType !== 'on-demand')
                            selected_node = mousedown_node;
                    }
                    for (var i=0; i<links.length; ++i) {
                        links[i]['highlighted'] = false;
                    }
	                mousedown_node = null;
					if (!$scope.$$phase) $scope.$apply()
                    restart(false);

	            })
	            .on("dblclick", function (d) {
	                if (d.fixed) {
						d3.select(this).classed("fixed", d.fixed = false);
						force.start();  // let the nodes move to a new position
	                }
	                if (QDRService.nameFromId(d.key) == '__internal__') {
	                    editNode();
						if (!$scope.$$phase) $scope.$apply()
	                }
	            })
	            .on("contextmenu", function(d) {
	                $(document).click();
                    d3.event.preventDefault();
	                $scope.contextNode = d;
					if (!$scope.$$phase) $scope.$apply()     // we just changed a scope valiable during an async event
                    d3.select('#node_context_menu')
                      .style('left', (mouseX + $(document).scrollLeft()) + "px")
                      .style('top', (mouseY + $(document).scrollTop()) + "px")
                      .style('display', 'block');

                })
                .on("click", function (d) {
                    // clicked on a circle
                    clearPopups();
					if (!d.normals) {
						// circle was a router or a broker
			            if ( QDRService.isArtemis(d) && Core.ConnectionName === 'Artemis' ) {
							$location.path('/jmx/attributes?tab=artemis&con=Artemis')
						}
						return;
					}
                    clickPos = d3.mouse(this);
                    d3.event.stopPropagation();
					startUpdateConnectionsGrid(d);
				})

			var appendContent = function (g) {
		        // show node IDs
		        g.append('svg:text')
		            .attr('x', 0)
		            .attr('y', function (d) {
		                var y = 6;
		                if (QDRService.isArtemis(d))
		                    y = 8;
		                else if (QDRService.isQpid(d))
		                    y = 9;
		                else if (d.nodeType === 'inter-router')
		                    y = 4;
		                return y;})
		            .attr('class', 'id')
   	                .classed('console', function(d) { return QDRService.isConsole(d) } )
	                .classed('normal', function(d) { return d.nodeType === 'normal' } )
	                .classed('on-demand', function(d) { return d.nodeType === 'on-demand' } )
	                .classed('artemis', function(d) { return QDRService.isArtemis(d) } )
	                .classed('qpid-cpp', function(d) { return QDRService.isQpid(d) } )
		            .text(function (d) {
		                if (QDRService.isConsole(d)) {
		                    return '\uf108'; // icon-desktop for this console
		                }
						if (QDRService.isArtemis(d)) {
							return '\ue900'
						}
		                if (QDRService.isQpid(d)) {
		                    return '\ue901';
		                }
						if (d.nodeType === 'normal')
							return '\uf109'; // icon-laptop for clients
		                return d.name.length>7 ? d.name.substr(0,6)+'...' : d.name;
		        });
			}
			appendContent(g)

			var appendTitle = function (g) {
		        g.append("svg:title").text(function (d) {
	                var x = '';
	                if (d.normals && d.normals.length > 1)
	                    x = " x " + d.normals.length;
		            if (QDRService.isConsole(d)) {
	                    return 'Dispatch console' + x
	                }
		            if (d.properties.product == 'qpid-cpp') {
	                    return 'Broker - qpid-cpp' + x
	                }
		            if ( QDRService.isArtemis(d) ) {
	                    return 'Broker - Artemis' + x
	                }
		            return d.nodeType == 'normal' ? 'client' + x : (d.nodeType == 'on-demand' ? 'broker' : 'Router ' + d.name)
		        })
			}
			appendTitle(g);

	        // remove old nodes
	        circle.exit().remove();

			// add subcircles
			svg.selectAll('.subcircle').remove();
			var multiples = svg.selectAll('.multiple')
			multiples.each( function (d) {
				d.normals.forEach( function (n, i) {
					if (i<d.normals.length-1 && i<3) // only show a few shadow circles
						this.insert('svg:circle', ":first-child")
						.attr('class', 'subcircle node')
						.attr('r', 15 - i)
						.attr('transform', "translate("+ 4 * (i+1) +", 0)")
				}, d3.select(this))
			})

			// dynamically create the legend based on which node types are present
			var legendNodes = [];
			legendNodes.push(aNode("Router", "", "inter-router", undefined, 0, 0, 0, 0, false, {}))

			if (!svg.selectAll('circle.console').empty()) {
				legendNodes.push(aNode("Dispatch console", "", "normal", undefined, 1, 0, 0, 0, false, {console_identifier: 'Dispatch console'}))
			}
			if (!svg.selectAll('circle.client').empty()) {
				legendNodes.push(aNode("Client", "", "normal", undefined, 2, 0, 0, 0, false, {}))
			}
			if (!svg.selectAll('circle.qpid-cpp').empty()) {
				legendNodes.push(aNode("Qpid cpp broker", "", "on-demand", undefined, 3, 0, 0, 0, false, {product: 'qpid-cpp'}))
			}
			if (!svg.selectAll('circle.artemis').empty()) {
				legendNodes.push(aNode("Artemis broker", "", "on-demand", undefined, 4, 0, 0, 0, false, {}))
			}
		    lsvg = lsvg.data(legendNodes, function (d) {
	            return d.id;
            });
	        var lg = lsvg.enter().append('svg:g')
				.attr('transform', function (d, i) {
					// 45px between lines and add 10px space after 1st line
					return "translate(0, "+(45*i+(i>0?10:0))+")"
				})
			appendCircle(lg)
			appendContent(lg)
			appendTitle(lg)
			lg.append('svg:text')
				.attr('x', 35)
				.attr('y', 6)
				.attr('class', "label")
				.text(function (d) {return d.key })
			lsvg.exit().remove();
			var svgEl = document.getElementById("svglegend"),
				bb = svgEl.getBBox();
			svgEl.style.height = (bb.y + bb.height) + 'px';
			svgEl.style.width = (bb.x + bb.width) + 'px';

	        if (!mousedown_node || !selected_node)
	            return;

            if (!start)
                return;
	        // set the graph in motion
	        //QDR.log.debug("mousedown_node is " + mousedown_node);
	        force.start();

	    }

		var startUpdateConnectionsGrid = function (d) {
			var extendConnections = function () {
				$scope.multiData = []
				var normals = d.normals;
				// find updated normals for d
		        d3.selectAll('.normal')
                    .each(function(newd) {
                        if (newd.id == d.id && newd.name == d.name) {
                            normals = newd.normals;
                        }
                    });
				if (normals) {
					normals.forEach( function (n) {
						var nodeInfo = QDRService.topology.nodeInfo();
						var links = nodeInfo[n.key]['.router.link'];
						var linkTypeIndex = links.attributeNames.indexOf('linkType');
						var connectionIdIndex = links.attributeNames.indexOf('connectionId');
						n.linkData = [];
						links.results.forEach( function (link) {
							if (link[linkTypeIndex] === 'endpoint' && link[connectionIdIndex] === n.connectionId) {
								var l = {};
								l.owningAddr = QDRService.valFor(links.attributeNames, link, 'owningAddr');
								l.dir = QDRService.valFor(links.attributeNames, link, 'linkDir');
								if (l.owningAddr && l.owningAddr.length > 2)
									if (l.owningAddr[0] === 'M')
										l.owningAddr = l.owningAddr.substr(2)
									else
										l.owningAddr = l.owningAddr.substr(1)

								l.deliveryCount = QDRService.pretty(QDRService.valFor(links.attributeNames, link, 'deliveryCount'));
								l.undeliveredCount = QDRService.pretty(QDRService.valFor(links.attributeNames, link, 'undeliveredCount'));
								l.unsettledCount = QDRService.pretty(QDRService.valFor(links.attributeNames, link, 'unsettledCount'));
								l.adminStatus = QDRService.valFor(links.attributeNames, link, 'adminStatus');
								l.identity = QDRService.valFor(links.attributeNames, link, 'identity')
								l.connectionId = QDRService.valFor(links.attributeNames, link, 'connectionId')

								// TODO: remove this fake quiescing/reviving logic when the routers do the work
								initConnState(n.connectionId)
								if ($scope.quiesceState[n.connectionId].linkStates[l.identity])
									l.adminStatus = $scope.quiesceState[n.connectionId].linkStates[l.identity];
								if ($scope.quiesceState[n.connectionId].state == 'quiescing') {
									if (l.adminStatus === 'enabled') {
										// 25% chance of switching
										var chance = Math.floor(Math.random() * 2);
										if (chance == 1) {
											l.adminStatus = 'disabled';
											$scope.quiesceState[n.connectionId].linkStates[l.identity] = 'disabled';
										}
									}
								}
								if ($scope.quiesceState[n.connectionId].state == 'reviving') {
									if (l.adminStatus === 'disabled') {
										// 25% chance of switching
										var chance = Math.floor(Math.random() * 2);
										if (chance == 1) {
											l.adminStatus = 'enabled';
											$scope.quiesceState[n.connectionId].linkStates[l.identity] = 'enabled';
										}
									}
								}
								QDR.log.debug("pushing link state for " + l.owningAddr + " status: "+ l.adminStatus)


								n.linkData.push(l)
							}
						})
						$scope.multiData.push(n)
						if (n.connectionId == $scope.connectionId)
							$scope.linkData = n.linkData;
						initConnState(n.connectionId)
						$scope.multiDetails.updateState(n)
					})
				}
				$scope.$apply();

	            d3.select('#multiple_details')
	                .style({
	                    height: (normals.length + 1) * 30 + "px",
	                    'overflow-y': normals.length > 10 ? 'scroll' : 'hidden'
					})
			}

	        QDRService.addUpdatedAction("normalsStats", extendConnections)
			extendConnections();
			clearPopups();
			var display = 'block'
			var left = mouseX + $(document).scrollLeft()
			if (d.normals.length === 1) {
				display = 'none'
				left = left - 30;
				mouseY = mouseY - 20
			}
            d3.select('#multiple_details')
                .style({
                    display: display,
                    opacity: 1,
                    left: (mouseX + $(document).scrollLeft()) + "px",
                    top:  (mouseY + $(document).scrollTop()) + "px"})
            if (d.normals.length === 1) {
				// simulate a click on the connection to popup the link details
                $scope.multiDetails.showLinksList( {entity: d} )
            }
		}
		var stopUpdateConnectionsGrid = function () {
	        QDRService.delUpdatedAction("normalsStats");
		}

		var initConnState = function (id) {
			if (!angular.isDefined($scope.quiesceState[id])) {
				$scope.quiesceState[id] = {
					state:          'enabled',
					buttonText:     'Quiesce',
					buttonDisabled: false,
					linkStates:     {}
				}
			}
		}

        function nextHop(thisNode, d) {
            if ((thisNode) && (thisNode != d)) {
                var target = findNextHopNode(thisNode, d);
                //QDR.log.debug("highlight link from node ");
                 //console.dump(nodeFor(selected_node.name));
                 //console.dump(target);
                if (target) {
                    var hlLink = linkFor(nodeFor(thisNode.name), target);
                    //QDR.log.debug("need to highlight");
                    //console.dump(hlLink);
                    if (hlLink)
                        hlLink['highlighted'] = true;
                    else
                        target = null;
                }
                setTimeout(nextHop, 1, target, d);
            }
            restart();
        }


	    function mousedown() {
	        // prevent I-bar on drag
	        //d3.event.preventDefault();

	        // because :active only works in WebKit?
	        svg.classed('active', true);
	    }

        QDRService.addUpdatedAction("topology", function() {
            //QDR.log.debug("Topology controller was notified that the model was updated");
            if (hasChanged()) {
                QDR.log.info("svg graph changed")
                saveChanged();
                // TODO: update graph nodes instead of rebuilding entire graph
                d3.select("#SVG_ID").remove();
                d3.select("#svg_legend svg").remove();
                animate = true;
                initForceGraph();
                //if ($location.path().startsWith("/topology"))
                //    Core.notification('info', "Qpid dispatch router topology changed");

            } else {
                //QDR.log.debug("no changes")
            }
        });

		function hasChanged () {
			// Don't update the underlying topology diagram if we are adding a new node.
			// Once adding is completed, the topology will update automatically if it has changed
			if ($scope.addingNode.step > 0)
				return false;
			var nodeInfo = QDRService.topology.nodeInfo();
			if (Object.keys(nodeInfo).length != Object.keys(savedKeys).length)
				return true;
			for (var key in nodeInfo) {
                // if this node isn't in the saved node list
                if (!savedKeys.hasOwnProperty(key))
                    return true;
                // if the number of connections for this node chaanged
                if (nodeInfo[key]['.connection'].results.length != savedKeys[key]) {
					/*
					QDR.log.debug("number of connections changed for " + key);
					QDR.log.debug("QDRService.topology._nodeInfo[key]['.connection'].results.length");
					console.dump(QDRService.topology._nodeInfo[key]['.connection'].results.length);
					QDR.log.debug("savedKeys[key]");
					console.dump(savedKeys[key]);
					*/
                    return true;
                }
			}
			return false;
		};
		function saveChanged () {
            savedKeys = {};
            var nodeInfo = QDRService.topology.nodeInfo();
            // save the number of connections per node
		    for (var key in nodeInfo) {
		        savedKeys[key] = nodeInfo[key]['.connection'].results.length;
		    }
			//QDR.log.debug("saving current keys");
			console.dump(savedKeys);
		};
		// we are about to leave the page, save the node positions
		$rootScope.$on('$locationChangeStart', function(event, newUrl, oldUrl) {
			//QDR.log.debug("locationChangeStart");
			nodes.forEach( function (d) {
	           localStorage[d.name] = angular.toJson({x: d.x, y: d.y, fixed: d.fixed});
			});
            $scope.addingNode.step = 0;

		});
		// When the DOM element is removed from the page,
        // AngularJS will trigger the $destroy event on
        // the scope
        $scope.$on("$destroy", function( event ) {
   			//QDR.log.debug("scope on destroy");
            QDRService.stopUpdating();
            QDRService.delUpdatedAction("topology");
			d3.select("#SVG_ID").remove();
        });

		initForceGraph();
		saveChanged();
        QDRService.startUpdating();

	    function doAddDialog(NewRouterName) {
		    var d = $dialog.dialog({
				dialogClass: "modal dlg-large",
				backdrop: true,
				keyboard: true,
				backdropClick: true,
		        controller: 'QDR.NodeDialogController',
		        templateUrl: 'node-config-template.html',
		        resolve: {
		            newname: function () {
		                return NewRouterName;
		            }
		        }
		    });
		    d.open().then(function (result) {
				if (result)
					doDownloadDialog(result);
		    });
        };

	    function doDownloadDialog(result) {
		    d = $dialog.dialog({
				backdrop: true,
				keyboard: true,
				backdropClick: true,
				controller: 'QDR.DownloadDialogController',
		        templateUrl: 'download-dialog-template.html',
		        resolve: {
		            results: function () {
		                return result;
		            }
		        }
		    });
		    d.open().then(function (result) {
		    //QDR.log.debug("download dialog done")
		    })
            if (!$scope.$$phase) $scope.$apply()
        };
  }]);

  QDR.module.controller("QDR.NodeDialogController", function($scope, QDRService, dialog, newname) {
   		var schema = QDRService.schema;
   		var myEntities = ['router', 'log', 'listener' ];
   		var typeMap = {integer: 'number', string: 'text', path: 'text', boolean: 'boolean'};
		var newLinks = $('path.temp').toArray();    // jquery array of new links for the added router
		var nodeInfo = QDRService.topology.nodeInfo();
		var separatedEntities = []; // additional entities required if a link is reversed
		var myPort = 0, myAddr = '0.0.0.0'; // port and address for new router
   		$scope.entities = [];

		// find max port number that is used in all the listeners
		var getMaxPort = function (nodeInfo) {
			var maxPort = 5674;
			for (var key in nodeInfo) {
				var node = nodeInfo[key];
				var listeners = node['.listener'];
				var attrs = listeners.attributeNames;
				for (var i=0; i<listeners.results.length; ++i) {
					var res = listeners.results[i];
					var port = QDRService.valFor(attrs, res, 'port');
					if (parseInt(port, 10) > maxPort)
						maxPort = parseInt(port, 10);
				}
			}
			return maxPort;
		}
		var maxPort = getMaxPort(nodeInfo);

		// construct an object that contains all the info needed for a single tab's fields
		var entity = function (actualName, tabName, humanName, ent, icon, link) {
			var nameIndex = -1; // the index into attributes that the name field was placed
			var index = 0;
			var info = {
			    actualName: actualName,
				tabName:    tabName,
				humanName:  humanName,
				description:ent.description,
				icon:       angular.isDefined(icon) ? icon : '',
				references: ent.references,
				link:       link,

   		        attributes: $.map(ent.attributes, function (value, key) {
					// skip identity and depricated fields
   		            if (key == 'identity' || value.description.startsWith('Deprecated'))
   		                return null;
					var val = value['default'];
					if (key == 'name')
						nameIndex = index;
					index++;
					return {    name:       key,
								humanName:  QDRService.humanify(key),
                                description:value.description,
                                type:       typeMap[value.type],
                                rawtype:    value.type,
                                input:      typeof value.type == 'string' ? value.type == 'boolean' ? 'boolean' : 'input'
                                                                          : 'select',
                                selected:   val ? val : undefined,
                                'default':  value['default'],
                                value:      val,
                                required:   value.required,
                                unique:     value.unique
                    };
                })
			}
			// move the 'name' attribute to the 1st position
			if (nameIndex > -1) {
				var tmp = info.attributes[0];
				info.attributes[0] = info.attributes[nameIndex];
				info.attributes[nameIndex] = tmp;
			}
			return info;
		}

		// remove the annotation fields
		var stripAnnotations = function (entityName, ent, annotations) {
			if (ent.references) {
				var newEnt = {attributes: {}};
				ent.references.forEach( function (annoKey) {
					if (!annotations[annoKey])
						annotations[annoKey] = {};
					annotations[annoKey][entityName] = true;    // create the key/consolidate duplicates
					var keys = Object.keys(schema.annotations[annoKey].attributes);
					for (var attrib in ent.attributes) {
						if (keys.indexOf(attrib) == -1) {
							newEnt.attributes[attrib] = ent.attributes[attrib];
						}
					}
					// add a field for the reference name
					newEnt.attributes[annoKey] = {type: 'string',
							description: 'Name of the ' + annoKey + ' section.',
							'default': annoKey, required: true};
				})
				newEnt.references = ent.references;
				newEnt.description = ent.description;
				return newEnt;
			}
			return ent;
		}

		var annotations = {};
   		myEntities.forEach(function (entityName) {
   		    var ent = schema.entityTypes[entityName];
   		    var hName = QDRService.humanify(entityName);
   		    if (entityName == 'listener')
   		        hName = "Listener for clients";
   		    var noAnnotations = stripAnnotations(entityName, ent, annotations);
			var ediv = entity(entityName, entityName, hName, noAnnotations, undefined);
			if (ediv.actualName == 'router') {
				ediv.attributes.filter(function (attr) { return attr.name == 'name'})[0].value = newname;
				// if we have any new links (connectors), then the router's mode should be interior
				if (newLinks.length) {
					var roleAttr = ediv.attributes.filter(function (attr) { return attr.name == 'mode'})[0];
					roleAttr.value = roleAttr.selected = "interior";
				}
			}
			if (ediv.actualName == 'container') {
				ediv.attributes.filter(function (attr) { return attr.name == 'containerName'})[0].value = newname + "-container";
			}
			if (ediv.actualName == 'listener') {
				// find max port number that is used in all the listeners
				ediv.attributes.filter(function (attr) { return attr.name == 'port'})[0].value = ++maxPort;
			}
			// special case for required log.module since it doesn't have a default
			if (ediv.actualName == 'log') {
				var moduleAttr = ediv.attributes.filter(function (attr) { return attr.name == 'module'})[0];
				moduleAttr.value = moduleAttr.selected = "DEFAULT";
			}
			$scope.entities.push( ediv );
   		})

		// add a tab for each annotation that was found
		var annotationEnts = [];
		for (var key in annotations) {
			ent = angular.copy(schema.annotations[key]);
			ent.attributes.name = {type: "string", unique: true, description: "Unique name that is used to refer to this set of attributes."}
			var ediv = entity(key, key+'tab', QDRService.humanify(key), ent, undefined);
			ediv.attributes.filter(function (attr) { return attr.name == 'name'})[0].value = key;
			$scope.entities.push( ediv );
			annotationEnts.push( ediv );
		}

		// add an additional listener tab if any links are reversed
		ent = schema.entityTypes['listener'];
		newLinks.some(function (link) {
			if (link.__data__.right) {
	   		    var noAnnotations = stripAnnotations('listener', ent, annotations);
				var ediv = entity("listener", "listener0", "Listener (internal)", noAnnotations, undefined);
				ediv.attributes.filter(function (attr) { return attr.name == 'port'})[0].value = ++maxPort;
				// connectors from other routers need to connect to this addr:port
				myPort = maxPort;
				myAddr = ediv.attributes.filter(function (attr) { return attr.name == 'host'})[0].value

				// override the role. 'normal' is the default, but we want inter-router
				ediv.attributes.filter(function( attr ) { return attr.name == 'role'})[0].selected = 'inter-router';
				separatedEntities.push( ediv );
				return true; // stop looping
			}
			return false;   // continue looping
		})

		// Add connector tabs for each new link on the topology graph
		ent = schema.entityTypes['connector'];
		newLinks.forEach(function (link, i) {
   		    var noAnnotations = stripAnnotations('connector', ent, annotations);
			var ediv = entity('connector', 'connector' + i, " " + link.__data__.source.name, noAnnotations, link.__data__.right, link)

			// override the connector role. 'normal' is the default, but we want inter-router
			ediv.attributes.filter(function( attr ) { return attr.name == 'role'})[0].selected = 'inter-router';

			// find the addr:port of the inter-router listener to use
			var listener = nodeInfo[link.__data__.source.key]['.listener'];
			var attrs = listener.attributeNames;
			for (var i=0; i<listener.results.length; ++i) {
				var res = listener.results[i];
				var role = QDRService.valFor(attrs, res, 'role');
				if (role == 'inter-router') {
					ediv.attributes.filter(function( attr ) { return attr.name == 'host'})[0].value =
						QDRService.valFor(attrs, res, 'host')
					ediv.attributes.filter(function( attr ) { return attr.name == 'port'})[0].value =
						QDRService.valFor(attrs, res, 'port')
					break;
				}
			}
			if (link.__data__.right) {
				// connectors from other nodes need to connect to the new router's listener addr:port
   				ediv.attributes.filter(function (attr) { return attr.name == 'port'})[0].value = myPort;
   				ediv.attributes.filter(function (attr) { return attr.name == 'host'})[0].value = myAddr;

				separatedEntities.push(ediv)
			}
			else
				$scope.entities.push( ediv );
		})
		Array.prototype.push.apply($scope.entities, separatedEntities);

		// update the description on all the annotation tabs
		annotationEnts.forEach ( function (ent) {
			var shared = Object.keys(annotations[ent.actualName]);
			ent.description += " These fields are shared by " + shared.join(" and ") + ".";

		})

		$scope.testPattern = function (attr) {
			if (attr.rawtype == 'path')
				return /^(\/)?([^/\0]+(\/)?)+$/;
				//return /^(.*\/)([^/]*)$/;
			return /(.*?)/;
		}

		$scope.attributeDescription = '';
		$scope.attributeType = '';
		$scope.attributeRequired = '';
		$scope.attributeUnique = '';
		$scope.active = 'router'
		$scope.fieldsetDivs = "/fieldsetDivs.html"
		$scope.setActive = function (tabName) {
			$scope.active = tabName
		}
		$scope.isActive = function (tabName) {
			return $scope.active === tabName
		}
		$scope.showDescription = function (attr, e) {
			$scope.attributeDescription = attr.description;
			var offset = jQuery(e.currentTarget).offset()
			jQuery('.attr-description').offset({top: offset.top})

			$scope.attributeType = "Type: " + JSON.stringify(attr.rawtype);
			$scope.attributeRequired = attr.required ? 'required' : '';
			$scope.attributeUnique = attr.unique ? 'Must be unique' : '';
		}
        // handle the download button click
        // copy the dialog's values to the original node
        $scope.download = function () {
	        dialog.close({entities: $scope.entities, annotations: annotations});
        }
        $scope.cancel = function () {
            dialog.close()
        };

		$scope.selectAnnotationTab = function (tabName) {
            var tabs = $( "#tabs" ).tabs();
            tabs.tabs("select", tabName);
		}

        var initTabs = function () {
            var div = angular.element("#tabs");
            if (!div.width()) {
                setTimeout(initTabs, 100);
                return;
            }
            $( "#tabs" )
                .tabs()
                .addClass('ui-tabs-vertical ui-helper-clearfix');
        }
        // start the update loop
        initTabs();

  });

QDR.module.controller("QDR.DownloadDialogController", function($scope, QDRService, $templateCache, $window, dialog, results) {
		var result = results.entities;
		var annotations = results.annotations;
		var annotationKeys = Object.keys(annotations);
		var annotationSections = {};

		// use the router's name as the file name if present
		$scope.newRouterName = 'router';
		result.forEach( function (e) {
			if (e.actualName == 'router') {
				e.attributes.forEach( function (a) {
					if (a.name == 'name') {
						$scope.newRouterName = a.value;
					}
				})
			}
		})
		$scope.newRouterName = $scope.newRouterName + ".conf";

		var template = $templateCache.get('config-file-header.html');
		$scope.verbose = true;
		$scope.$watch('verbose', function (newVal) {
			if (newVal !== undefined) {
				// recreate output using current verbose setting
				getOutput();
			}
		})

		var getOutput = function () {
			$scope.output = template + '\n';
			$scope.parts = [];
			var commentChar = '#'
			result.forEach(function (entity) {
				// don't output a section for annotations, they get flattened into the entities
				var section = "";
				if (entity.icon) {
					section += "##\n## Add to " + entity.link.__data__.source.name + "'s configuration file\n##\n";
				}
				section += "##\n## " + QDRService.humanify(entity.actualName) + " - " + entity.description + "\n##\n";
				section += entity.actualName + " {\n";
				entity.attributes.forEach(function (attribute) {
					if (attribute.input == 'select')
						attribute.value = attribute.selected;

					// treat values with all spaces and empty strings as undefined
					attribute.value = String(attribute.value).trim();
					if (attribute.value === 'undefined' || attribute.value === '')
						attribute.value = undefined;

					if ($scope.verbose) {
						commentChar = attribute.required || attribute.value != attribute['default'] ? ' ' : '#';
						if (!attribute.value) {
							commentChar = '#';
							attribute.value = '';
						}
						section += commentChar + "    "
							+ attribute.name + ":" + Array(Math.max(20 - attribute.name.length, 1)).join(" ")
							+ attribute.value
						    + Array(Math.max(20 - ((attribute.value)+"").length, 1)).join(" ")
							+ '# ' + attribute.description
						    + "\n";
					} else {
						if (attribute.value) {
							if (attribute.value != attribute['default'] || attribute.required)
								section += "    "
									+ attribute.name + ":" + Array(20 - attribute.name.length).join(" ")
									+ attribute.value + "\n";

						}
					}
				})
				section += "}\n\n";
				// if entity.icon is true, this is a connector intended for another router
				if (entity.icon)
					$scope.parts.push({output: section,
								link: entity.link,
								name: entity.link.__data__.source.name,
								references: entity.references});
				else
					$scope.output += section;

				// if this section is actually an annotation
				if (annotationKeys.indexOf(entity.actualName) > -1) {
					annotationSections[entity.actualName] = section;
				}
			})
			// go back and add annotation sections to the parts
			$scope.parts.forEach (function (part) {
				for (var section in annotationSections) {
					if (part.references.indexOf(section) > -1) {
						part.output += annotationSections[section];
					}
				}
			})
			QDR.log.debug($scope.output);
		}

        // handle the download button click
        $scope.download = function () {
			var output = $scope.output + "\n\n"
			var blob = new Blob([output], { type: 'text/plain;charset=utf-16' });
			saveAs(blob, $scope.newRouterName);
        }

		$scope.downloadPart = function (part) {
			var linkName = part.link.__data__.source.name + 'additional.conf';
			var blob = new Blob([part.output], { type: 'text/plain;charset=utf-16' });
			saveAs(blob, linkName);
		}

		$scope.done = function () {
	        dialog.close();
		}
});

  return QDR;
}(QDR || {}));
