// File: /workspace/github_cpp_makefile_star2_O1/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movl %r9d, %r13d
movl %r8d, %r12d
movl %ecx, %ebx
movl %edx, %ebp
movq %rsi, %r14
movq %rdi, %r15
movq (%rsi), %rsi
callq 0x9a98
movq (%r14), %rsi
movq %r15, %rdi
movl %ebp, %edx
movl %ebx, %ecx
movl %r13d, %r8d
callq 0x9c18
cmpb $0x0, 0x90(%rsp)
sete %al
testl %ebp, %ebp
sete %cl
orb %al, %cl
movl %ebp, %eax
movzbl %r12b, %ecx
movq %rax, %r12
movzbl %r13b, %eax
movl %eax, 0x24(%rsp)
movl %ecx, 0xc(%rsp)
jne 0x9f92
xorl %edx, %edx
movl 0x24(%rsp), %r13d
movq (%r14), %rax
movb (%rax,%rdx), %cl
movb %cl, 0x18(%rsp)
cmpb $0x41, %cl
movq %rdx, 0x10(%rsp)
je 0x9ed2
movb $0x41, (%rax,%rdx)
movq (%r14), %rsi
movq %r15, %rdi
movl %ebp, %edx
movl %ebx, %ecx
movl 0xc(%rsp), %r8d
callq 0x9a98
movq (%r14), %rsi
movq %r15, %rdi
movl %ebp, %edx
movl %ebx, %ecx
movl %r13d, %r8d
callq 0x9c18
movq 0x10(%rsp), %rdx
cmpb $0x43, 0x18(%rsp)
je 0x9f0b
movq (%r14), %rax
movb $0x43, (%rax,%rdx)
movq (%r14), %rsi
movq %r15, %rdi
movl %ebp, %edx
movl %ebx, %ecx
movl 0xc(%rsp), %r8d
callq 0x9a98
movq (%r14), %rsi
movq %r15, %rdi
movl %ebp, %edx
movl %ebx, %ecx
movl %r13d, %r8d
callq 0x9c18
movq 0x10(%rsp), %rdx
cmpb $0x47, 0x18(%rsp)
je 0x9f48
movq (%r14), %rax
movb $0x47, (%rax,%rdx)
movq (%r14), %rsi
movq %r15, %rdi
movl %ebp, %edx
movl %ebx, %ecx
movl 0xc(%rsp), %r8d
callq 0x9a98
movq (%r14), %rsi
movq %r15, %rdi
movl %ebp, %edx
movl %ebx, %ecx
movl %r13d, %r8d
callq 0x9c18
movb 0x18(%rsp), %sil
movq 0x10(%rsp), %rdx
cmpb $0x54, %sil
je 0x9f7f
movq (%r14), %rax
movb $0x54, (%rax,%rdx)
movq (%r14), %rsi
movq %r15, %rdi
movl %ebp, %edx
movl %ebx, %ecx
movl 0xc(%rsp), %r8d
callq 0x9a98
movq (%r14), %rsi
movq %r15, %rdi
movl %ebp, %edx
movl %ebx, %ecx
movl %r13d, %r8d
callq 0x9c18
movb 0x18(%rsp), %sil
movq 0x10(%rsp), %rdx
movq (%r14), %rax
movb %sil, (%rax,%rdx)
incq %rdx
cmpq %rdx, %r12
jne 0x9e88
movq %r15, 0x50(%rsp)
movl %ebx, 0x2c(%rsp)
cmpb $0x2, 0x90(%rsp)
setb %al
testl %ebp, %ebp
sete %cl
orb %al, %cl
jne 0xa0e5
movl $0x1, %eax
movq %rax, 0x30(%rsp)
xorl %eax, %eax
leaq 0x1f0a(%rip), %rcx      # 0xbed0
movl %ebp, 0x28(%rsp)
movq %r12, 0x38(%rsp)
movq 0x50(%rsp), %rbx
movq %rax, 0x10(%rsp)
incq %rax
movq %rax, 0x40(%rsp)
cmpq %r12, %rax
jae 0xa0cd
movq (%r14), %rax
movq 0x10(%rsp), %rdx
movb (%rax,%rdx), %dl
movq 0x30(%rsp), %rsi
movb %dl, 0xa(%rsp)
movq (%r14), %rax
movb (%rax,%rsi), %dil
xorl %eax, %eax
movq %rsi, 0x18(%rsp)
movb %dil, 0xb(%rsp)
movq %rax, 0x48(%rsp)
movb (%rax,%rcx), %r12b
xorl %r13d, %r13d
cmpb %dl, %r12b
je 0xa09f
movb (%r13,%rcx), %al
cmpb %dil, %al
je 0xa09f
movq (%r14), %rcx
movq 0x10(%rsp), %r8
movb %r12b, (%rcx,%r8)
movq (%r14), %rcx
movb %al, (%rcx,%rsi)
movq (%r14), %rsi
movq %rbx, %rdi
movq %r14, %r15
movl 0x28(%rsp), %r14d
movl %r14d, %edx
movl 0x2c(%rsp), %ebp
movl %ebp, %ecx
movl 0xc(%rsp), %r8d
callq 0x9a98
movq (%r15), %rsi
movq %rbx, %rdi
movl %r14d, %edx
movq %r15, %r14
movl %ebp, %ecx
movl 0x24(%rsp), %r8d
callq 0x9c18
movb 0xb(%rsp), %dil
movq 0x18(%rsp), %rsi
movb 0xa(%rsp), %dl
leaq 0x1e44(%rip), %rcx      # 0xbed0
movq (%r15), %rax
movq 0x10(%rsp), %r8
movb %dl, (%rax,%r8)
movq (%r15), %rax
movb %dil, (%rax,%rsi)
incq %r13
cmpq $0x4, %r13
jne 0xa01d
movq 0x48(%rsp), %rax
incq %rax
cmpq $0x4, %rax
jne 0xa011
incq %rsi
movl 0x28(%rsp), %ebp
cmpl %ebp, %esi
jne 0x9ffe
incq 0x30(%rsp)
movq 0x38(%rsp), %r12
movq 0x40(%rsp), %rax
cmpq %r12, %rax
jne 0x9fd4
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq