// File: Ahhgust[P]STRaitRazor/trie.cpp
// Function: Trie::addPermutations(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, unsigned int, unsigned int, unsigned char, unsigned char, unsigned char)
void
Trie::addPermutations(string w, unsigned wordLen, unsigned id, unsigned char type1, unsigned char type2, unsigned char distance) {


  unsigned i, j;
  char letter, l1, l2;

  addWord(w.c_str(), wordLen, id, type1);
  addWordRC(w.c_str(), wordLen, id, type2);


  if (distance > 0) {
  // this does all of the (3*kmer.len) single-base substitution permutations
  // and adds them to the vector
    for (i=0; i < wordLen; ++i) {
      
      letter = w[i];
      
      if (letter != 'A') {
        w[i] = 'A';
        addWord(w.c_str(), wordLen, id, type1);
        addWordRC(w.c_str(), wordLen, id, type2);
      }
      if (letter != 'C') {
        w[i] = 'C';
        addWord(w.c_str(), wordLen, id, type1);
        addWordRC(w.c_str(), wordLen, id, type2);
      }
      if (letter != 'G') {
        w[i] = 'G';
        addWord(w.c_str(), wordLen, id, type1);
        addWordRC(w.c_str(), wordLen, id, type2);
      }
      if (letter != 'T') {
        w[i] = 'T';
        addWord(w.c_str(), wordLen, id, type1);
        addWordRC(w.c_str(), wordLen, id, type2);
      }
      // undo the substitution at base position i
      w[i] = letter;
    }
  } 

  if (distance > 1) { // all of the two-base substitutions as well

    char LETTERS[4] = {'A','C','G','T'};
    
    // every single pair of positions
    for (i=0; i < wordLen; ++i) {
      l1 = w[i];
      for (j=i+1; j < wordLen; ++j) {
        l2 = w[j];

	// every single pair of base pair changes
        unsigned char a, b;
        for (a=0; a < 4; ++a) {
          for (b=0; b < 4; ++b) {
            if (LETTERS[a] != l1 && LETTERS[b] != l2) { // make sure what we're adding is unique
              w[i] = LETTERS[a];
              w[j] = LETTERS[b];

              addWord(w.c_str(), wordLen, id, type1);
              addWordRC(w.c_str(), wordLen, id, type2);
              w[i] = l1;
              w[j] = l2;

            }
          }
        }
      }
    }
    

  }

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movl %r8d, -0x4c(%rbp)
movl %ecx, %eax
movl -0x4c(%rbp), %ecx
movl %eax, -0x48(%rbp)
movl %edx, %eax
movl -0x48(%rbp), %edx
movl %eax, -0x44(%rbp)
movq %rsi, %rax
movl -0x44(%rbp), %esi
movq %rax, -0x40(%rbp)
movq %rdi, %r8
movq -0x40(%rbp), %rdi
movb %r9b, %al
movb 0x10(%rbp), %r9b
movq %r8, -0x8(%rbp)
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movb %cl, -0x19(%rbp)
movb %al, -0x1a(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x38(%rbp)
callq 0x3100
movq -0x38(%rbp), %rdi
movq %rax, %rsi
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
movzbl -0x19(%rbp), %r8d
callq 0x117f0
movq -0x40(%rbp), %rdi
callq 0x3100
movq -0x38(%rbp), %rdi
movq %rax, %rsi
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
movzbl -0x1a(%rbp), %r8d
callq 0x11a60
movzbl 0x10(%rbp), %eax
cmpl $0x0, %eax
jle 0x11fd0
movl $0x0, -0x20(%rbp)
movl -0x20(%rbp), %eax
cmpl -0x14(%rbp), %eax
jae 0x11fce
movq -0x40(%rbp), %rdi
movl -0x20(%rbp), %eax
movl %eax, %esi
callq 0x3520
movb (%rax), %al
movb %al, -0x25(%rbp)
movsbl -0x25(%rbp), %eax
cmpl $0x41, %eax
je 0x11e99
movq -0x40(%rbp), %rdi
movl -0x20(%rbp), %eax
movl %eax, %esi
callq 0x3520
movq -0x40(%rbp), %rdi
movb $0x41, (%rax)
callq 0x3100
movq -0x38(%rbp), %rdi
movq %rax, %rsi
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
movzbl -0x19(%rbp), %r8d
callq 0x117f0
movq -0x40(%rbp), %rdi
callq 0x3100
movq -0x38(%rbp), %rdi
movq %rax, %rsi
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
movzbl -0x1a(%rbp), %r8d
callq 0x11a60
movsbl -0x25(%rbp), %eax
cmpl $0x43, %eax
je 0x11ef3
movq -0x40(%rbp), %rdi
movl -0x20(%rbp), %eax
movl %eax, %esi
callq 0x3520
movq -0x40(%rbp), %rdi
movb $0x43, (%rax)
callq 0x3100
movq -0x38(%rbp), %rdi
movq %rax, %rsi
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
movzbl -0x19(%rbp), %r8d
callq 0x117f0
movq -0x40(%rbp), %rdi
callq 0x3100
movq -0x38(%rbp), %rdi
movq %rax, %rsi
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
movzbl -0x1a(%rbp), %r8d
callq 0x11a60
movsbl -0x25(%rbp), %eax
cmpl $0x47, %eax
je 0x11f4d
movq -0x40(%rbp), %rdi
movl -0x20(%rbp), %eax
movl %eax, %esi
callq 0x3520
movq -0x40(%rbp), %rdi
movb $0x47, (%rax)
callq 0x3100
movq -0x38(%rbp), %rdi
movq %rax, %rsi
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
movzbl -0x19(%rbp), %r8d
callq 0x117f0
movq -0x40(%rbp), %rdi
callq 0x3100
movq -0x38(%rbp), %rdi
movq %rax, %rsi
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
movzbl -0x1a(%rbp), %r8d
callq 0x11a60
movsbl -0x25(%rbp), %eax
cmpl $0x54, %eax
je 0x11fa7
movq -0x40(%rbp), %rdi
movl -0x20(%rbp), %eax
movl %eax, %esi
callq 0x3520
movq -0x40(%rbp), %rdi
movb $0x54, (%rax)
callq 0x3100
movq -0x38(%rbp), %rdi
movq %rax, %rsi
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
movzbl -0x19(%rbp), %r8d
callq 0x117f0
movq -0x40(%rbp), %rdi
callq 0x3100
movq -0x38(%rbp), %rdi
movq %rax, %rsi
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
movzbl -0x1a(%rbp), %r8d
callq 0x11a60
movq -0x40(%rbp), %rdi
movb -0x25(%rbp), %al
movb %al, -0x4d(%rbp)
movl -0x20(%rbp), %eax
movl %eax, %esi
callq 0x3520
movb -0x4d(%rbp), %cl
movb %cl, (%rax)
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20(%rbp)
jmp 0x11e20
jmp 0x11fd0
movzbl 0x10(%rbp), %eax
cmpl $0x1, %eax
jle 0x1216e
movl 0x2e3f(%rip), %eax      # 0x14e22
movl %eax, -0x2b(%rbp)
movl $0x0, -0x20(%rbp)
movl -0x20(%rbp), %eax
cmpl -0x14(%rbp), %eax
jae 0x1216c
movq -0x40(%rbp), %rdi
movl -0x20(%rbp), %eax
movl %eax, %esi
callq 0x3520
movb (%rax), %al
movb %al, -0x26(%rbp)
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %eax
cmpl -0x14(%rbp), %eax
jae 0x1215c
movq -0x40(%rbp), %rdi
movl -0x24(%rbp), %eax
movl %eax, %esi
callq 0x3520
movb (%rax), %al
movb %al, -0x27(%rbp)
movb $0x0, -0x2c(%rbp)
movzbl -0x2c(%rbp), %eax
cmpl $0x4, %eax
jge 0x1214c
movb $0x0, -0x2d(%rbp)
movzbl -0x2d(%rbp), %eax
cmpl $0x4, %eax
jge 0x1213d
movzbl -0x2c(%rbp), %eax
movsbl -0x2b(%rbp,%rax), %eax
movsbl -0x26(%rbp), %ecx
cmpl %ecx, %eax
je 0x1212e
movzbl -0x2d(%rbp), %eax
movsbl -0x2b(%rbp,%rax), %eax
movsbl -0x27(%rbp), %ecx
cmpl %ecx, %eax
je 0x1212e
movq -0x40(%rbp), %rdi
movzbl -0x2c(%rbp), %eax
movb -0x2b(%rbp,%rax), %al
movb %al, -0x51(%rbp)
movl -0x20(%rbp), %eax
movl %eax, %esi
callq 0x3520
movb -0x51(%rbp), %cl
movq -0x40(%rbp), %rdi
movb %cl, (%rax)
movzbl -0x2d(%rbp), %eax
movb -0x2b(%rbp,%rax), %al
movb %al, -0x50(%rbp)
movl -0x24(%rbp), %eax
movl %eax, %esi
callq 0x3520
movb -0x50(%rbp), %cl
movq -0x40(%rbp), %rdi
movb %cl, (%rax)
callq 0x3100
movq -0x38(%rbp), %rdi
movq %rax, %rsi
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
movzbl -0x19(%rbp), %r8d
callq 0x117f0
movq -0x40(%rbp), %rdi
callq 0x3100
movq -0x38(%rbp), %rdi
movq %rax, %rsi
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
movzbl -0x1a(%rbp), %r8d
callq 0x11a60
movq -0x40(%rbp), %rdi
movb -0x26(%rbp), %al
movb %al, -0x4f(%rbp)
movl -0x20(%rbp), %eax
movl %eax, %esi
callq 0x3520
movb -0x4f(%rbp), %cl
movq -0x40(%rbp), %rdi
movb %cl, (%rax)
movb -0x27(%rbp), %al
movb %al, -0x4e(%rbp)
movl -0x24(%rbp), %eax
movl %eax, %esi
callq 0x3520
movb -0x4e(%rbp), %cl
movb %cl, (%rax)
jmp 0x12130
movb -0x2d(%rbp), %al
addb $0x1, %al
movb %al, -0x2d(%rbp)
jmp 0x12049
jmp 0x1213f
movb -0x2c(%rbp), %al
addb $0x1, %al
movb %al, -0x2c(%rbp)
jmp 0x12038
jmp 0x1214e
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x12015
jmp 0x1215e
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20(%rbp)
jmp 0x11fed
jmp 0x1216e
addq $0x60, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)