// File: /workspace/github_cpp_makefile_star2_O1/tomfunkhouser[P]gaps/apps/scn2cam/scn2cam.cpp
// Function: FindIndexOfFurthestPointAlongPath(gaps::R2Grid const&, int, int*, int*)
static int
FindIndexOfFurthestPointAlongPath(const R2Grid& grid, int start_index,
  int *path = NULL, int *path_size = NULL)
{
  // Initialize Dijksra bookkeeping
  R2Grid parent_grid(grid), distance_grid(grid);
  parent_grid.Clear(R2_GRID_UNKNOWN_VALUE);
  distance_grid.Clear(FLT_MAX);
  const RNScalar *grid_values = distance_grid.GridValues();
  int neighbor_index, ix, iy;
  int end_index = -1;
  
  // Compute shortest path to all nonzero points
  RNHeap<const RNScalar *> heap(0);
  distance_grid.SetGridValue(start_index, 0);
  parent_grid.SetGridValue(start_index, start_index);
  heap.Push(grid_values + start_index);
  while (!heap.IsEmpty()) {
    const RNScalar *grid_entry = heap.Pop();
    int grid_index = grid_entry - grid_values;
    end_index = grid_index;
    grid.IndexToIndices(grid_index, ix, iy);
    for (int dx = -1; dx <= 1; dx++) {
      int nx = ix + dx;
      if ((nx < 0) || (nx > grid.XResolution()-1)) continue;
      for (int dy = -1; dy <= 1; dy++) {
        int ny = iy + dy;
        if ((ny < 0) || (ny > grid.YResolution()-1)) continue;
        grid.IndicesToIndex(nx, ny, neighbor_index);
        if (neighbor_index == grid_index) continue;
        if (grid.GridValue(neighbor_index) != R2_GRID_UNKNOWN_VALUE) {
          RNScalar d = distance_grid.GridValue(grid_index) + sqrt(dx*dx + dy*dy);
          RNScalar old_d = distance_grid.GridValue(neighbor_index);
          if (d < old_d) {
            distance_grid.SetGridValue(neighbor_index, d);
            parent_grid.SetGridValue(neighbor_index, grid_index);
            if (old_d == FLT_MAX) heap.Push(grid_values + neighbor_index);
            else heap.Update(grid_values + neighbor_index);
          }
        }
      }
    }
  }

  // Fill in path
  if (path && path_size) {
    // Construct path backwards
    int count = 0;
    path[count++] = end_index;
    while (path[count-1] != start_index) {
      path[count] = (int) parent_grid.GridValue(path[count-1]);
      count++;
    }

    // Reverse order of path
    for (int i = 0; i < count/2; i++) {
      int swap = path[i];
      path[i] = path[count-1-i];
      path[count-1-i] = swap;
    }

    // Fill in path size
    *path_size = count;
  }

  // Return last visited index
  return end_index;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x228, %rsp            # imm = 0x228
movq %rcx, %rbx
movq %rdx, %r14
movl %esi, %ebp
movq %rdi, %r12
leaq 0x158(%rsp), %rdi
movq %r12, %rsi
callq 0x89e20
leaq 0x88(%rsp), %rdi
movq %r12, %rsi
callq 0x89e20
leaq 0x158(%rsp), %rdi
movsd 0xc7948(%rip), %xmm0    # 0xf40a0
callq 0x8b58a
leaq 0x88(%rsp), %rdi
movsd 0xc794b(%rip), %xmm0    # 0xf40b8
callq 0x8b58a
movq 0x140(%rsp), %rdx
xorpd %xmm0, %xmm0
leaq 0x50(%rsp), %rdi
movapd %xmm0, (%rdi)
movabsq $-0x100000000, %rax     # imm = 0xFFFFFFFF00000000
movq %rax, 0x10(%rdi)
movupd %xmm0, 0x18(%rdi)
xorl %eax, %eax
movq %rax, 0x28(%rdi)
movl $0x1, 0x30(%rdi)
movslq %ebp, %rcx
movq %rax, (%rdx,%rcx,8)
xorps %xmm0, %xmm0
cvtsi2sd %ecx, %xmm0
movq 0x210(%rsp), %rax
movsd %xmm0, (%rax,%rcx,8)
movl %ecx, %eax
movq %rdx, 0x20(%rsp)
leaq (%rdx,%rax,8), %rsi
callq 0x2db9c
movl %ebp, 0x14(%rsp)
movq %r14, 0x28(%rsp)
movq %rbx, 0x30(%rsp)
cmpl $0x0, 0x58(%rsp)
je 0x2c973
leaq 0x50(%rsp), %rdi
callq 0x2dc98
movq %rax, %rcx
subq 0x20(%rsp), %rcx
shrq $0x3, %rcx
movl %ecx, %eax
cltd
idivl 0xc8(%r12)
movl %eax, %ebx
movl %edx, 0x18(%rsp)
movq %rcx, 0x8(%rsp)
movslq %ecx, %rcx
movq %rcx, 0x48(%rsp)
xorps %xmm0, %xmm0
cvtsi2sd %ecx, %xmm0
movsd %xmm0, 0x38(%rsp)
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
movl %ebp, %r14d
addl 0x18(%rsp), %r14d
js 0x2c95b
cmpl 0xc0(%r12), %r14d
jge 0x2c95b
movl %ebp, %eax
imull %ebp, %eax
movl %eax, 0x1c(%rsp)
movl $0xffffffff, %r15d      # imm = 0xFFFFFFFF
movl %ebx, %eax
addl %r15d, %eax
js 0x2c94e
cmpl 0xc4(%r12), %eax
jge 0x2c94e
imull 0xc8(%r12), %eax
addl %r14d, %eax
cmpl 0x8(%rsp), %eax
je 0x2c94e
movq 0xb8(%r12), %rcx
movslq %eax, %r13
movsd (%rcx,%r13,8), %xmm0
ucomisd 0xc77fc(%rip), %xmm0    # 0xf40a0
jne 0x2c8ac
jnp 0x2c94e
movq 0x140(%rsp), %rax
movq 0x48(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm1
movl %r15d, %eax
imull %r15d, %eax
addl 0x1c(%rsp), %eax
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
ucomisd 0xc77d0(%rip), %xmm0    # 0xf40a8
jb 0x2c8e0
sqrtsd %xmm0, %xmm0
jmp 0x2c8f1
movsd %xmm1, 0x40(%rsp)
callq 0x22680
movsd 0x40(%rsp), %xmm1
addsd %xmm0, %xmm1
movq 0x140(%rsp), %rax
movsd (%rax,%r13,8), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x2c94e
movsd %xmm1, (%rax,%r13,8)
movq 0x210(%rsp), %rax
movsd 0x38(%rsp), %xmm1
movsd %xmm1, (%rax,%r13,8)
ucomisd 0xc778d(%rip), %xmm0    # 0xf40b8
movq 0x20(%rsp), %rax
leaq (%rax,%r13,8), %rsi
jne 0x2c944
jp 0x2c944
leaq 0x50(%rsp), %rdi
callq 0x2db9c
jmp 0x2c94e
leaq 0x50(%rsp), %rdi
callq 0x2dd32
incl %r15d
cmpl $0x2, %r15d
jne 0x2c85c
incl %ebp
cmpl $0x2, %ebp
jne 0x2c831
cmpl $0x0, 0x58(%rsp)
jne 0x2c7eb
jmp 0x2c97d
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movq %rax, 0x8(%rsp)
movq 0x28(%rsp), %r10
testq %r10, %r10
sete %al
movq 0x30(%rsp), %r9
testq %r9, %r9
sete %cl
orb %al, %cl
movq 0x8(%rsp), %rbx
jne 0x2ca13
movl %ebx, (%r10)
movl 0x14(%rsp), %r8d
cmpl %r8d, %ebx
jne 0x2c9b2
movl $0x1, %eax
xorl %ecx, %ecx
jmp 0x2c9e8
movl $0x1, %eax
movq 0x210(%rsp), %rdx
xorl %ecx, %ecx
movabsq $0x100000000, %rsi      # imm = 0x100000000
movl %ebx, %edi
movslq %edi, %rdi
cvttsd2si (%rdx,%rdi,8), %edi
addq %rsi, %rcx
movl %edi, (%r10,%rax,4)
incq %rax
cmpl %r8d, %edi
jne 0x2c9cd
sarq $0x20, %rcx
cmpl $0x2, %eax
jb 0x2ca10
movl %eax, %edx
shrl %edx
leaq (%r10,%rcx,4), %rcx
xorl %esi, %esi
movl (%r10,%rsi,4), %edi
movl (%rcx), %r8d
movl %r8d, (%r10,%rsi,4)
movl %edi, (%rcx)
incq %rsi
addq $-0x4, %rcx
cmpq %rsi, %rdx
jne 0x2c9f7
movl %eax, (%r9)
movq 0x50(%rsp), %rdi
testq %rdi, %rdi
je 0x2ca22
callq 0x22c00
leaq 0x88(%rsp), %rdi
callq 0x89ff8
leaq 0x158(%rsp), %rdi
callq 0x89ff8
movl %ebx, %eax
addq $0x228, %rsp            # imm = 0x228
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x2ca5e
movq %rax, %rbx
jmp 0x2ca7d
movq %rax, %rbx
jmp 0x2ca70
jmp 0x2ca5e
movq %rax, %rbx
movq 0x50(%rsp), %rdi
testq %rdi, %rdi
je 0x2ca70
callq 0x22c00
leaq 0x88(%rsp), %rdi
callq 0x89ff8
leaq 0x158(%rsp), %rdi
callq 0x89ff8
movq %rbx, %rdi
callq 0x230a0