// File: Luthaf[P]zeopp/networkstorage.cc
// Function: parse_edge(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>*, int, ATOM_NETWORK*, int, bool)
void parse_edge(vector<string> *token, int first_index, ATOM_NETWORK *cell, int atom_index, bool uses_node) {
  bool verbose = false;
  if(!uses_node) {
    printf("NET ERROR: parsed unexpected \"edge\" field, when edges where expected to be provided with atoms\n");
    exit(EXIT_FAILURE);
  }
  XYZ start(convertToDouble(token->at(first_index+0)), convertToDouble(token->at(first_index+1)), convertToDouble(token->at(first_index+2)));
  XYZ start_xyz = cell->abc_to_xyz_returning_XYZ(start);
  XYZ end(convertToDouble(token->at(first_index+3)), convertToDouble(token->at(first_index+4)), convertToDouble(token->at(first_index+5)));
  XYZ end_xyz = cell->abc_to_xyz_returning_XYZ(end);
  //1) detect which vertex it starts at
  int v_index = -1;
  for(int i=0; i<atom_index && v_index==-1; i++) {
    if((start_xyz-cell->abc_to_xyz_returning_XYZ(cell->vertices.at(i).abc)).magnitude()<DISTANCE_TOLERANCE) { //match to parsed vertex
      v_index = i;
    }
  }
  if(v_index==-1) {
    printf("NET ERROR: could not match this edge start position to a previously parsed vertex\n");
    exit(EXIT_FAILURE);
  }
  //2) update the cell accordingly
  cell->vertices.at(v_index).edges.push_back(end);
  if(verbose) printf("parsed edge assigned to vertex %d at %.3f %.3f %.3f\n", v_index+1, end.x, end.y, end.z);
  //3) detect which vertex it ends at
  v_index = -1;
  for(int i=0; i<atom_index && v_index==-1; i++) {
    if((end_xyz-cell->abc_to_xyz_returning_XYZ(cell->vertices.at(i).abc)).magnitude()<DISTANCE_TOLERANCE) { //match to parsed vertex
      v_index = i;
    }
  }
  if(v_index==-1) {
/*
    printf("ERROR: could not match this edge end position to a previously parsed vertex\n");
    exit(EXIT_FAILURE);
*/
    if(verbose) printf("DEBUG: could not match this edge end position to a previously parsed vertex - creating an orphan edge to temporarily store this start/end until its true position by symmetry is known\n");
    //this is a specific scenario - the cgd file contains a definition of an edge, for which the end point is not a basic vertex - normally this is the default case, but for this cgd format the edges are not given exhaustively and so we need to know of each edge in both directions in order to construct the complete net including symmetry operations upon these edges
    //accordingly, we need to store this orphan edge, by saving its start and end in the cell as an orphan - this vertex is the symmetry image of some basic vertex, and we will assign this orphaned edge to that vertex when we know it
    cell->orphan_edge_starts.push_back(end);
    cell->orphan_edge_ends.push_back(start);
  } else {
    //4) update the cell accordingly
    cell->vertices.at(v_index).edges.push_back(start);
    if(verbose) printf("parsed edge assigned to vertex %d at %.3f %.3f %.3f\n", v_index+1, start.x, start.y, start.z);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x130, %rsp            # imm = 0x130
movb %r8b, %al
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq %rdx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
andb $0x1, %al
movb %al, -0x1d(%rbp)
movb $0x0, -0x1e(%rbp)
testb $0x1, -0x1d(%rbp)
jne 0xa8513
leaq 0x151539(%rip), %rdi    # 0x1f9a3b
movb $0x0, %al
callq 0x5070
movl $0x1, %edi
callq 0x67c0
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %eax
addl $0x0, %eax
movslq %eax, %rsi
callq 0xaf450
movq %rax, %rdi
callq 0x8a8a0
movsd %xmm0, -0x108(%rbp)
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rsi
callq 0xaf450
movq %rax, %rdi
callq 0x8a8a0
movsd %xmm0, -0x110(%rbp)
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %eax
addl $0x2, %eax
movslq %eax, %rsi
callq 0xaf450
movq %rax, %rdi
callq 0x8a8a0
movsd -0x110(%rbp), %xmm1
movaps %xmm0, %xmm2
movsd -0x108(%rbp), %xmm0
leaq -0x38(%rbp), %rdi
callq 0xea8e0
movq -0x18(%rbp), %rsi
leaq -0x50(%rbp), %rdi
leaq -0x38(%rbp), %rdx
callq 0x97310
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %eax
addl $0x3, %eax
movslq %eax, %rsi
callq 0xaf450
movq %rax, %rdi
callq 0x8a8a0
movsd %xmm0, -0xf8(%rbp)
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %eax
addl $0x4, %eax
movslq %eax, %rsi
callq 0xaf450
movq %rax, %rdi
callq 0x8a8a0
movsd %xmm0, -0x100(%rbp)
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %eax
addl $0x5, %eax
movslq %eax, %rsi
callq 0xaf450
movq %rax, %rdi
callq 0x8a8a0
movsd -0x100(%rbp), %xmm1
movaps %xmm0, %xmm2
movsd -0xf8(%rbp), %xmm0
leaq -0x68(%rbp), %rdi
callq 0xea8e0
movq -0x18(%rbp), %rsi
leaq -0x80(%rbp), %rdi
leaq -0x68(%rbp), %rdx
callq 0x97310
movl $0xffffffff, -0x84(%rbp) # imm = 0xFFFFFFFF
movl $0x0, -0x88(%rbp)
movl -0x88(%rbp), %ecx
xorl %eax, %eax
cmpl -0x1c(%rbp), %ecx
movb %al, -0x111(%rbp)
jge 0xa8660
cmpl $-0x1, -0x84(%rbp)
sete %al
movb %al, -0x111(%rbp)
movb -0x111(%rbp), %al
testb $0x1, %al
jne 0xa866f
jmp 0xa86fd
movq -0x18(%rbp), %rax
movq %rax, -0x120(%rbp)
movq -0x18(%rbp), %rdi
addq $0x3c0, %rdi            # imm = 0x3C0
movslq -0x88(%rbp), %rsi
callq 0xae4a0
movq -0x120(%rbp), %rsi
movq %rax, %rdx
leaq -0xb8(%rbp), %rdi
callq 0x97310
leaq -0xa0(%rbp), %rdi
leaq -0x50(%rbp), %rsi
leaq -0xb8(%rbp), %rdx
callq 0xeadf0
leaq -0xa0(%rbp), %rdi
callq 0xe9240
movaps %xmm0, %xmm1
movsd 0x14f193(%rip), %xmm0   # 0x1f7868
ucomisd %xmm1, %xmm0
jbe 0xa86e7
movl -0x88(%rbp), %eax
movl %eax, -0x84(%rbp)
jmp 0xa86e9
movl -0x88(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x88(%rbp)
jmp 0xa863d
cmpl $-0x1, -0x84(%rbp)
jne 0xa871e
leaq 0x15138e(%rip), %rdi    # 0x1f9a9b
movb $0x0, %al
callq 0x5070
movl $0x1, %edi
callq 0x67c0
movq -0x18(%rbp), %rdi
addq $0x3c0, %rdi            # imm = 0x3C0
movslq -0x84(%rbp), %rsi
callq 0xae4a0
movq %rax, %rdi
addq $0x20, %rdi
leaq -0x68(%rbp), %rsi
callq 0xafc20
testb $0x1, -0x1e(%rbp)
je 0xa8771
movl -0x84(%rbp), %esi
addl $0x1, %esi
movsd -0x68(%rbp), %xmm0
movsd -0x60(%rbp), %xmm1
movsd -0x58(%rbp), %xmm2
leaq 0x151384(%rip), %rdi    # 0x1f9aee
movb $0x3, %al
callq 0x5070
movl $0xffffffff, -0x84(%rbp) # imm = 0xFFFFFFFF
movl $0x0, -0xbc(%rbp)
movl -0xbc(%rbp), %ecx
xorl %eax, %eax
cmpl -0x1c(%rbp), %ecx
movb %al, -0x121(%rbp)
jge 0xa87a8
cmpl $-0x1, -0x84(%rbp)
sete %al
movb %al, -0x121(%rbp)
movb -0x121(%rbp), %al
testb $0x1, %al
jne 0xa87b7
jmp 0xa8845
movq -0x18(%rbp), %rax
movq %rax, -0x130(%rbp)
movq -0x18(%rbp), %rdi
addq $0x3c0, %rdi            # imm = 0x3C0
movslq -0xbc(%rbp), %rsi
callq 0xae4a0
movq -0x130(%rbp), %rsi
movq %rax, %rdx
leaq -0xf0(%rbp), %rdi
callq 0x97310
leaq -0xd8(%rbp), %rdi
leaq -0x80(%rbp), %rsi
leaq -0xf0(%rbp), %rdx
callq 0xeadf0
leaq -0xd8(%rbp), %rdi
callq 0xe9240
movaps %xmm0, %xmm1
movsd 0x14f04b(%rip), %xmm0   # 0x1f7868
ucomisd %xmm1, %xmm0
jbe 0xa882f
movl -0xbc(%rbp), %eax
movl %eax, -0x84(%rbp)
jmp 0xa8831
movl -0xbc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xbc(%rbp)
jmp 0xa8785
cmpl $-0x1, -0x84(%rbp)
jne 0xa888c
testb $0x1, -0x1e(%rbp)
je 0xa8862
leaq 0x1512c8(%rip), %rdi    # 0x1f9b23
movb $0x0, %al
callq 0x5070
movq -0x18(%rbp), %rdi
addq $0x3d8, %rdi            # imm = 0x3D8
leaq -0x68(%rbp), %rsi
callq 0xafc20
movq -0x18(%rbp), %rdi
addq $0x3f0, %rdi            # imm = 0x3F0
leaq -0x38(%rbp), %rsi
callq 0xafc20
jmp 0xa88e1
movq -0x18(%rbp), %rdi
addq $0x3c0, %rdi            # imm = 0x3C0
movslq -0x84(%rbp), %rsi
callq 0xae4a0
movq %rax, %rdi
addq $0x20, %rdi
leaq -0x38(%rbp), %rsi
callq 0xafc20
testb $0x1, -0x1e(%rbp)
je 0xa88df
movl -0x84(%rbp), %esi
addl $0x1, %esi
movsd -0x38(%rbp), %xmm0
movsd -0x30(%rbp), %xmm1
movsd -0x28(%rbp), %xmm2
leaq 0x151216(%rip), %rdi    # 0x1f9aee
movb $0x3, %al
callq 0x5070
jmp 0xa88e1
addq $0x130, %rsp            # imm = 0x130
popq %rbp
retq
nopw (%rax,%rax)