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

	Node *in_node;
	Node *out_node;


	int i = 0; // counter in case no new connection is possible
	bool duplicate = false;

	vector<Connection*>::iterator conPtr;


	do{

		int in_node_id = randint(0, nodes.size()-(*out_size)-1);
		// cout << "ma1" << endl;

		in_node = nodes[in_node_id];
		// cout << "ma2" << endl;

		int out_node_id;

		do{

			out_node_id = randint(*in_size, nodes.size()-1);
			i++;

		}while(in_node_id==out_node_id);

		out_node = nodes[out_node_id];

		duplicate = false;

		for(conPtr=out_node->in_connections.begin(); conPtr != out_node->in_connections.end(); ++conPtr){

			if((*conPtr)->in_node==in_node) duplicate = true; // proposed connection already exists

		}
			// cout << "ma3" << endl;

		for(conPtr=out_node->out_connections.begin(); conPtr != out_node->out_connections.end(); ++conPtr){

			if((*conPtr)->out_node==in_node) duplicate = true; // proposed opposite connection already exists, prevents simple loops

		}


	}while(i<20 && duplicate==true);

	if(duplicate==true) return false; // couldn't find any new possible connection


	int new_innov_number;

	bool found = false;


	for(conPtr=all_connections->begin(); conPtr != all_connections->end(); ++conPtr){
		// give identical mutations same hist_marking
		// could also check for mutation hist gen? 
		// (https://www.cs.ucf.edu/~kstanley/neat.html#FAQ1  - see "record of innovation" Q
		if((*conPtr)->in_node->hist_marking==in_node->hist_marking && (*conPtr)->out_node->hist_marking==out_node->hist_marking){
			new_innov_number = (*conPtr)->hist_marking;
			found = true;
			break;
		}

	}

	if(!found){
		new_innov_number = *innov_num;
		(*innov_num)++;
	}

	Connection *new_connection = new Connection(in_node, out_node, new_innov_number, *generation);

	connections.push_back(new_connection);
	// (*all_connections).push_back(new_connection);
	// cout << "ma3" << endl;

	in_node->out_connections.push_back(new_connection);
	out_node->in_connections.push_back(new_connection);

	return true;

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0xa0(%rbp)
movl $0x0, -0x34(%rbp)
movb $0x0, -0x35(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x1800
movq -0xa0(%rbp), %rdi
addq $0x18, %rdi
callq 0x4070
movq -0xa0(%rbp), %rcx
movq 0x88(%rcx), %rcx
movslq (%rcx), %rcx
subq %rcx, %rax
subq $0x1, %rax
movl %eax, %esi
xorl %edi, %edi
callq 0xe160
movq -0xa0(%rbp), %rdi
movl %eax, -0x44(%rbp)
addq $0x18, %rdi
movslq -0x44(%rbp), %rsi
callq 0xdfe0
movq (%rax), %rax
movq %rax, -0x28(%rbp)
movq -0xa0(%rbp), %rdi
movq 0x80(%rdi), %rax
movl (%rax), %eax
movl %eax, -0xa4(%rbp)
addq $0x18, %rdi
callq 0x4070
movl -0xa4(%rbp), %edi
subq $0x1, %rax
movl %eax, %esi
callq 0xe160
movl %eax, -0x48(%rbp)
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
movl -0x44(%rbp), %eax
cmpl -0x48(%rbp), %eax
je 0x125f5
movq -0xa0(%rbp), %rdi
addq $0x18, %rdi
movslq -0x48(%rbp), %rsi
callq 0xdfe0
movq (%rax), %rax
movq %rax, -0x30(%rbp)
movb $0x0, -0x35(%rbp)
movq -0x30(%rbp), %rdi
addq $0x18, %rdi
callq 0x1820
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x30(%rbp), %rdi
addq $0x18, %rdi
callq 0x1890
movq %rax, -0x58(%rbp)
leaq -0x40(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x1850
testb $0x1, %al
jne 0x12695
jmp 0x126bb
leaq -0x40(%rbp), %rdi
callq 0x18c0
movq (%rax), %rax
movq (%rax), %rax
cmpq -0x28(%rbp), %rax
jne 0x126ae
movb $0x1, -0x35(%rbp)
jmp 0x126b0
leaq -0x40(%rbp), %rdi
callq 0x18e0
jmp 0x12671
movq -0x30(%rbp), %rdi
addq $0x30, %rdi
callq 0x1820
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x30(%rbp), %rdi
addq $0x30, %rdi
callq 0x1890
movq %rax, -0x68(%rbp)
leaq -0x40(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x1850
testb $0x1, %al
jne 0x126f8
jmp 0x1271f
leaq -0x40(%rbp), %rdi
callq 0x18c0
movq (%rax), %rax
movq 0x8(%rax), %rax
cmpq -0x28(%rbp), %rax
jne 0x12712
movb $0x1, -0x35(%rbp)
jmp 0x12714
leaq -0x40(%rbp), %rdi
callq 0x18e0
jmp 0x126d4
jmp 0x12721
xorl %eax, %eax
cmpl $0x14, -0x34(%rbp)
movb %al, -0xa5(%rbp)
jge 0x12743
movb -0x35(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
sete %al
movb %al, -0xa5(%rbp)
movb -0xa5(%rbp), %al
testb $0x1, %al
jne 0x125a6
movb -0x35(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x12767
movb $0x0, -0x1(%rbp)
jmp 0x128cf
movb $0x0, -0x6d(%rbp)
movq -0x20(%rbp), %rdi
callq 0x1820
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x20(%rbp), %rdi
callq 0x1890
movq %rax, -0x80(%rbp)
leaq -0x40(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x1850
testb $0x1, %al
jne 0x127a0
jmp 0x127fc
leaq -0x40(%rbp), %rdi
callq 0x18c0
movq (%rax), %rax
movq (%rax), %rax
movl 0x4(%rax), %eax
movq -0x28(%rbp), %rcx
cmpl 0x4(%rcx), %eax
jne 0x127ef
leaq -0x40(%rbp), %rdi
callq 0x18c0
movq (%rax), %rax
movq 0x8(%rax), %rax
movl 0x4(%rax), %eax
movq -0x30(%rbp), %rcx
cmpl 0x4(%rcx), %eax
jne 0x127ef
leaq -0x40(%rbp), %rdi
callq 0x18c0
movq (%rax), %rax
movl 0x1c(%rax), %eax
movl %eax, -0x6c(%rbp)
movb $0x1, -0x6d(%rbp)
jmp 0x127fc
jmp 0x127f1
leaq -0x40(%rbp), %rdi
callq 0x18e0
jmp 0x12780
testb $0x1, -0x6d(%rbp)
jne 0x1281d
movq -0xa0(%rbp), %rax
movq 0x78(%rax), %rcx
movl (%rcx), %ecx
movl %ecx, -0x6c(%rbp)
movq 0x78(%rax), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
movl $0x28, %edi
callq 0x10e0
movq %rax, %rdi
movq -0xa0(%rbp), %rax
movq %rdi, %rcx
movq %rcx, -0xb0(%rbp)
movq -0x28(%rbp), %rsi
movq -0x30(%rbp), %rdx
movl -0x6c(%rbp), %ecx
movq 0x90(%rax), %rax
movl (%rax), %r8d
callq 0x13b20
jmp 0x12857
movq -0xa0(%rbp), %rdi
movq -0xb0(%rbp), %rax
movq %rax, -0x88(%rbp)
addq $0x60, %rdi
leaq -0x88(%rbp), %rsi
callq 0x39d0
movq -0x28(%rbp), %rdi
addq $0x30, %rdi
leaq -0x88(%rbp), %rsi
callq 0x39d0
movq -0x30(%rbp), %rdi
addq $0x18, %rdi
leaq -0x88(%rbp), %rsi
callq 0x39d0
movb $0x1, -0x1(%rbp)
jmp 0x128cf
movq -0xb0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
movl $0x28, %esi
callq 0x10f0
jmp 0x128dd
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0xb0, %rsp
popq %rbp
retq
movq -0x90(%rbp), %rdi
callq 0x1180
nopl (%rax)