// File: Luthaf[P]zeopp/networkanalysis.cc
// Function: calculateNodalFreeSphere(DIJKSTRA_NETWORK*, DELTA_POS)
double calculateNodalFreeSphere(DIJKSTRA_NETWORK *dnet, DELTA_POS filter){
  vector<bool> nodeProcessed = vector<bool>(dnet->nodes.size(), false);
  vector<double> bestRadii   = vector<double>(dnet->nodes.size(), -1);
  unsigned int nodeIndex = 0;

  double maxRadius = 0.0;

  // Iterate over all nodes
  while(nodeIndex < nodeProcessed.size()){
   
    // Place starting node on stack with (0,0,0) displacement
    DELTA_POS displacement = DELTA_POS(0,0,0);
    map<int, pair<DELTA_POS, double> > visitedNodes;
    
    HEAP<pair<int, pair<DELTA_POS, double> > > heap (betterPath);
    heap.insert(pair<int, pair<DELTA_POS, double> > (nodeIndex, pair<DELTA_POS, double> (displacement, dnet->nodes[nodeIndex].max_radius)));
  
    while(heap.size() != 0){
      // Remove best remaining path
      pair<int, pair<DELTA_POS, double> > pathInfo = heap.pop();
      map<int, pair<DELTA_POS, double> >::iterator nodeInfo = visitedNodes.find(pathInfo.first);
      
      if(pathInfo.second.second < maxRadius)
	break;

      // Ending on a preprocessed node
      if(pathInfo.first == -1){
	bestRadii[nodeIndex] = pathInfo.first;
	break;
      }

      if(nodeInfo != visitedNodes.end()){
	if(nodeInfo->second.first.equals(pathInfo.second.first)){
	  // Circling back to previous node so terminate path
	  continue;
	}
	else {
	  // Found the optimal path through the start node
	  bestRadii[nodeIndex] = min(pathInfo.second.second, nodeInfo->second.second);
	  maxRadius = max(maxRadius, bestRadii[nodeIndex]);
	  break;
	}
      }
      else{
	visitedNodes.insert(pathInfo);
	DIJKSTRA_NODE currentNode = dnet->nodes[pathInfo.first];
	vector<CONN>::iterator connIter = currentNode.connections.begin();
	// Follow all edges leading to adjoining nodes
      
	while(connIter != currentNode.connections.end()){
	  int to = connIter->to;
	  if(nodeProcessed[to]){
	    // Know the best radii for this path because the next node has already been processed
	    // Change its node id to -1 to denote this
	    heap.insert(pair<int, pair<DELTA_POS, double> > (
	      -1, pair<DELTA_POS, double> (DELTA_POS(0,0,0), min(
	      connIter->max_radius, min(pathInfo.second.second, bestRadii[to])))));
	  }
	  else{
	    DELTA_POS newDisplacement = pathInfo.second.first + (
	      connIter->deltaPos*filter);
	    heap.insert(pair<int, pair<DELTA_POS, double> > (
	      to, pair<DELTA_POS, double> (newDisplacement, min(
	      dnet->nodes[to].max_radius, min(pathInfo.second.second,
	      connIter->max_radius)))));
	  }
	  connIter++;
	}
      }
    }
    nodeProcessed[nodeIndex] = true;
    nodeIndex++;
  }
  return maxRadius;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x410, %rsp            # imm = 0x410
movq %rsi, -0x20(%rbp)
movl %edx, -0x18(%rbp)
movl -0x18(%rbp), %eax
movl %eax, -0x8(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x10(%rbp)
movq %rdi, -0x28(%rbp)
movq -0x28(%rbp), %rdi
callq 0x10100
movq %rax, -0x2e8(%rbp)
movb $0x0, -0x51(%rbp)
leaq -0x52(%rbp), %rdi
movq %rdi, -0x2e0(%rbp)
callq 0x64b50
movq -0x2e8(%rbp), %rsi
movq -0x2e0(%rbp), %rcx
leaq -0x50(%rbp), %rdi
leaq -0x51(%rbp), %rdx
callq 0x64b70
jmp 0x5fee5
leaq -0x52(%rbp), %rdi
callq 0x64bf0
movq -0x28(%rbp), %rdi
callq 0x10100
movq %rax, -0x2f8(%rbp)
movabsq $-0x4010000000000000, %rax # imm = 0xBFF0000000000000
movq %rax, -0x88(%rbp)
leaq -0x89(%rbp), %rdi
movq %rdi, -0x2f0(%rbp)
callq 0x10b20
movq -0x2f8(%rbp), %rsi
movq -0x2f0(%rbp), %rcx
leaq -0x80(%rbp), %rdi
leaq -0x88(%rbp), %rdx
callq 0x64ff0
jmp 0x5ff42
leaq -0x89(%rbp), %rdi
callq 0x1ebe0
movl $0x0, -0x90(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x98(%rbp)
movl -0x90(%rbp), %eax
movq %rax, -0x300(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x27d50
movq %rax, %rcx
movq -0x300(%rbp), %rax
cmpq %rcx, %rax
jae 0x60709
leaq -0xa4(%rbp), %rdi
xorl %ecx, %ecx
movl %ecx, %esi
movl %ecx, %edx
callq 0x94010
jmp 0x5ffa0
leaq -0xd8(%rbp), %rdi
callq 0x65070
leaq -0x163(%rip), %rsi      # 0x5fe50
leaq -0xf8(%rbp), %rdi
callq 0x65090
jmp 0x5ffc1
movq -0x28(%rbp), %rdi
movl -0x90(%rbp), %eax
movl %eax, %esi
callq 0x2a4c0
movq %rax, %rdx
addq $0x38, %rdx
leaq -0x130(%rbp), %rdi
leaq -0xa4(%rbp), %rsi
callq 0x65150
jmp 0x5ffee
leaq -0x118(%rbp), %rdi
leaq -0x90(%rbp), %rsi
leaq -0x130(%rbp), %rdx
callq 0x65190
jmp 0x6000a
movups -0x118(%rbp), %xmm0
movups -0x108(%rbp), %xmm1
movq %rsp, %rax
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
leaq -0xf8(%rbp), %rdi
callq 0x650f0
jmp 0x60030
jmp 0x60032
leaq -0xf8(%rbp), %rdi
callq 0x651d0
movl %eax, -0x304(%rbp)
jmp 0x60046
movl -0x304(%rbp), %eax
cmpl $0x0, %eax
je 0x60675
leaq -0x150(%rbp), %rdi
leaq -0xf8(%rbp), %rsi
callq 0x651f0
jmp 0x6006a
leaq -0xd8(%rbp), %rdi
leaq -0x150(%rbp), %rsi
callq 0x65280
movq %rax, -0x310(%rbp)
jmp 0x60086
movq -0x310(%rbp), %rax
movq %rax, -0x158(%rbp)
movsd -0x138(%rbp), %xmm1
movsd -0x98(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x60119
jmp 0x60675
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x52(%rbp), %rdi
callq 0x64bf0
jmp 0x6074e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x89(%rbp), %rdi
callq 0x1ebe0
jmp 0x60745
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x6073c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x606fb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x606ef
cmpl $-0x1, -0x150(%rbp)
jne 0x60154
cvtsi2sdl -0x150(%rbp), %xmm0
movsd %xmm0, -0x318(%rbp)
movl -0x90(%rbp), %eax
movl %eax, %esi
leaq -0x80(%rbp), %rdi
callq 0xedb0
movsd -0x318(%rbp), %xmm0
movsd %xmm0, (%rax)
jmp 0x60675
leaq -0xd8(%rbp), %rdi
callq 0x652e0
movq %rax, -0x160(%rbp)
leaq -0x158(%rbp), %rdi
leaq -0x160(%rbp), %rsi
callq 0x652b0
testb $0x1, %al
jne 0x60183
jmp 0x602a6
leaq -0x158(%rbp), %rdi
callq 0x65310
movq %rax, %rdi
addq $0x8, %rdi
movl -0x140(%rbp), %eax
movl %eax, -0x168(%rbp)
movq -0x148(%rbp), %rax
movq %rax, -0x170(%rbp)
movl -0x168(%rbp), %eax
movl %eax, -0x178(%rbp)
movq -0x170(%rbp), %rax
movq %rax, -0x180(%rbp)
movq -0x180(%rbp), %rsi
movl -0x178(%rbp), %edx
callq 0x94040
movb %al, -0x319(%rbp)
jmp 0x601e4
movb -0x319(%rbp), %al
testb $0x1, %al
jne 0x601f0
jmp 0x601f5
jmp 0x60032
leaq -0x138(%rbp), %rax
movq %rax, -0x330(%rbp)
leaq -0x158(%rbp), %rdi
callq 0x65310
movq -0x330(%rbp), %rdi
movq %rax, %rsi
addq $0x18, %rsi
callq 0x64f50
movq %rax, -0x328(%rbp)
jmp 0x6022b
movq -0x328(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x348(%rbp)
movl -0x90(%rbp), %eax
movl %eax, %esi
leaq -0x80(%rbp), %rdi
movq %rdi, -0x340(%rbp)
callq 0xedb0
movsd -0x348(%rbp), %xmm0
movq -0x340(%rbp), %rdi
movsd %xmm0, (%rax)
movl -0x90(%rbp), %eax
movl %eax, %esi
callq 0xedb0
movq %rax, %rsi
leaq -0x98(%rbp), %rdi
callq 0x64c70
movq %rax, -0x338(%rbp)
jmp 0x6028e
movq -0x338(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x98(%rbp)
jmp 0x60675
leaq -0xd8(%rbp), %rdi
leaq -0x150(%rbp), %rsi
callq 0x65330
movb %dl, -0x351(%rbp)
movq %rax, -0x350(%rbp)
jmp 0x602c8
movb -0x351(%rbp), %al
movq -0x350(%rbp), %rcx
movq %rcx, -0x190(%rbp)
movb %al, -0x188(%rbp)
movq -0x28(%rbp), %rdi
movslq -0x150(%rbp), %rsi
callq 0x2a4c0
movq %rax, %rsi
leaq -0x1d8(%rbp), %rdi
callq 0x64400
jmp 0x60303
leaq -0x1d8(%rbp), %rdi
addq $0x20, %rdi
callq 0x2a8e0
movq %rax, -0x1e0(%rbp)
leaq -0x1d8(%rbp), %rdi
addq $0x20, %rdi
callq 0x2a710
movq %rax, -0x1e8(%rbp)
leaq -0x1e0(%rbp), %rdi
leaq -0x1e8(%rbp), %rsi
callq 0x65370
testb $0x1, %al
jne 0x6034d
jmp 0x60664
leaq -0x1e0(%rbp), %rdi
callq 0x653b0
movl 0x4(%rax), %eax
movl %eax, -0x1ec(%rbp)
movslq -0x1ec(%rbp), %rsi
leaq -0x50(%rbp), %rdi
callq 0x29990
movq %rdx, -0x368(%rbp)
movq %rax, -0x360(%rbp)
jmp 0x60382
movq -0x368(%rbp), %rax
movq -0x360(%rbp), %rcx
movq %rcx, -0x200(%rbp)
movq %rax, -0x1f8(%rbp)
leaq -0x200(%rbp), %rdi
callq 0x101a0
testb $0x1, %al
jne 0x603b3
jmp 0x604ba
movl $0xffffffff, -0x224(%rbp) # imm = 0xFFFFFFFF
leaq -0x24c(%rbp), %rdi
xorl %ecx, %ecx
movl %ecx, %esi
movl %ecx, %edx
callq 0x94010
jmp 0x603d1
leaq -0x1e0(%rbp), %rdi
callq 0x653b0
addq $0x10, %rax
movq %rax, -0x380(%rbp)
leaq -0x138(%rbp), %rax
movq %rax, -0x378(%rbp)
movslq -0x1ec(%rbp), %rsi
leaq -0x80(%rbp), %rdi
callq 0xedb0
movq -0x378(%rbp), %rdi
movq %rax, %rsi
callq 0x64f50
movq %rax, -0x370(%rbp)
jmp 0x6041e
movq -0x370(%rbp), %rsi
movq -0x380(%rbp), %rdi
callq 0x64f50
movq %rax, -0x388(%rbp)
jmp 0x6043a
movq -0x388(%rbp), %rdx
leaq -0x240(%rbp), %rdi
leaq -0x24c(%rbp), %rsi
callq 0x653d0
jmp 0x60456
leaq -0x220(%rbp), %rdi
leaq -0x224(%rbp), %rsi
leaq -0x240(%rbp), %rdx
callq 0x65410
jmp 0x60472
movups -0x220(%rbp), %xmm0
movups -0x210(%rbp), %xmm1
movq %rsp, %rax
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
leaq -0xf8(%rbp), %rdi
callq 0x650f0
jmp 0x60498
jmp 0x6064a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x1d8(%rbp), %rdi
callq 0x100e0
jmp 0x606ef
leaq -0x148(%rbp), %rax
movq %rax, -0x3a0(%rbp)
leaq -0x1e0(%rbp), %rdi
callq 0x653b0
movq %rax, %rdi
addq $0x18, %rdi
leaq -0x10(%rbp), %rsi
callq 0x940f0
movl %edx, -0x394(%rbp)
movq %rax, -0x390(%rbp)
jmp 0x604f3
movq -0x3a0(%rbp), %rdi
movl -0x394(%rbp), %eax
movq -0x390(%rbp), %rcx
movq %rcx, -0x278(%rbp)
movl %eax, -0x270(%rbp)
movl -0x270(%rbp), %eax
movl %eax, -0x260(%rbp)
movq -0x278(%rbp), %rax
movq %rax, -0x268(%rbp)
leaq -0x268(%rbp), %rsi
callq 0x94150
movl %edx, -0x3ac(%rbp)
movq %rax, -0x3a8(%rbp)
jmp 0x60549
movl -0x3ac(%rbp), %eax
movq -0x3a8(%rbp), %rcx
movq %rcx, -0x288(%rbp)
movl %eax, -0x280(%rbp)
movl -0x280(%rbp), %eax
movl %eax, -0x250(%rbp)
movq -0x288(%rbp), %rax
movq %rax, -0x258(%rbp)
movq -0x28(%rbp), %rdi
movslq -0x1ec(%rbp), %rsi
callq 0x2a4c0
addq $0x38, %rax
movq %rax, -0x3c8(%rbp)
leaq -0x138(%rbp), %rax
movq %rax, -0x3c0(%rbp)
leaq -0x1e0(%rbp), %rdi
callq 0x653b0
movq -0x3c0(%rbp), %rdi
movq %rax, %rsi
addq $0x10, %rsi
callq 0x64f50
movq %rax, -0x3b8(%rbp)
jmp 0x605ce
movq -0x3b8(%rbp), %rsi
movq -0x3c8(%rbp), %rdi
callq 0x64f50
movq %rax, -0x3d0(%rbp)
jmp 0x605ea
movq -0x3d0(%rbp), %rdx
leaq -0x2c0(%rbp), %rdi
leaq -0x258(%rbp), %rsi
callq 0x65450
jmp 0x60606
leaq -0x2a8(%rbp), %rdi
leaq -0x1ec(%rbp), %rsi
leaq -0x2c0(%rbp), %rdx
callq 0x65490
jmp 0x60622
movups -0x2a8(%rbp), %xmm0
movups -0x298(%rbp), %xmm1
movq %rsp, %rax
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
leaq -0xf8(%rbp), %rdi
callq 0x650f0
jmp 0x60648
jmp 0x6064a
leaq -0x1e0(%rbp), %rdi
xorl %esi, %esi
callq 0x654d0
movq %rax, -0x2c8(%rbp)
jmp 0x6031a
leaq -0x1d8(%rbp), %rdi
callq 0x100e0
jmp 0x60032
movl -0x90(%rbp), %eax
movl %eax, %esi
leaq -0x50(%rbp), %rdi
callq 0x29990
movq %rdx, -0x3e0(%rbp)
movq %rax, -0x3d8(%rbp)
jmp 0x60696
movq -0x3e0(%rbp), %rax
movq -0x3d8(%rbp), %rcx
movq %rcx, -0x2d8(%rbp)
movq %rax, -0x2d0(%rbp)
leaq -0x2d8(%rbp), %rdi
movl $0x1, %esi
callq 0x10040
movl -0x90(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x90(%rbp)
leaq -0xf8(%rbp), %rdi
callq 0x65510
leaq -0xd8(%rbp), %rdi
callq 0x65530
jmp 0x5ff63
leaq -0xf8(%rbp), %rdi
callq 0x65510
leaq -0xd8(%rbp), %rdi
callq 0x65530
jmp 0x6073c
movsd -0x98(%rbp), %xmm0
movsd %xmm0, -0x3e8(%rbp)
leaq -0x80(%rbp), %rdi
callq 0xf9d0
leaq -0x50(%rbp), %rdi
callq 0xf9b0
movsd -0x3e8(%rbp), %xmm0
addq $0x410, %rsp            # imm = 0x410
popq %rbp
retq
leaq -0x80(%rbp), %rdi
callq 0xf9d0
leaq -0x50(%rbp), %rdi
callq 0xf9b0
movq -0x60(%rbp), %rdi
callq 0x58f0
nopw (%rax,%rax)