// File: bowenfan96[P]icl-mcs-enigma/enigma.cpp
// Function: Enigma::encryptor(char)
char Enigma::encryptor(char letter) 
{
    // check input letter is upper case letter
    if(!isupper(letter)) {
        std::cerr << letter << " is not a valid input character (input characters must be upper case letters A-Z)!" << "\n";
        throw INVALID_INPUT_CHARACTER;
    }
    
    int input = letter - 'A';
    
    // send signal through Plugboard
    input = pb->mapper(input);
    
    // send signal through rotors, right to left
    if(num_rotors > 0) {
        turn_rotors();
        
        // use reverse iterator for right to left signal flow
        for(auto rot = vec_rotors.rbegin(); rot != vec_rotors.rend(); ++rot) {
            input = rot->mapper(input);
        }
    }
    
    // send signal through reflector
    input = rf->mapper(input);
    
    // reflect signal through rotors, left to right
    if(num_rotors > 0) {
        for(auto rot = vec_rotors.begin(); rot != vec_rotors.end(); ++rot) {
            input = rot->rf_mapper(input);
        }
    }
    
    // reflect signal through Plugboard
    input = pb->mapper(input);
    
    // cast int to corresponding letter
    char letter_out = (char)('A' + input);
    
    return letter_out;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movb %sil, %al
movq %rdi, -0x8(%rbp)
movb %al, -0x9(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x40(%rbp)
movsbl -0x9(%rbp), %edi
callq 0x2130
cmpl $0x0, %eax
jne 0x4fc9
movq 0xd071(%rip), %rdi      # 0x11ff0
movsbl -0x9(%rbp), %esi
callq 0x2220
movq %rax, %rdi
leaq 0x7476(%rip), %rsi      # 0xc408
callq 0x21d0
movq %rax, %rdi
leaq 0x70db(%rip), %rsi      # 0xc07c
callq 0x21d0
movl $0x4, %edi
callq 0x20b0
movq %rax, %rdi
movl $0x2, (%rdi)
movq 0xcfd0(%rip), %rsi      # 0x11f90
xorl %eax, %eax
movl %eax, %edx
callq 0x2310
movq -0x40(%rbp), %rax
movsbl -0x9(%rbp), %ecx
subl $0x41, %ecx
movl %ecx, -0x10(%rbp)
movq 0x38(%rax), %rdi
movl -0x10(%rbp), %esi
callq 0x31d0
movl %eax, %ecx
movq -0x40(%rbp), %rax
movl %ecx, -0x10(%rbp)
cmpl $0x0, (%rax)
jle 0x5053
movq -0x40(%rbp), %rdi
callq 0x50f0
movq -0x40(%rbp), %rsi
addq $0x8, %rsi
leaq -0x18(%rbp), %rdi
callq 0x5b80
movq -0x40(%rbp), %rsi
addq $0x8, %rsi
leaq -0x20(%rbp), %rdi
callq 0x5c00
leaq -0x18(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0x5bd0
testb $0x1, %al
jne 0x502f
jmp 0x5051
leaq -0x18(%rbp), %rdi
callq 0x5c50
movq %rax, %rdi
movl -0x10(%rbp), %esi
callq 0x3b90
movl %eax, -0x10(%rbp)
leaq -0x18(%rbp), %rdi
callq 0x5c90
jmp 0x500b
jmp 0x5053
movq -0x40(%rbp), %rax
movq 0x40(%rax), %rdi
movl -0x10(%rbp), %esi
callq 0x4530
movl %eax, %ecx
movq -0x40(%rbp), %rax
movl %ecx, -0x10(%rbp)
cmpl $0x0, (%rax)
jle 0x50ca
movq -0x40(%rbp), %rdi
addq $0x8, %rdi
callq 0x5cc0
movq %rax, -0x28(%rbp)
movq -0x40(%rbp), %rdi
addq $0x8, %rdi
callq 0x5d30
movq %rax, -0x30(%rbp)
leaq -0x28(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x5cf0
testb $0x1, %al
jne 0x50a6
jmp 0x50c8
leaq -0x28(%rbp), %rdi
callq 0x5d60
movq %rax, %rdi
movl -0x10(%rbp), %esi
callq 0x3c00
movl %eax, -0x10(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x5d80
jmp 0x5082
jmp 0x50ca
movq -0x40(%rbp), %rax
movq 0x38(%rax), %rdi
movl -0x10(%rbp), %esi
callq 0x31d0
movl %eax, -0x10(%rbp)
movl -0x10(%rbp), %eax
addl $0x41, %eax
movb %al, -0x31(%rbp)
movb -0x31(%rbp), %al
addq $0x40, %rsp
popq %rbp
retq
nop