// File: IHorvalds[P]RomAna/./processing/InflexEngineUtil.cpp
// Function: InflexEngine::InflexEngine(InflexEngine::Mode, char const*, char const*)
InflexEngine::InflexEngine(Mode generationMode, const char* filename, const char* latinFilename) : generationMode(generationMode) {
  // Initialize the auxiliar InflexEngine
  auxTrieSize = 0, auxTrie = nullptr;
  
  switch (generationMode) {
    // Simple initialization
    case Read : {
      // Necessary when deallocating
      bufferLastPtr = 0;
      break;
    }
    // Load from external binary file
    case Load : {
      loadExternal(filename);
      break;
    }
    // Build up the InflexEngine from the file with inflections
    case Build : {
      // Compute properties of the namespace
      size = SIZE;
      sigma = romanian::ROMANIAN_SIGMA;
      assert(sigma <= MAX_ACCEPTED_SIGMA);
      
      // Pay attention to the right shift when sigma == MAX_ACCEPTED_SIGMA
      fullBits = (sigma == MAX_ACCEPTED_SIGMA) ? 0xffffffff : ((1u << sigma) - 1);
      
      // Alloc staticTrie
      bufferLastPtr = 0;
      staticTrie = new InflexEngineNode[size];
      for (unsigned index = 0; index < size; index++) {
        staticTrie[index].code = 0;
        staticTrie[index].parent = 0;
        staticTrie[index].sons = new uint32_t[sigma]();
        staticTrie[index].configuration = fullBits;
      }
      
      // And consume the inflexions
      consumeInflexions(filename, latinFilename);
      break;
    }
    default : {
      std::cerr << "Mode of InflexEngine does not (yet) exist." << std::endl;
    }
  }
}

// Assembly:
subq $0x88, %rsp
movq %rdi, 0x80(%rsp)
movl %esi, 0x7c(%rsp)
movq %rdx, 0x70(%rsp)
movq %rcx, 0x68(%rsp)
movq 0x80(%rsp), %rax
movq %rax, 0x48(%rsp)
movl 0x7c(%rsp), %ecx
movl %ecx, (%rax)
movl $0x0, 0x1c(%rax)
movq $0x0, 0x10(%rax)
movl 0x7c(%rsp), %eax
movl %eax, 0x54(%rsp)
testl %eax, %eax
je 0x6176
jmp 0x615d
movl 0x54(%rsp), %eax
subl $0x1, %eax
je 0x6187
jmp 0x6168
movl 0x54(%rsp), %eax
subl $0x2, %eax
je 0x619b
jmp 0x63a6
movq 0x48(%rsp), %rax
movl $0x0, 0x28(%rax)
jmp 0x63c8
movq 0x48(%rsp), %rdi
movq 0x70(%rsp), %rsi
callq 0x63e0
jmp 0x63c8
movq 0x48(%rsp), %rax
movl $0x2625a0, 0x18(%rax)   # imm = 0x2625A0
movl $0x1f, 0x20(%rax)
cmpl $0x20, 0x20(%rax)
ja 0x61b6
jmp 0x61d5
leaq 0xee96(%rip), %rdi      # 0x15053
leaq 0xeeab(%rip), %rsi      # 0x1506f
movl $0x1f, %edx
leaq 0xeec1(%rip), %rcx      # 0x15091
callq 0x4230
movq 0x48(%rsp), %rax
cmpl $0x20, 0x20(%rax)
jne 0x61eb
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movl %eax, 0x44(%rsp)
jmp 0x6201
movq 0x48(%rsp), %rax
movl 0x20(%rax), %ecx
movl $0x1, %eax
shll %cl, %eax
subl $0x1, %eax
movl %eax, 0x44(%rsp)
movq 0x48(%rsp), %rax
movl 0x44(%rsp), %ecx
movl %ecx, 0x24(%rax)
movl $0x0, 0x28(%rax)
movl 0x18(%rax), %eax
movq %rax, 0x30(%rsp)
movl $0x14, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
movq %rdi, 0x28(%rsp)
callq 0x4030
movq %rax, %rcx
movq 0x30(%rsp), %rax
movq %rcx, 0x38(%rsp)
cmpq $0x0, %rax
je 0x629c
movq 0x38(%rsp), %rax
movq 0x30(%rsp), %rcx
imulq $0x14, %rcx, %rdx
movq %rax, %rcx
addq %rdx, %rcx
movq %rcx, 0x18(%rsp)
movq %rax, 0x20(%rsp)
movq 0x20(%rsp), %rdi
movq %rdi, 0x10(%rsp)
callq 0xae60
jmp 0x6284
movq 0x18(%rsp), %rcx
movq 0x10(%rsp), %rax
addq $0x14, %rax
cmpq %rcx, %rax
movq %rax, 0x20(%rsp)
jne 0x6273
movq 0x48(%rsp), %rax
movq 0x38(%rsp), %rcx
movq %rcx, 0x8(%rax)
movl $0x0, 0x58(%rsp)
movq 0x48(%rsp), %rcx
movl 0x58(%rsp), %eax
cmpl 0x18(%rcx), %eax
jae 0x6390
movq 0x48(%rsp), %rax
movq 0x8(%rax), %rcx
movl 0x58(%rsp), %edx
imulq $0x14, %rdx, %rdx
addq %rdx, %rcx
movl $0x0, (%rcx)
movq 0x8(%rax), %rcx
movl 0x58(%rsp), %edx
imulq $0x14, %rdx, %rdx
addq %rdx, %rcx
movl $0x0, 0x4(%rcx)
movl 0x20(%rax), %eax
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
movq %rdi, (%rsp)
callq 0x4030
movq (%rsp), %rdx
movq %rax, %rdi
movq %rdi, 0x8(%rsp)
xorl %esi, %esi
callq 0x41b0
movq 0x8(%rsp), %rdx
movq 0x48(%rsp), %rax
movq 0x8(%rax), %rcx
movl 0x58(%rsp), %esi
imulq $0x14, %rsi, %rsi
addq %rsi, %rcx
movq %rdx, 0xc(%rcx)
movl 0x24(%rax), %ecx
movq 0x8(%rax), %rax
movl 0x58(%rsp), %edx
imulq $0x14, %rdx, %rdx
addq %rdx, %rax
movl %ecx, 0x8(%rax)
movl 0x58(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x58(%rsp)
jmp 0x62b2
movq 0x28(%rsp), %rsi
movq 0x38(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x60(%rsp)
movl %eax, 0x5c(%rsp)
callq 0x4690
jmp 0x63d0
movq 0x48(%rsp), %rdi
movq 0x70(%rsp), %rsi
movq 0x68(%rsp), %rdx
callq 0x66b0
jmp 0x63c8
movq 0x15c43(%rip), %rdi     # 0x1bff0
leaq 0xed1a(%rip), %rsi      # 0x150ce
callq 0x4330
movq %rax, %rdi
movq 0x15be5(%rip), %rsi     # 0x1bfa8
callq 0x4380
addq $0x88, %rsp
retq
movq 0x60(%rsp), %rdi
callq 0x4620
nopw (%rax,%rax)