// File: bjohnsonfl[P]Overhead-Chess-Engine-/moveGen.cpp
// Function: generateCastling(position const&, candidate*)
candidate* generateCastling(const position& pos, candidate* moveList)
{
    player us = pos.get_sideToPlay();
    player them = player(!us);
    bitboard occupied  = pos.get_pieces();
    bitboard enemy = pos.get_pieces(them);
    int castlightRights = us == white ? pos.get_castlingRights(white) : pos.get_castlingRights(black) >> 2;
    square sq, kSq; //rkSq
    bool illegal = false;
    kSq = lsb_sq(pos.get_king(us));
    
    illegal = ((pos.squareAttackedBy(kSq)) & enemy) == true ? true :false;
    
    square a_1 = us == white ? a1 : a8;
    square b_1 = us == white ? b1 : b8;
    square h_1 = us == white ? h1 : h8;
    
    if((castlightRights & 0x1) && !illegal) // KING SIDE CASTLE
    {
        sq = square(kSq + 1);
        while(!illegal && (sq < h_1))
        {
            if(squareBitMask[sq] & occupied) illegal = true;
            if((pos.squareAttackedBy(sq)) & enemy) illegal = true;
           
            sq = square( sq + 1 );
        }
        
        if(!illegal)
        {
            //make move
            (*moveList++).mv = make_move(kSq, h_1, pieceType(0) , castling);
            
        }
        
        
        illegal = false;
    }
    if ((castlightRights & 0x2) && !illegal) // QUEEN SIDE CASTLE
    {
        sq = square(kSq - 1);
        //BUGGGGGGGGGG b1 is never cheked
        while(!illegal && (sq > a_1))
        {
            if(squareBitMask[sq] & occupied) illegal = true;
            if(((pos.squareAttackedBy(sq)) & enemy) && sq != b_1) illegal = true;
           // printBitboard(pos.squareAttackedBy(sq));
           // printBitboard(pos.squareAttackedBy(sq) & enemy);
            
            sq = square( sq - 1 );
        }
        
        if(!illegal)
        {
            //make move
            (*moveList++).mv = make_move(kSq, a_1, pieceType(0) , castling);
           
        }
    }
    
    
    return moveList;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rdi
callq 0x75c0
movl %eax, -0x14(%rbp)
cmpl $0x0, -0x14(%rbp)
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x18(%rbp)
movq -0x8(%rbp), %rdi
callq 0x7690
movq %rax, -0x20(%rbp)
movq -0x8(%rbp), %rdi
movl -0x18(%rbp), %esi
callq 0x7600
movq %rax, -0x28(%rbp)
cmpl $0x0, -0x14(%rbp)
jne 0x63a0
movq -0x8(%rbp), %rdi
xorl %esi, %esi
callq 0x7570
movl %eax, -0x48(%rbp)
jmp 0x63b4
movq -0x8(%rbp), %rdi
movl $0x1, %esi
callq 0x7570
sarl $0x2, %eax
movl %eax, -0x48(%rbp)
movl -0x48(%rbp), %eax
movl %eax, -0x2c(%rbp)
movb $0x0, -0x35(%rbp)
movq -0x8(%rbp), %rdi
movl -0x14(%rbp), %esi
callq 0x77f0
movq %rax, %rdi
callq 0x7780
movl %eax, -0x34(%rbp)
movq -0x8(%rbp), %rdi
movl -0x34(%rbp), %esi
callq 0x98b0
movq -0x28(%rbp), %rcx
andq %rcx, %rax
subq $0x1, %rax
sete %al
negb %al
andb $0x1, %al
movb %al, -0x35(%rbp)
movl -0x14(%rbp), %edx
movl $0x38, %eax
xorl %ecx, %ecx
cmpl $0x0, %edx
cmovel %ecx, %eax
movl %eax, -0x3c(%rbp)
movl -0x14(%rbp), %edx
movl $0x39, %eax
movl $0x1, %ecx
cmpl $0x0, %edx
cmovel %ecx, %eax
movl %eax, -0x40(%rbp)
movl -0x14(%rbp), %edx
movl $0x3f, %eax
movl $0x7, %ecx
cmpl $0x0, %edx
cmovel %ecx, %eax
movl %eax, -0x44(%rbp)
movl -0x2c(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x64e9
testb $0x1, -0x35(%rbp)
jne 0x64e9
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
xorl %eax, %eax
testb $0x1, -0x35(%rbp)
movb %al, -0x49(%rbp)
jne 0x646e
movl -0x30(%rbp), %eax
cmpl -0x44(%rbp), %eax
setl %al
movb %al, -0x49(%rbp)
movb -0x49(%rbp), %al
testb $0x1, %al
jne 0x6477
jmp 0x64ba
movl -0x30(%rbp), %eax
movl %eax, %ecx
leaq 0xca1d(%rip), %rax      # 0x12ea0
movq (%rax,%rcx,8), %rax
andq -0x20(%rbp), %rax
cmpq $0x0, %rax
je 0x6495
movb $0x1, -0x35(%rbp)
movq -0x8(%rbp), %rdi
movl -0x30(%rbp), %esi
callq 0x98b0
andq -0x28(%rbp), %rax
cmpq $0x0, %rax
je 0x64af
movb $0x1, -0x35(%rbp)
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0x6457
testb $0x1, -0x35(%rbp)
jne 0x64e5
movl -0x34(%rbp), %edi
movl -0x44(%rbp), %esi
xorl %edx, %edx
movl $0x2, %ecx
callq 0x7830
movl %eax, %ecx
movq -0x10(%rbp), %rax
movq %rax, %rdx
addq $0x8, %rdx
movq %rdx, -0x10(%rbp)
movl %ecx, (%rax)
movb $0x0, -0x35(%rbp)
movl -0x2c(%rbp), %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0x65a3
testb $0x1, -0x35(%rbp)
jne 0x65a3
movl -0x34(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x30(%rbp)
xorl %eax, %eax
testb $0x1, -0x35(%rbp)
movb %al, -0x4a(%rbp)
jne 0x6522
movl -0x30(%rbp), %eax
cmpl -0x3c(%rbp), %eax
setg %al
movb %al, -0x4a(%rbp)
movb -0x4a(%rbp), %al
testb $0x1, %al
jne 0x652b
jmp 0x6576
movl -0x30(%rbp), %eax
movl %eax, %ecx
leaq 0xc969(%rip), %rax      # 0x12ea0
movq (%rax,%rcx,8), %rax
andq -0x20(%rbp), %rax
cmpq $0x0, %rax
je 0x6549
movb $0x1, -0x35(%rbp)
movq -0x8(%rbp), %rdi
movl -0x30(%rbp), %esi
callq 0x98b0
andq -0x28(%rbp), %rax
cmpq $0x0, %rax
je 0x656b
movl -0x30(%rbp), %eax
cmpl -0x40(%rbp), %eax
je 0x656b
movb $0x1, -0x35(%rbp)
movl -0x30(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0x650b
testb $0x1, -0x35(%rbp)
jne 0x65a1
movl -0x34(%rbp), %edi
movl -0x3c(%rbp), %esi
xorl %edx, %edx
movl $0x2, %ecx
callq 0x7830
movl %eax, %ecx
movq -0x10(%rbp), %rax
movq %rax, %rdx
addq $0x8, %rdx
movq %rdx, -0x10(%rbp)
movl %ecx, (%rax)
jmp 0x65a3
movq -0x10(%rbp), %rax
addq $0x50, %rsp
popq %rbp
retq
nopl (%rax)