// File: yuroitaki[P]enigma_machine/enigma.cpp
// Function: Enigma::encrypt(int&)
void Enigma::encrypt(int& code){

  int len = rotor_vector.size();
  
  plugb_ref->mapping(code,PB);             //plugboard forward mapping
  
  if (len!=0){
    Rotor* r_last = rotor_vector[len-1];
    r_last->shift_ground(RUN);             //rotate the right-hand rotor before circuit closes
    
    for (int j=len-1;j>0;j--){
      if ((rotor_vector[j])->get_notch_stat()){    //if notch is reached, engage the rotor on the left
	rotor_vector[j-1]->shift_ground(RUN);
	rotor_vector[j]->set_notch_stat(false);
      }
      }
    for(int j=len-1;j>=0;j--){
      rotor_vector[j]->encrypting(code,FORWARD);    //rotor forward mapping
    }
  }

  plugb_ref->mapping(code,RF);                     //reflector mapping
    
  if(len!=0){
    for(int j=0;j<len;j++){
      rotor_vector[j]->encrypting(code,BACKWARD);      //rotor backward mapping
    }
  }

  plugb_ref->mapping(code,PB);                   //plugboard backward mapping

  cout << static_cast<char>(code+CONVERSION);        //print result to output stream
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x38(%rbp)
addq $0x10, %rdi
callq 0x2f50
movq %rax, %rcx
movq -0x38(%rbp), %rax
movl %ecx, -0x14(%rbp)
movq 0x8(%rax), %rdi
movq -0x10(%rbp), %rsi
movl $0x64, %edx
callq 0x6a10
cmpl $0x0, -0x14(%rbp)
je 0x2b89
movq -0x38(%rbp), %rdi
addq $0x10, %rdi
movl -0x14(%rbp), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x2f70
movq (%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rdi
movl $0xfffffffe, %esi       # imm = 0xFFFFFFFE
callq 0x6ef0
movl -0x14(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x24(%rbp)
cmpl $0x0, -0x24(%rbp)
jle 0x2b4b
movq -0x38(%rbp), %rdi
addq $0x10, %rdi
movslq -0x24(%rbp), %rsi
callq 0x2f70
movq (%rax), %rdi
callq 0x7280
testb $0x1, %al
jne 0x2b00
jmp 0x2b3e
movq -0x38(%rbp), %rdi
addq $0x10, %rdi
movl -0x24(%rbp), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x2f70
movq (%rax), %rdi
movl $0xfffffffe, %esi       # imm = 0xFFFFFFFE
callq 0x6ef0
movq -0x38(%rbp), %rdi
addq $0x10, %rdi
movslq -0x24(%rbp), %rsi
callq 0x2f70
movq (%rax), %rdi
xorl %esi, %esi
callq 0x7150
jmp 0x2b40
movl -0x24(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x2adb
movl -0x14(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x28(%rbp)
cmpl $0x0, -0x28(%rbp)
jl 0x2b87
movq -0x38(%rbp), %rdi
addq $0x10, %rdi
movslq -0x28(%rbp), %rsi
callq 0x2f70
movq (%rax), %rdi
movq -0x10(%rbp), %rsi
movl $0x3e8, %edx            # imm = 0x3E8
callq 0x7170
movl -0x28(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x2b54
jmp 0x2b89
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x10(%rbp), %rsi
movl $0xc8, %edx
callq 0x6a10
cmpl $0x0, -0x14(%rbp)
je 0x2be3
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x2be1
movq -0x38(%rbp), %rdi
addq $0x10, %rdi
movslq -0x2c(%rbp), %rsi
callq 0x2f70
movq (%rax), %rdi
movq -0x10(%rbp), %rsi
movl $0x7d0, %edx            # imm = 0x7D0
callq 0x7170
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x2bac
jmp 0x2be3
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x10(%rbp), %rsi
movl $0x64, %edx
callq 0x6a10
movq -0x10(%rbp), %rax
movl (%rax), %eax
addl $0x41, %eax
movq 0x93bf(%rip), %rdi      # 0xbfc8
movsbl %al, %esi
callq 0x2160
addq $0x40, %rsp
popq %rbp
retq
nopw (%rax,%rax)