// File: /workspace/github_cpp_makefile_star2_O3/dcarrey[P]hgt-detection/./fonctions.cpp
// Function: findAllHGT(InputTree, InputTree, Parameters, HGT*)
int findAllHGT(struct InputTree SpeciesTree, struct InputTree GeneTree,struct Parameters param,struct HGT *tabHGT){
	
	int nbHGT=0;	
	struct InputTree tmpTree;
	int i,j,ktSpecies;
	int size = SpeciesTree.size;
	struct CRITERIA aCrit;
	struct DescTree *DTSpecies,*DTGene;

	initInputTree(&tmpTree);

	//== compute criteria
	InitCriteria(&aCrit,size);

	DTGene = (struct DescTree*)malloc((2*GeneTree.size)*sizeof(struct DescTree));
	RechercherBipartition(GeneTree.ARETE,GeneTree.ADD,GeneTree.Root,GeneTree.Adjacence,DTGene,GeneTree.size,GeneTree.kt);	

	DTSpecies = (struct DescTree*)malloc((2*SpeciesTree.size)*sizeof(struct DescTree));
	RechercherBipartition(SpeciesTree.ARETE,SpeciesTree.ADD,SpeciesTree.Root,SpeciesTree.Adjacence,DTSpecies,SpeciesTree.size,SpeciesTree.kt);
	//printf("\n\n RF = %d \n LS = %lf",aCrit.RF,aCrit.LS);

	//printf("<br>size = %d<br>",size);
	//== Test all possible HGT
	//printEdges(0,SpeciesTree.ARETE,SpeciesTree.LONGUEUR,SpeciesTree.SpeciesName,SpeciesTree.size);
	

	for(i=1;i<2*size-3-SpeciesTree.kt;i++)
		for(j=1;j<2*size-3-SpeciesTree.kt;j++){
		
			//== is it a valid hgt ?
			if(isAValidHGT(SpeciesTree,i,j)==1){

			//	printf(".");

				copyInputTree(&tmpTree,SpeciesTree,0,0);
				
				//printf("\nTransfert : %d--%d -> %d--%d",tmpTree.ARETE[2*i-1],tmpTree.ARETE[2*i-2],tmpTree.ARETE[2*j-1],tmpTree.ARETE[2*j-2]);
				//getchar();

				if(strcmp(param.subtree,"yes") == 0)
					if(TestSubTreeConstraint(SpeciesTree,i,j,DTSpecies,DTGene) == 0) continue;
				
				//printf("\n\n");
				//printEdges(0,tmpTree.ARETE,tmpTree.LONGUEUR,SpeciesTree.SpeciesName,tmpTree.size);
				
				applyHGT(GeneTree.ADD,&tmpTree,i,j);
				//printf("\nTransfert : %d--%d -> %d--%d",tmpTree.ARETE[2*i-1],tmpTree.ARETE[2*i-2],tmpTree.ARETE[2*j-1],tmpTree.ARETE[2*j-2]);
				
				/*printEdges(0,tmpTree.ARETE,tmpTree.LONGUEUR,SpeciesTree.SpeciesName,tmpTree.size);
				printEdges(0,GeneTree.ARETE,GeneTree.LONGUEUR,SpeciesTree.SpeciesName,GeneTree.size);
				printMatrix(SpeciesTree.SpeciesName,tmpTree.ADD,tmpTree.size);
				printMatrix(SpeciesTree.SpeciesName,GeneTree.ADD,GeneTree.size);
				getchar();*/
				//printf("avant");
				AdjustBranchLength(&tmpTree,GeneTree,0,1);
				
				computeCriteria(tmpTree.ADD,GeneTree.ADD,size,&aCrit,tmpTree.LONGUEUR,tmpTree.ARETE,GeneTree.LONGUEUR,GeneTree.ARETE);
				nbHGT++;
				loadCriteria(aCrit,&tabHGT[nbHGT]);
				tabHGT[nbHGT].source = i;
				tabHGT[nbHGT].destination = j;
				
				//printf("\nTransfert : %d--%d (%d)-> %d--%d (%d)",SpeciesTree.ARETE[2*i-1],SpeciesTree.ARETE[2*i-2],i,SpeciesTree.ARETE[2*j-1],SpeciesTree.ARETE[2*j-2],j);
				//printf("=====>RF = %d, LS = %lf",aCrit.RF,aCrit.LS);
			
			}
		}
	
	FreeCriteria(&aCrit,size);

	for(i=1;i<=nbHGT;i++)
		findListSpecies(&tabHGT[i],DTSpecies,SpeciesTree);

	return nbHGT;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x158, %rsp            # imm = 0x158
movq %rdi, -0x50(%rbp)
movslq 0x10(%rbp), %r12
xorl %eax, %eax
movq %rax, -0xb8(%rbp)
xorps %xmm0, %xmm0
movups %xmm0, -0x98(%rbp)
movq %rax, -0x88(%rbp)
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movl %eax, -0xa0(%rbp)
movl %eax, -0xc0(%rbp)
movl $0x0, -0x78(%rbp)
movups %xmm0, -0xb0(%rbp)
leaq -0x120(%rbp), %rdi
movl %r12d, %esi
callq 0xb8ba
movslq 0x68(%rbp), %r15
movq %r15, %rax
shlq $0x4, %rax
leaq (%rax,%rax,2), %rdi
callq 0x1140
movq %rax, %r8
movq 0x98(%rbp), %rdi
movq 0x70(%rbp), %rsi
movl 0x88(%rbp), %edx
movq 0x90(%rbp), %rcx
movl 0xb0(%rbp), %eax
movl %eax, (%rsp)
movq %rsi, -0x60(%rbp)
movq %r8, -0x58(%rbp)
movl %r15d, %r9d
callq 0x4e01
leal (%r12,%r12), %ebx
movq %r12, %rax
shlq $0x4, %rax
leaq (%rax,%rax,2), %rdi
callq 0x1140
movq %rax, %r13
movq 0x40(%rbp), %rdi
movq 0x18(%rbp), %rsi
movl 0x30(%rbp), %edx
movq 0x38(%rbp), %rcx
movl 0x58(%rbp), %r15d
movl %r15d, (%rsp)
movq %rax, %r8
movl %r12d, %r9d
callq 0x4e01
subl %r15d, %ebx
movq %rbx, -0x68(%rbp)
leal -0x3(%rbx), %eax
movl %eax, -0x34(%rbp)
cmpl $0x1, %eax
jle 0xbe03
movq %r13, -0x40(%rbp)
movq %r12, -0x48(%rbp)
movl $0x1, %r15d
movq $0x0, -0x30(%rbp)
leaq -0xc0(%rbp), %r14
movl $0x4, %r13d
leal -0x3(%r13), %r12d
movl $0xb, %ecx
movq %rsp, %rdi
leaq 0x10(%rbp), %rbx
movq %rbx, %rsi
rep  movsq (%rsi), %es:(%rdi)
movl %r15d, %edi
movl %r12d, %esi
callq 0xa42b
testl %eax, %eax
je 0xbd90
movl $0xb, %ecx
movq %rsp, %rdi
movq %rbx, %rsi
rep  movsq (%rsi), %es:(%rdi)
movq %r14, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0xa587
leaq 0xc0(%rbp), %rax
cmpl $0x736579, 0xe9e(%rax)  # imm = 0x736579
jne 0xbcf8
movl $0xb, %ecx
movq %rsp, %rdi
leaq 0x10(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
movl %r15d, %edi
movl %r12d, %esi
movq -0x40(%rbp), %rdx
movq -0x58(%rbp), %rcx
callq 0x7eee
testl %eax, %eax
je 0xbd90
movq %r14, %rsi
movl %r15d, %edx
movl %r12d, %ecx
callq 0x8d4e
movl $0xb, %ecx
movq %rsp, %rdi
leaq 0x68(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
movq %r14, %rdi
xorl %esi, %esi
movl $0x1, %edx
callq 0xb793
movq -0xb8(%rbp), %rdi
movq -0x60(%rbp), %rsi
movq -0x48(%rbp), %rdx
leaq -0x120(%rbp), %rcx
callq 0x8c46
movq -0x30(%rbp), %rcx
incl %ecx
movsd -0x120(%rbp), %xmm0
movsd -0x110(%rbp), %xmm1
movq -0xf0(%rbp), %rax
movq %rcx, -0x30(%rbp)
movslq %ecx, %rcx
imulq $0xa8, %rcx, %rcx
movq -0x50(%rbp), %rdx
movsd %xmm0, 0x20(%rdx,%rcx)
movq %rax, 0x50(%rdx,%rcx)
movsd %xmm1, 0x30(%rdx,%rcx)
movl $0x1, (%rdx,%rcx)
movl %r15d, 0x4(%rdx,%rcx)
movl %r12d, 0x8(%rdx,%rcx)
incl %r13d
cmpl %r13d, -0x68(%rbp)
jne 0xbc78
incl %r15d
cmpl -0x34(%rbp), %r15d
jne 0xbc72
leaq -0x120(%rbp), %rdi
movq -0x48(%rbp), %rsi
callq 0xb982
movq -0x30(%rbp), %rax
testl %eax, %eax
jle 0xbe14
movl %eax, %r15d
movq -0x50(%rbp), %rbx
addq $0xa8, %rbx
movq -0x40(%rbp), %r12
leaq 0x10(%rbp), %r13
movl $0xb, %ecx
movq %rsp, %rdi
movq %r13, %rsi
rep  movsq (%rsi), %es:(%rdi)
movq %rbx, %rdi
movq %r12, %rsi
callq 0xa143
addq $0xa8, %rbx
decq %r15
jne 0xbdd8
movq -0x30(%rbp), %rax
jmp 0xbe14
leaq -0x120(%rbp), %rdi
movl %r12d, %esi
callq 0xb982
xorl %eax, %eax
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq