// File: samuel500[P]NEAT/individual.cpp
// Function: Individual::mutate_add_node(std::vector<Node*, std::allocator<Node*>>*, std::vector<Connection*, std::allocator<Connection*>>*)
bool Individual::mutate_add_node(vector<Node*> *all_nodes, vector<Connection*> *all_connections){

	bool found_active = false;
	int rand_connection_id;
	for(int i=0; i<15; i++){
		rand_connection_id = randint(0, connections.size()-1);
		if(connections[rand_connection_id]->is_active){
			found_active = true;
			break;
		}
	}
	if(!found_active){ 
		cout << "no active connection found"<< endl;
		return false;


	}

	Connection *chosen_con = connections[rand_connection_id];
	Node *init_node = chosen_con->in_node;
	Node *end_node = chosen_con->out_node;

	chosen_con->is_active = false;


	bool found = false;
	int new_node_innov_number, new_in_connection_innov_number, new_out_connection_innov_number;


	vector<Node*>::iterator nodePtr;

	for(nodePtr=all_nodes->begin(); nodePtr != all_nodes->end(); ++nodePtr){
		// this will only find those nodes that haven't gotten any new connections since added
		// (Stanley's implementation only looks for nodes mutated in the current generation)
		if((*nodePtr)->in_connections.size()==1 && (*nodePtr)->out_connections.size()==1){

			if((*nodePtr)->in_connections[0]->in_node->hist_marking==init_node->hist_marking && (*nodePtr)->out_connections[0]->out_node->hist_marking==end_node->hist_marking){
				found = true;
				new_node_innov_number = (*nodePtr)->hist_marking;
				new_in_connection_innov_number = (*nodePtr)->in_connections[0]->hist_marking;
				new_out_connection_innov_number = (*nodePtr)->out_connections[0]->hist_marking;
			}

		}

	}

	if(!found){
		new_node_innov_number = *innov_num;
		(*innov_num)++;
		new_in_connection_innov_number = *innov_num;
		(*innov_num)++;
		new_out_connection_innov_number = *innov_num;
		(*innov_num)++;
	}


	Node *new_node = new Node(HIDDEN, new_node_innov_number, *generation);
	
	Connection *new_in_connection = new Connection(init_node, new_node, new_in_connection_innov_number, *generation);
	Connection *new_out_connection = new Connection(new_node, end_node, new_out_connection_innov_number, *generation);
	
	new_in_connection->weight = 1.0;
	new_out_connection->weight = chosen_con->weight;


	connections.push_back(new_in_connection);
	connections.push_back(new_out_connection);

	// all_connections->push_back(new_in_connection);
	// all_connections->push_back(new_out_connection);

	nodes.insert(nodes.begin()+(nodes.size()-(*out_size)), new_node); // add before the output nodes
	// all_nodes->push_back(new_node);

	return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xe0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0xc0(%rbp)
movb $0x0, -0x21(%rbp)
movl $0x0, -0x2c(%rbp)
cmpl $0xf, -0x2c(%rbp)
jge 0x12133
movq -0xc0(%rbp), %rdi
addq $0x60, %rdi
callq 0x4050
subq $0x1, %rax
movl %eax, %esi
xorl %edi, %edi
callq 0xe160
movq -0xc0(%rbp), %rdi
movl %eax, -0x28(%rbp)
addq $0x60, %rdi
movslq -0x28(%rbp), %rsi
callq 0xe000
movq (%rax), %rax
testb $0x1, 0x18(%rax)
je 0x12126
movb $0x1, -0x21(%rbp)
jmp 0x12133
jmp 0x12128
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x120dd
testb $0x1, -0x21(%rbp)
jne 0x12164
movq 0xbe98(%rip), %rdi      # 0x1dfd8
leaq 0x315a(%rip), %rsi      # 0x152a1
callq 0x10d0
movq %rax, %rdi
movq 0xbe72(%rip), %rsi      # 0x1dfc8
callq 0x1100
movb $0x0, -0x1(%rbp)
jmp 0x12555
movq -0xc0(%rbp), %rdi
addq $0x60, %rdi
movslq -0x28(%rbp), %rsi
callq 0xe000
movq (%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x40(%rbp)
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x48(%rbp)
movq -0x38(%rbp), %rax
movb $0x0, 0x18(%rax)
movb $0x0, -0x49(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x39b0
movq -0x18(%rbp), %rdi
callq 0x3a40
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x18(%rbp), %rdi
callq 0x3ab0
movq %rax, -0x70(%rbp)
leaq -0x60(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x3a70
testb $0x1, %al
jne 0x121e3
jmp 0x122e8
leaq -0x60(%rbp), %rdi
callq 0x3b50
movq (%rax), %rdi
addq $0x18, %rdi
callq 0x4050
cmpq $0x1, %rax
jne 0x122d8
leaq -0x60(%rbp), %rdi
callq 0x3b50
movq (%rax), %rdi
addq $0x30, %rdi
callq 0x4050
cmpq $0x1, %rax
jne 0x122d8
leaq -0x60(%rbp), %rdi
callq 0x3b50
movq (%rax), %rdi
addq $0x18, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0xe000
movq (%rax), %rax
movq (%rax), %rax
movl 0x4(%rax), %eax
movq -0x40(%rbp), %rcx
cmpl 0x4(%rcx), %eax
jne 0x122d6
leaq -0x60(%rbp), %rdi
callq 0x3b50
movq (%rax), %rdi
addq $0x30, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0xe000
movq (%rax), %rax
movq 0x8(%rax), %rax
movl 0x4(%rax), %eax
movq -0x48(%rbp), %rcx
cmpl 0x4(%rcx), %eax
jne 0x122d6
movb $0x1, -0x49(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x3b50
movq (%rax), %rax
movl 0x4(%rax), %eax
movl %eax, -0x50(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x3b50
movq (%rax), %rdi
addq $0x18, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0xe000
movq (%rax), %rax
movl 0x1c(%rax), %eax
movl %eax, -0x54(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x3b50
movq (%rax), %rdi
addq $0x30, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0xe000
movq (%rax), %rax
movl 0x1c(%rax), %eax
movl %eax, -0x58(%rbp)
jmp 0x122d8
jmp 0x122da
leaq -0x60(%rbp), %rdi
callq 0x3b70
jmp 0x121c0
testb $0x1, -0x49(%rbp)
jne 0x12331
movq -0xc0(%rbp), %rax
movq 0x78(%rax), %rcx
movl (%rcx), %ecx
movl %ecx, -0x50(%rbp)
movq 0x78(%rax), %rcx
movl (%rcx), %edx
addl $0x1, %edx
movl %edx, (%rcx)
movq 0x78(%rax), %rcx
movl (%rcx), %ecx
movl %ecx, -0x54(%rbp)
movq 0x78(%rax), %rcx
movl (%rcx), %edx
addl $0x1, %edx
movl %edx, (%rcx)
movq 0x78(%rax), %rcx
movl (%rcx), %ecx
movl %ecx, -0x58(%rbp)
movq 0x78(%rax), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
movl $0x48, %edi
callq 0x10e0
movq %rax, %rdi
movq -0xc0(%rbp), %rax
movq %rdi, %rcx
movq %rcx, -0xc8(%rbp)
movl -0x50(%rbp), %edx
movq 0x90(%rax), %rax
movl (%rax), %ecx
movl $0x2, %esi
callq 0x13870
jmp 0x12367
movq -0xc8(%rbp), %rax
movq %rax, -0x78(%rbp)
movl $0x28, %edi
callq 0x10e0
movq %rax, %rdi
movq -0xc0(%rbp), %rax
movq %rdi, %rcx
movq %rcx, -0xd0(%rbp)
movq -0x40(%rbp), %rsi
movq -0x78(%rbp), %rdx
movl -0x54(%rbp), %ecx
movq 0x90(%rax), %rax
movl (%rax), %r8d
callq 0x13b20
jmp 0x123ac
movq -0xd0(%rbp), %rax
movq %rax, -0x90(%rbp)
movl $0x28, %edi
callq 0x10e0
movq %rax, %rdi
movq -0xc0(%rbp), %rax
movq %rdi, %rcx
movq %rcx, -0xd8(%rbp)
movq -0x78(%rbp), %rsi
movq -0x48(%rbp), %rdx
movl -0x58(%rbp), %ecx
movq 0x90(%rax), %rax
movl (%rax), %r8d
callq 0x13b20
jmp 0x123f4
movq -0xc0(%rbp), %rdi
movq -0xd8(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0x90(%rbp), %rax
movsd 0x2c40(%rip), %xmm0     # 0x15058
movsd %xmm0, 0x10(%rax)
movq -0x38(%rbp), %rax
movsd 0x10(%rax), %xmm0
movq -0x98(%rbp), %rax
movsd %xmm0, 0x10(%rax)
addq $0x60, %rdi
leaq -0x90(%rbp), %rsi
callq 0x39d0
movq -0xc0(%rbp), %rdi
addq $0x60, %rdi
leaq -0x98(%rbp), %rsi
callq 0x39d0
movq -0xc0(%rbp), %rdi
movq %rdi, %rax
addq $0x18, %rax
movq %rax, -0xe0(%rbp)
addq $0x18, %rdi
callq 0x3a40
movq -0xc0(%rbp), %rdi
movq %rax, -0xb0(%rbp)
addq $0x18, %rdi
callq 0x4070
movq %rax, %rsi
movq -0xc0(%rbp), %rax
movq 0x88(%rax), %rax
movslq (%rax), %rax
subq %rax, %rsi
leaq -0xb0(%rbp), %rdi
callq 0xf200
movq %rax, -0xa8(%rbp)
leaq -0xa0(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0x12b90
movq -0xe0(%rbp), %rdi
movq -0xa0(%rbp), %rsi
leaq -0x78(%rbp), %rdx
callq 0x12d10
movq %rax, -0xb8(%rbp)
movb $0x1, -0x1(%rbp)
jmp 0x12555
movq -0xc8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
movl $0x48, %esi
callq 0x10f0
jmp 0x12563
movq -0xd0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
movl $0x28, %esi
callq 0x10f0
jmp 0x12563
movq -0xd8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
movl $0x28, %esi
callq 0x10f0
jmp 0x12563
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0xe0, %rsp
popq %rbp
retq
movq -0x80(%rbp), %rdi
callq 0x1180
nopl (%rax)