// File: /workspace/github_cpp_makefile_star2_O1/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, %rbx
leaq 0x10(%rbp), %r15
movslq (%r15), %r12
xorl %eax, %eax
movq %rax, -0xc0(%rbp)
xorps %xmm0, %xmm0
movups %xmm0, -0xa0(%rbp)
movq $0x0, -0x38(%rbp)
movq %rax, -0x90(%rbp)
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movl %eax, -0xa8(%rbp)
movl %eax, -0xc8(%rbp)
movl $0x0, -0x80(%rbp)
movups %xmm0, -0xb8(%rbp)
leaq -0x128(%rbp), %rdi
movl %r12d, %esi
callq 0xb933
movslq 0x68(%rbp), %r14
movq %r14, %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, -0x68(%rbp)
movq %r8, -0x60(%rbp)
movl %r14d, %r9d
callq 0x4ef6
leal (%r12,%r12), %r13d
movq %r12, %rax
shlq $0x4, %rax
leaq (%rax,%rax,2), %rdi
callq 0x1140
movq 0x30(%r15), %rdi
movq 0x8(%r15), %rsi
movl 0x20(%r15), %edx
movq 0x28(%r15), %rcx
movl 0x48(%r15), %r14d
movl %r14d, (%rsp)
movq %rax, -0x50(%rbp)
movq %rax, %r8
movq %r12, -0x58(%rbp)
movl %r12d, %r9d
callq 0x4ef6
subl %r14d, %r13d
movq %r13, -0x70(%rbp)
leal -0x3(%r13), %eax
movl %eax, -0x44(%rbp)
cmpl $0x2, %eax
jl 0xbe35
movl $0x1, -0x2c(%rbp)
movq $0x0, -0x38(%rbp)
leaq -0xc8(%rbp), %r15
movq %rbx, -0x40(%rbp)
movl $0x4, %r13d
movq %r15, %rbx
leal -0x3(%r13), %r14d
movl $0xb, %ecx
movq %rsp, %rdi
leaq 0x10(%rbp), %r15
movq %r15, %rsi
rep  movsq (%rsi), %es:(%rdi)
movl -0x2c(%rbp), %edi
movl %r14d, %esi
callq 0xa4c5
testl %eax, %eax
je 0xbe10
movl $0xb, %ecx
movq %rsp, %rdi
movq %r15, %rsi
rep  movsq (%rsi), %es:(%rdi)
movq %rbx, %r15
movq %rbx, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0xa621
leaq 0xc0(%rbp), %rax
cmpl $0x736579, 0xe9e(%rax)  # imm = 0x736579
jne 0xbd72
movl $0xb, %ecx
movq %rsp, %rdi
leaq 0x10(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
movl -0x2c(%rbp), %edi
movl %r14d, %esi
movq -0x50(%rbp), %rdx
movq -0x60(%rbp), %rcx
callq 0x8016
testl %eax, %eax
je 0xbe13
movq %r15, %rsi
movl -0x2c(%rbp), %r12d
movl %r12d, %edx
movl %r14d, %ecx
callq 0x8e8a
movl $0xb, %ecx
movq %rsp, %rdi
leaq 0x68(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
movq %r15, %rdi
xorl %esi, %esi
movl $0x1, %edx
callq 0xb80c
movq -0xc0(%rbp), %rdi
movq -0x68(%rbp), %rsi
movq -0x58(%rbp), %rdx
leaq -0x128(%rbp), %rcx
callq 0x8d82
movq -0x38(%rbp), %rcx
incl %ecx
movsd -0x128(%rbp), %xmm0
movsd -0x118(%rbp), %xmm1
movq -0xf8(%rbp), %rax
movq %rcx, -0x38(%rbp)
movslq %ecx, %rcx
imulq $0xa8, %rcx, %rcx
movq -0x40(%rbp), %rbx
movsd %xmm0, 0x20(%rbx,%rcx)
movq %rax, 0x50(%rbx,%rcx)
movsd %xmm1, 0x30(%rbx,%rcx)
movl $0x1, (%rbx,%rcx)
movl %r12d, 0x4(%rbx,%rcx)
movl %r14d, 0x8(%rbx,%rcx)
jmp 0xbe17
movq %rbx, %r15
movq -0x40(%rbp), %rbx
incl %r13d
cmpl %r13d, -0x70(%rbp)
jne 0xbcec
movl -0x2c(%rbp), %eax
incl %eax
movl %eax, -0x2c(%rbp)
cmpl -0x44(%rbp), %eax
jne 0xbce6
leaq -0x128(%rbp), %rdi
movq -0x58(%rbp), %rsi
callq 0xb9fb
movq -0x38(%rbp), %r15
testl %r15d, %r15d
leaq 0x10(%rbp), %r12
movq -0x50(%rbp), %r13
jle 0xbe85
movl %r15d, %r14d
addq $0xa8, %rbx
movl $0xb, %ecx
movq %rsp, %rdi
movq %r12, %rsi
rep  movsq (%rsi), %es:(%rdi)
movq %rbx, %rdi
movq %r13, %rsi
callq 0xa1f8
addq $0xa8, %rbx
decq %r14
jne 0xbe60
movl %r15d, %eax
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq