// File: melop[P]admixem/Individual.cpp
// Function: Individual::Individual(Individual*, Individual*, bool&)
Individual::Individual(Individual * pFather, Individual * pMother, bool &bSuccess) {
	this->_bDead = false;
	this->_pPrevPop = NULL;
	this->_pPop = pMother->GetPop();

	if (pFather->GetSex() != Male || pMother -> GetSex() != Female) { // gay sex not implemented.
		bSuccess = false;
		//throw "Cannot create a new individual from same-sex parents!";
		return;
	}
	
	this -> _nId = nCurrIndividualId;
	nCurrIndividualId++;
	
	this->_nFatherId = pFather->GetID();
	this->_nMotherId = pMother->GetID();

	
	this->_nHaploidChrNum = SimulConfig.pMarkerConfig->GetHaploidChromosomeNum();
	this->_nTotalChrNum = 2* this->_nHaploidChrNum ;

	SimulConfig.pPhenotypeConfig->InitKeys(&this->_mpPhenotypes);
	SimulConfig.pPhenotypeConfig->InitKeys(&this->_mpEnvPhenotypes);
	
	this->_mpDadPhenotypes.insert(pFather->_mpPhenotypes.begin(), pFather->_mpPhenotypes.end()); // save parent's phenotypes
	this->_mpMomPhenotypes.insert(pMother->_mpPhenotypes.begin(), pMother->_mpPhenotypes.end());
	
	vector< vector<Marker> > vFatherMarkers, vMotherMarkers;
	vector< vector<Gene> > vFatherGenes, vMotherGenes;
	//#pragma omp critical 
	//{
		pFather->GetGamete(vFatherMarkers, vFatherGenes);
		pMother->GetGamete(vMotherMarkers, vMotherGenes);
	//}

	//printf("vFatherMarkers.size() %d\n", vFatherMarkers.size());
	//printf("vFatherGenes.size() %d\n", vFatherGenes.size());
	this->_arrMarkers.reserve(vFatherMarkers.size() * 2);
	this->_arrGenes.reserve(vFatherGenes.size() * 2);

	//put chromosomes in order:
	for (int i=0;i<vFatherMarkers.size();i++) {
		this->_arrMarkers.push_back(vFatherMarkers.at(i));
		this->_arrMarkers.push_back(vMotherMarkers.at(i));

	}

	for (int i=0;i<vFatherGenes.size();i++) {
		this->_arrGenes.push_back(vFatherGenes.at(i));
		this->_arrGenes.push_back(vMotherGenes.at(i));
	}

	//printf("_arrMarkers.size() %d\n", _arrMarkers.size());
	//printf("_arrGenes.size() %d\n", _arrGenes.size());
	this->fnDeterminePhenotypes();
	this->fnDetermineSex();
	this->fnDetermineNumGametes();
	bSuccess = true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1a0, %rsp            # imm = 0x1A0
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0xc8(%rbp)
addq $0x50, %rdi
movq %rdi, -0x100(%rbp)
callq 0x2d7c0
movq -0xc8(%rbp), %rdi
subq $-0x80, %rdi
movq %rdi, -0xf8(%rbp)
callq 0x2d7c0
movq -0xc8(%rbp), %rdi
addq $0xb0, %rdi
movq %rdi, -0xf0(%rbp)
callq 0x2d7c0
movq -0xc8(%rbp), %rdi
addq $0xe0, %rdi
movq %rdi, -0xe8(%rbp)
callq 0x2d7c0
movq -0xc8(%rbp), %rdi
addq $0x110, %rdi            # imm = 0x110
movq %rdi, -0xe0(%rbp)
callq 0x5b530
movq -0xc8(%rbp), %rdi
addq $0x128, %rdi            # imm = 0x128
movq %rdi, -0xd8(%rbp)
callq 0x5b550
movq -0xc8(%rbp), %rdi
addq $0x140, %rdi            # imm = 0x140
movq %rdi, -0xd0(%rbp)
callq 0x5b570
movq -0xc8(%rbp), %rax
movb $0x0, 0x2d(%rax)
movq $0x0, 0x20(%rax)
movq -0x18(%rbp), %rdi
callq 0x570d0
movq %rax, -0xc0(%rbp)
jmp 0x56b94
movq -0xc8(%rbp), %rax
movq -0xc0(%rbp), %rcx
movq %rcx, 0x18(%rax)
movq -0x10(%rbp), %rdi
callq 0x570f0
movl %eax, -0x104(%rbp)
jmp 0x56bb7
movl -0x104(%rbp), %eax
cmpl $0x0, %eax
jne 0x56bde
movq -0x18(%rbp), %rdi
callq 0x570f0
movl %eax, -0x108(%rbp)
jmp 0x56bd3
movl -0x108(%rbp), %eax
cmpl $0x1, %eax
je 0x56bfb
movq -0x20(%rbp), %rax
movb $0x0, (%rax)
jmp 0x57066
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
jmp 0x5706f
movq -0xc8(%rbp), %rax
movq 0x538df(%rip), %rcx     # 0xaa4e8
movq %rcx, 0x10(%rax)
movq 0x538d4(%rip), %rax     # 0xaa4e8
incq %rax
movq %rax, 0x538ca(%rip)     # 0xaa4e8
movq -0x10(%rbp), %rdi
callq 0x57110
movq %rax, -0x110(%rbp)
jmp 0x56c30
movq -0xc8(%rbp), %rax
movq -0x110(%rbp), %rcx
movq %rcx, (%rax)
movq -0x18(%rbp), %rdi
callq 0x57110
movq %rax, -0x118(%rbp)
jmp 0x56c53
movq -0xc8(%rbp), %rax
movq -0x118(%rbp), %rcx
movq %rcx, 0x8(%rax)
leaq 0x53dec(%rip), %rax     # 0xaaa58
movq (%rax), %rdi
callq 0x1ce90
movl %eax, -0x11c(%rbp)
jmp 0x56c7c
movq -0xc8(%rbp), %rsi
movl -0x11c(%rbp), %eax
movl %eax, 0x44(%rsi)
movl 0x44(%rsi), %eax
addl %eax, %eax
movl %eax, 0x48(%rsi)
leaq 0x53dbd(%rip), %rax     # 0xaaa58
movq 0x10(%rax), %rdi
addq $0x50, %rsi
callq 0x21a70
jmp 0x56caa
movq -0xc8(%rbp), %rsi
leaq 0x53da0(%rip), %rax     # 0xaaa58
movq 0x10(%rax), %rdi
subq $-0x80, %rsi
callq 0x21a70
jmp 0x56cc7
movq -0xc8(%rbp), %rax
addq $0xb0, %rax
movq %rax, -0x128(%rbp)
movq -0x10(%rbp), %rdi
addq $0x50, %rdi
callq 0x2b540
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rdi
addq $0x50, %rdi
callq 0x107a0
movq -0x128(%rbp), %rdi
movq %rax, -0x40(%rbp)
movq -0x38(%rbp), %rsi
movq -0x40(%rbp), %rdx
callq 0x5bde0
jmp 0x56d13
movq -0xc8(%rbp), %rax
addq $0xe0, %rax
movq %rax, -0x130(%rbp)
movq -0x18(%rbp), %rdi
addq $0x50, %rdi
callq 0x2b540
movq %rax, -0x48(%rbp)
movq -0x18(%rbp), %rdi
addq $0x50, %rdi
callq 0x107a0
movq -0x130(%rbp), %rdi
movq %rax, -0x50(%rbp)
movq -0x48(%rbp), %rsi
movq -0x50(%rbp), %rdx
callq 0x5bde0
jmp 0x56d5f
leaq -0x68(%rbp), %rdi
movq %rdi, -0x140(%rbp)
callq 0x5b530
leaq -0x80(%rbp), %rdi
callq 0x5b530
leaq -0x98(%rbp), %rdi
movq %rdi, -0x138(%rbp)
callq 0x5b550
leaq -0xb0(%rbp), %rdi
callq 0x5b550
movq -0x140(%rbp), %rsi
movq -0x138(%rbp), %rdx
movq -0x10(%rbp), %rdi
callq 0x57130
jmp 0x56db0
movq -0x18(%rbp), %rdi
leaq -0x80(%rbp), %rsi
leaq -0xb0(%rbp), %rdx
callq 0x57130
jmp 0x56dc6
movq -0xc8(%rbp), %rax
addq $0x110, %rax            # imm = 0x110
movq %rax, -0x148(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x5bf20
movq -0x148(%rbp), %rdi
movq %rax, %rsi
addq %rsi, %rsi
callq 0x5be20
jmp 0x56df7
movq -0xc8(%rbp), %rax
addq $0x128, %rax            # imm = 0x128
movq %rax, -0x150(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x5c050
movq -0x150(%rbp), %rdi
movq %rax, %rsi
addq %rsi, %rsi
callq 0x5bf50
jmp 0x56e2b
movl $0x0, -0xb4(%rbp)
movslq -0xb4(%rbp), %rax
movq %rax, -0x158(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x5bf20
movq %rax, %rcx
movq -0x158(%rbp), %rax
cmpq %rcx, %rax
jae 0x56f34
movq -0xc8(%rbp), %rax
addq $0x110, %rax            # imm = 0x110
movq %rax, -0x168(%rbp)
movslq -0xb4(%rbp), %rsi
leaq -0x68(%rbp), %rdi
callq 0x5c080
movq %rax, -0x160(%rbp)
jmp 0x56e8c
movq -0x160(%rbp), %rsi
movq -0x168(%rbp), %rdi
callq 0x5b7d0
jmp 0x56ea1
movq -0xc8(%rbp), %rax
addq $0x110, %rax            # imm = 0x110
movq %rax, -0x178(%rbp)
movslq -0xb4(%rbp), %rsi
leaq -0x80(%rbp), %rdi
callq 0x5c080
movq %rax, -0x170(%rbp)
jmp 0x56ece
movq -0x170(%rbp), %rsi
movq -0x178(%rbp), %rdi
callq 0x5b7d0
jmp 0x56ee3
jmp 0x56ee5
movl -0xb4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xb4(%rbp)
jmp 0x56e35
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x5b5f0
leaq -0x98(%rbp), %rdi
callq 0x5b5f0
leaq -0x80(%rbp), %rdi
callq 0x5b650
leaq -0x68(%rbp), %rdi
callq 0x5b650
jmp 0x5706f
movl $0x0, -0xb8(%rbp)
movslq -0xb8(%rbp), %rax
movq %rax, -0x180(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x5c050
movq %rax, %rcx
movq -0x180(%rbp), %rax
cmpq %rcx, %rax
jae 0x5700b
movq -0xc8(%rbp), %rax
addq $0x128, %rax            # imm = 0x128
movq %rax, -0x190(%rbp)
movslq -0xb8(%rbp), %rsi
leaq -0x98(%rbp), %rdi
callq 0x5bb40
movq %rax, -0x188(%rbp)
jmp 0x56f9b
movq -0x188(%rbp), %rsi
movq -0x190(%rbp), %rdi
callq 0x5b990
jmp 0x56fb0
movq -0xc8(%rbp), %rax
addq $0x128, %rax            # imm = 0x128
movq %rax, -0x1a0(%rbp)
movslq -0xb8(%rbp), %rsi
leaq -0xb0(%rbp), %rdi
callq 0x5bb40
movq %rax, -0x198(%rbp)
jmp 0x56fe0
movq -0x198(%rbp), %rsi
movq -0x1a0(%rbp), %rdi
callq 0x5b990
jmp 0x56ff5
jmp 0x56ff7
movl -0xb8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xb8(%rbp)
jmp 0x56f3e
movq -0xc8(%rbp), %rdi
callq 0x55ac0
jmp 0x57019
movq -0xc8(%rbp), %rdi
callq 0x56800
jmp 0x57027
movq -0xc8(%rbp), %rdi
callq 0x568d0
jmp 0x57035
movq -0x20(%rbp), %rax
movb $0x1, (%rax)
leaq -0xb0(%rbp), %rdi
callq 0x5b5f0
leaq -0x98(%rbp), %rdi
callq 0x5b5f0
leaq -0x80(%rbp), %rdi
callq 0x5b650
leaq -0x68(%rbp), %rdi
callq 0x5b650
addq $0x1a0, %rsp            # imm = 0x1A0
popq %rbp
retq
movq -0xd0(%rbp), %rdi
callq 0x5b590
movq -0xd8(%rbp), %rdi
callq 0x5b5f0
movq -0xe0(%rbp), %rdi
callq 0x5b650
movq -0xe8(%rbp), %rdi
callq 0x2d860
movq -0xf0(%rbp), %rdi
callq 0x2d860
movq -0xf8(%rbp), %rdi
callq 0x2d860
movq -0x100(%rbp), %rdi
callq 0x2d860
movq -0x28(%rbp), %rdi
callq 0x8860
nopl (%rax)