// File: IncredibleHannes[P]QMUL-ChessGame/src/Controller/Controler.cpp
// Function: Controller::run()
void Controller::run() {

  Board *board = new Board();

  View view = View();

  view.printGreeting();

  while (true) {
    if (board->isCheck()) {
      view.printCheck();
      if (board->isCheckmate()) {
        view.printCheckmate();
        view.printBoard(board);
        break;
      }
    }
    if (board->isDraw()) {
      view.printDraw();
      view.printBoard(board);
      break;
    }
    view.printBoard(board);

    bool noInvalidAction = true;
    while (noInvalidAction) {
      UserAction *userAction = view.getUserAction();
      Move *move;
      switch (userAction->getType()) {
        case UserAction::Save :
          view.saveToFile(board->getPreviousMoves());
          noInvalidAction = false;
          break;
        case UserAction::Load :
          delete board;
          board = new Board(view.loadFromFile());
          noInvalidAction = false;
          break;
        case UserAction::Undo :
          board->undoLastMove();
          noInvalidAction = false;
          break;
        case UserAction::MoveAction :
          move = new Move(*userAction->getMove());
          if(!board->applyMove(move)) {
            view.printInvalidMove();
            delete move;
            delete userAction;
            continue;
          }
          if (board->isPromotion(move)) {
            board->applyPromotion(move, view.getPromotionType());
          }
          noInvalidAction = false;
          //delete move;
          break;
        case UserAction::Quit :
          view.printQuitMessage();
          delete board;
          delete userAction;
          return;
        default:
          view.printInvalidUserAction();
      }
      delete userAction;
    }
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xe0, %rsp
movq %rdi, -0x8(%rbp)
movl $0x40, %edi
callq 0x2160
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x70(%rbp)
callq 0x6b70
jmp 0x27ca
movq -0x70(%rbp), %rax
movq %rax, -0x10(%rbp)
leaq -0x1d(%rbp), %rdi
xorl %esi, %esi
movl $0x1, %edx
callq 0x20d0
leaq -0x1d(%rbp), %rdi
callq 0xb770
movq -0x10(%rbp), %rdi
callq 0x81e0
testb $0x1, %al
jne 0x27fa
jmp 0x2849
leaq -0x1d(%rbp), %rdi
callq 0xb820
movq -0x10(%rbp), %rdi
callq 0x8d40
testb $0x1, %al
jne 0x2812
jmp 0x2847
leaq -0x1d(%rbp), %rdi
callq 0xb860
movq -0x10(%rbp), %rsi
leaq -0x1d(%rbp), %rdi
callq 0xab20
jmp 0x2b98
movq -0x70(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
callq 0x2140
jmp 0x2ba1
jmp 0x2849
movq -0x10(%rbp), %rdi
callq 0x8fc0
testb $0x1, %al
jne 0x2858
jmp 0x2873
leaq -0x1d(%rbp), %rdi
callq 0xb8c0
movq -0x10(%rbp), %rsi
leaq -0x1d(%rbp), %rdi
callq 0xab20
jmp 0x2b98
movq -0x10(%rbp), %rsi
leaq -0x1d(%rbp), %rdi
callq 0xab20
movb $0x1, -0x1e(%rbp)
testb $0x1, -0x1e(%rbp)
je 0x2b93
leaq -0x1d(%rbp), %rdi
callq 0xb0f0
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
callq 0xaaf0
movl %eax, %ecx
movq %rcx, -0x78(%rbp)
subl $0x4, %eax
ja 0x2b5c
movq -0x78(%rbp), %rax
leaq 0x9746(%rip), %rcx      # 0xc004
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x10(%rbp), %rsi
leaq -0x48(%rbp), %rdi
movq %rdi, -0x80(%rbp)
callq 0x81b0
movq -0x80(%rbp), %rsi
leaq -0x1d(%rbp), %rdi
callq 0xb920
jmp 0x28e7
leaq -0x48(%rbp), %rdi
callq 0x2bb0
movb $0x0, -0x1e(%rbp)
jmp 0x2b65
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x2bb0
jmp 0x2ba1
movq -0x10(%rbp), %rax
movq %rax, -0x88(%rbp)
cmpq $0x0, %rax
je 0x293c
movq -0x88(%rbp), %rdi
callq 0x7e40
movq -0x88(%rbp), %rdi
callq 0x2140
movl $0x40, %edi
callq 0x2160
movq %rax, -0x90(%rbp)
movb $0x1, -0x61(%rbp)
leaq -0x60(%rbp), %rdi
leaq -0x1d(%rbp), %rsi
callq 0xbbd0
jmp 0x2960
movq -0x90(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x7430
jmp 0x2972
movq -0x90(%rbp), %rax
movb $0x0, -0x61(%rbp)
movq %rax, -0x10(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x2bb0
movb $0x0, -0x1e(%rbp)
jmp 0x2b65
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
jmp 0x29b6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x2bb0
testb $0x1, -0x61(%rbp)
jne 0x29be
jmp 0x29ca
movq -0x90(%rbp), %rdi
callq 0x2140
jmp 0x2ba1
movq -0x10(%rbp), %rdi
callq 0x8670
movb $0x0, -0x1e(%rbp)
jmp 0x2b65
movl $0x20, %edi
callq 0x2160
movq %rax, -0xa0(%rbp)
movq -0x28(%rbp), %rdi
callq 0xab00
movq %rax, -0x98(%rbp)
jmp 0x2a04
movq -0x98(%rbp), %rsi
movq -0xa0(%rbp), %rdi
callq 0x6930
jmp 0x2a19
movq -0xa0(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0x7510
testb $0x1, %al
jne 0x2ab2
leaq -0x1d(%rbp), %rdi
callq 0xaef0
movq -0x30(%rbp), %rax
movq %rax, -0xa8(%rbp)
cmpq $0x0, %rax
je 0x2a67
movq -0xa8(%rbp), %rdi
callq 0x69d0
movq -0xa8(%rbp), %rdi
callq 0x2140
movq -0x28(%rbp), %rax
movq %rax, -0xb0(%rbp)
cmpq $0x0, %rax
je 0x2a90
movq -0xb0(%rbp), %rdi
callq 0xaab0
movq -0xb0(%rbp), %rdi
callq 0x2140
jmp 0x2884
movq -0xa0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
callq 0x2140
jmp 0x2ba1
movq -0x10(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0x9060
testb $0x1, %al
jne 0x2ac5
jmp 0x2af9
movq -0x10(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0xb8(%rbp)
leaq -0x1d(%rbp), %rdi
callq 0xafb0
movq -0xc0(%rbp), %rdi
movq -0xb8(%rbp), %rsi
movl %eax, %edx
callq 0x8930
movb $0x0, -0x1e(%rbp)
jmp 0x2b65
leaq -0x1d(%rbp), %rdi
callq 0xaf70
movq -0x10(%rbp), %rax
movq %rax, -0xc8(%rbp)
cmpq $0x0, %rax
je 0x2b31
movq -0xc8(%rbp), %rdi
callq 0x7e40
movq -0xc8(%rbp), %rdi
callq 0x2140
movq -0x28(%rbp), %rax
movq %rax, -0xd0(%rbp)
cmpq $0x0, %rax
je 0x2b5a
movq -0xd0(%rbp), %rdi
callq 0xaab0
movq -0xd0(%rbp), %rdi
callq 0x2140
jmp 0x2b98
leaq -0x1d(%rbp), %rdi
callq 0xaf30
movq -0x28(%rbp), %rax
movq %rax, -0xd8(%rbp)
cmpq $0x0, %rax
je 0x2b8e
movq -0xd8(%rbp), %rdi
callq 0xaab0
movq -0xd8(%rbp), %rdi
callq 0x2140
jmp 0x2884
jmp 0x27eb
addq $0xe0, %rsp
popq %rbp
retq
movq -0x18(%rbp), %rdi
callq 0x2260
nopw (%rax,%rax)