function convert_to_topodata(switches, links, registry){
    var controllers={};
    var nr_controllers=0;
    var sws=[];
    var ls=[];
    var topo = new Array();
    switches.forEach(function(item) {
	var sw={}
	sw.name=item.dpid;
	sw.group=-1;
	sws.push(sw);
    });
    for (var r in registry){
	if ( ! (registry[r][0]['controllerId'] in controllers) ){
	    controllers[registry[r][0]['controllerId']] = ++nr_controllers;
	}
    }
    for (var i = 0; i < sws.length; i++){
	if (sws[i].name in registry){
	    sws[i].group=controllers[registry[sws[i].name][0]['controllerId']];
	    sws[i].controller=registry[sws[i].name][0]['controllerId'];
	}
    }
    links.forEach(function(item) {
	var link={};
	for (var i = 0; i < sws.length; i++){
	    if(sws[i].name == item['src-switch'])
		break;
	}
	link.source=i;
	for (var i = 0; i < sws.length; i++){
	    if(sws[i].name == item['dst-switch'])
		break;
	}
	link.target=i;
	ls.push(link);
    });
    topo['nodes']=sws;
    topo['links']=ls;
    return topo;
}

var width = 1280;
var height = 1280;
var radius = 8;
function gui(switch_url, link_url, registry_url){
    var svg = d3.select("#topology")
	.append("svg:svg")
	.attr("width", width)
	.attr("height", height);

    var force = d3.layout.force()
	.charge(-500)
	.linkDistance(100)
	.size([width, height]);

    var node_drag = d3.behavior.drag()
        .on("dragstart", dragstart)
        .on("drag", dragmove)
        .on("dragend", dragend);

    var color = d3.scale.category20();
    var topodata;
    var nodes = force.nodes();
    var links = force.links();

    d3.json(switch_url, function(error, rest_switches) {
	d3.json(link_url, function(error, rest_links) { 
	    d3.json(registry_url, function(error, rest_registry) { 
		topodata = convert_to_topodata(rest_switches, rest_links, rest_registry);
		init(topodata, nodes, links);
		path = svg.append("svg:g").selectAll("path").data(links);
		circle = svg.append("svg:g").selectAll("circle").data(nodes);
		text = svg.append("svg:g").selectAll("text").data(nodes);
		draw();
	    });
	}); 
    }); 

    setInterval(function(){ 
	d3.json(switch_url, function(error, rest_switches) {
	    d3.json(link_url, function(error, rest_links) { 
		d3.json(registry_url, function(error, rest_registry) { 
		    topodata = convert_to_topodata(rest_switches, rest_links, rest_registry);
		    var changed = update(topodata, nodes, links);
		    path = svg.selectAll("path").data(links)
		    circle = svg.selectAll("circle").data(nodes);
		    text = svg.selectAll("text").data(nodes);
		    if ( changed ){
			draw();
		    }
		});
	    }); 
	}); 
    }, 3000); 

    function draw(){
	force.stop();
	svg.append("svg:text")
	    .attr("x", 50)
	    .attr("y", 20)
            .text(function(){return "Switch: " + force.nodes().length + " (Active: " + nr_active_sw()  + ")/ Link: " + force.links().length});
    
	path.enter().append("svg:path")
	    .attr("class", function(d) { return "link"; })
	    .attr("marker-end", function(d) {
		if(d.type == 1){
		    return "url(#TriangleRed)";
		} else {
		    return "url(#Triangle)";
		}
	    });
	
	circle.enter().append("svg:circle")
	    .attr("r", function(d) { 
		if (d.group == 1000){
		    return radius;
		}else{
		    return radius;
		}
	    })
	    .call(node_drag);
    
	text.enter().append("svg:text")
	    .attr("x", radius)
	    .attr("y", ".31em")
	    .text(function(d) { 
		l=d.name.split(":").length
		return d.name.split(":")[l-2] + ":" + d.name.split(":")[l-1]
	    });
    
	circle.append("title")
	    .text(function(d) { return d.name; });
    
	circle.attr("fill", function(d) {
            if (d.group == 1){
		return "red"
            }else if (d.group == 2){
		return "blue"
            }else if (d.group == 3){
		return "green"
            }else if (d.group == 4){
		return "orange"
            }else if (d.group == 5){
		return "cyan"
            }else if (d.group == 6){
		return "magenta"
            }else if (d.group == 7){
		return "yellow"
            }else if (d.group == 8){
		return "purple"
            }else{
		return "gray"
            }
	});

        circle.on('mouseover', function(d){
   	 var nodeSelection = d3.select(this).style({opacity:'0.8'});
  	  nodeSelection.select("text").style({opacity:'1.0'});
	});


	path.attr("stroke", function(d) {
	    if(d.type == 1){
		return "red"
	    } else {
		return "black"
	    }
	}).attr("stroke-width", function(d) {
	    if(d.type == 1){
		return "2px";
	    } else {
		return "1.5px";
	    }
	}).attr("marker-end", function(d) {
	    if(d.type == 1){
		return "url(#TriangleRed)";
	    } else {
		return "url(#Triangle)";
	    }
	});
	path.exit().remove();
	circle.exit().remove();
	text.exit().remove();
	force.on("tick", tick);
	force.start();
    }
    function nr_active_sw(){
        var n=0; 
        var nodes = force.nodes();
        for(var i=0;i<nodes.length;i++){
          if(nodes[i].group!=0)
            n++;
        }; 
        return n;
    }
    function dragstart(d, i) {
        force.stop() // stops the force auto positioning before you start dragging
    }
    function dragmove(d, i) {
        d.px += d3.event.dx;
        d.py += d3.event.dy;
        d.x += d3.event.dx;
        d.y += d3.event.dy; 
        tick(); // this is the key to make it work together with updating both px,py,x,y on d !
    }

    function dragend(d, i) {
        d.fixed = true; // of course set the node to fixed so the force doesn't include the node in its auto positioning stuff
        tick();
        force.resume();
    }
    function tick() {
	path.attr("d", function(d) {
	    var dx = d.target.x - d.source.x,
	    dy = d.target.y - d.source.y,
	    dr = 1/d.linknum;  //linknum is defined above
	    dr = 0;  // 0 for direct line
	    return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
	});
	path.attr("stroke", function(d) {
	    if(d.type == 1){
		return "red"
	    } else {
		return "black"
	    }
	}).attr("stroke-width", function(d) {
	    if(d.type == 1){
		return "3px";
	    } else {
		return "1.5px";
	    }
	}).attr("marker-end", function(d) {
	    if(d.type == 1){
		return "url(#TriangleRed)";
	    } else {
		return "url(#Triangle)";
	    }
	});
//	circle.attr("cx", function(d) { return d.x; }).attr("cy", function(d) { return d.y; });
	circle.attr("transform", function(d) {
	    x = Math.max(radius, Math.min(width - radius, d.x));
	    y = Math.max(radius, Math.min(height - radius, d.y)); 
//	    return "translate(" + d.x + "," + d.y + ")";
	    return "translate(" + x + "," + y + ")";
	})
	circle.attr("fill", function(d) {
                if (d.group == 1){
                    return "red"
                }else if (d.group == 2){
                    return "blue"
                }else if (d.group == 3){
                    return "green"
                }else if (d.group == 4){
                    return "orange"
                }else if (d.group == 5){
                    return "cyan"
                }else if (d.group == 6){
                    return "magenta"
                }else if (d.group == 7){
                    return "yellow"
                }else if (d.group == 8){
                    return "purple"
                }else{
                    return "gray"
                }
	});
//	text.attr("x", function(d) { return d.x; }).attr("y", function(d) { return d.y; });
	text.attr("transform", function(d) {
	    return "translate(" + d.x + "," + d.y + ")";
	});
    }

}


function init(topodata, nodes, links){
    topodata.nodes.forEach(function(item) {
        nodes.push(item);
    });
    topodata.links.forEach(function(item) {
        links.push(item);
    });
    links.sort(compare_link);
    // distinguish links that have the same src & dst node by 'linknum'
    for (var i=1; i < links.length; i++) {
        if (links[i].source == links[i-1].source &&
            links[i].target == links[i-1].target) {
            links[i].linknum = links[i-1].linknum + 1;
        } else {
	    links[i].linknum = 1;
	};
    };
}

function compare_link (a, b){
    if (a.source > b.source)
	return 1;
    else if (a.source < b.source)
	return -1;
    else {
        if (a.target > b.target)
	    return 1;
        else if (a.target < b.target)
	    return -1;
        else
	    return 0;
    }
}

/* Return nodes that is not in the current list of nodes */
Array.prototype.node_diff = function(arr) {
    return this.filter(function(i) {
	for (var j = 0; j < arr.length ; j++) {
	    if (arr[j].name === i.name)
		return false;
	}
	return true;
    });
};

/* Return removed links */
function gone_links (topo_json, links){
    gone = []
    for (var i = 0; i < links.length ; i ++){
	var found = 0;
	for (var j = 0; j < topo_json.links.length ; j ++){
	    if (links[i].source.name == topo_json.nodes[topo_json.links[j].source].name && 
		links[i].target.name == topo_json.nodes[topo_json.links[j].target].name ){
		found = 1;
		break;
	    }
	}
	if ( found == 0 ){
	    gone.push(links[i]);
	}
    }
    return gone;
}

/* Return added links */
function added_links (topo_json, links) {
    added = [];
    for (var j = 0; j < topo_json.links.length ; j ++){
	var found = 0;
	for (var i = 0; i < links.length ; i ++){
	    if (links[i].source.name == topo_json.nodes[topo_json.links[j].source].name && 
		links[i].target.name == topo_json.nodes[topo_json.links[j].target].name ){
		found = 1;
		break;
	    }
	}
	if ( found == 0 ){
	    added.push(topo_json.links[j]);
	}
    }
    return added;
}

/* check if toplogy has changed and update node[] and link[] accordingly */
function update(json, nodes, links){
    var changed = false;
    var n_adds = json.nodes.node_diff(nodes);
    var n_rems = nodes.node_diff(json.nodes);
    for (var i = 0; i < n_adds.length; i++) {
	nodes.push(n_adds[i]);
	changed = true;
    }
    for (var i = 0; i < n_rems.length; i++) {
	for (var j = 0; j < nodes.length; j++) {
	    if ( nodes[j].name == n_rems[i].name ){
		nodes.splice(j,1);
		changed = true;
		break;
	    }
	}
    }
    var l_adds = added_links(json, links);
    var l_rems = gone_links(json, links);
    for (var i = 0; i < l_rems.length ; i++) {
	for (var j = 0; j < links.length; j++) {
            if (links[j].source.name == l_rems[i].source.name &&
		links[j].target.name == l_rems[i].target.name) {
		links.splice(j,1);
		changed = true;
		break;
            }
	}
    }
    // Sorce/target of an element of l_adds[] are corresponding to the index of json.node[]
    // which is different from the index of node[] (new nodes are always added to the last)
    // So update soure/target node indexes of l_add[] need to be fixed to point to the proper
    // node in node[];
    for (var i = 0; i < l_adds.length; i++) {
	for (var j = 0; j < nodes.length; j++) {
	    if ( json.nodes[l_adds[i].source].name == nodes[j].name ){
		l_adds[i].source = j; 
		break;
	    }
	}
	for (var j = 0; j < nodes.length; j++) {
	    if ( json.nodes[l_adds[i].target].name == nodes[j].name ){
		l_adds[i].target = j;
		break;
	    }
	}
	links.push(l_adds[i]);
	changed = true;
    }

    // Update "group" attribute of nodes
    for (var i = 0; i < nodes.length; i++) {
        for (var j = 0; j < json.nodes.length; j++) {
	    if ( nodes[i].name == json.nodes[j].name ){
		if (nodes[i].group != json.nodes[j].group){
		    nodes[i].group = json.nodes[j].group;
		    changed = true;
		}
	    }
	}
    }
    for (var i = 0; i < links.length; i++) {
        for (var j = 0; j < json.links.length; j++) {
	    if (links[i].target.name == json.nodes[json.links[j].target].name && 
		links[i].source.name == json.nodes[json.links[j].source].name ){
		if (links[i].type != json.links[j].type){
		    links[i].type = json.links[j].type;
		    changed = true;
		}
	    }
	}
    }
    return changed
}

