// File: 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
subq $0x390, %rsp            # imm = 0x390
leaq 0xc0(%rbp), %rax
movq %rax, -0x318(%rbp)
leaq 0x68(%rbp), %rax
movq %rax, -0x310(%rbp)
leaq 0x10(%rbp), %rax
movq %rax, -0x308(%rbp)
movq %rdi, -0x8(%rbp)
movl $0x0, -0xc(%rbp)
movl (%rax), %eax
movl %eax, -0x78(%rbp)
leaq -0x68(%rbp), %rdi
callq 0xd040
movl -0x78(%rbp), %esi
leaq -0xd8(%rbp), %rdi
callq 0x14520
movq -0x310(%rbp), %rax
movl (%rax), %eax
shll %eax
cltq
imulq $0x18, %rax, %rdi
callq 0x1110
movq %rax, %rcx
movq -0x310(%rbp), %rax
movq %rcx, -0xe8(%rbp)
movq 0x30(%rax), %rdi
movq 0x8(%rax), %rsi
movl 0x20(%rax), %edx
movq 0x28(%rax), %rcx
movq -0xe8(%rbp), %r8
movl (%rax), %r9d
movl 0x48(%rax), %eax
movl %eax, (%rsp)
callq 0x84e0
movq -0x308(%rbp), %rax
movl (%rax), %eax
shll %eax
cltq
imulq $0x18, %rax, %rdi
callq 0x1110
movq %rax, %rcx
movq -0x308(%rbp), %rax
movq %rcx, -0xe0(%rbp)
movq 0x30(%rax), %rdi
movq 0x8(%rax), %rsi
movl 0x20(%rax), %edx
movq 0x28(%rax), %rcx
movq -0xe0(%rbp), %r8
movl (%rax), %r9d
movl 0x48(%rax), %eax
movl %eax, (%rsp)
callq 0x84e0
movl $0x1, -0x6c(%rbp)
movq -0x308(%rbp), %rdx
movl -0x6c(%rbp), %eax
movl -0x78(%rbp), %ecx
shll %ecx
subl $0x3, %ecx
subl 0x48(%rdx), %ecx
cmpl %ecx, %eax
jge 0x14dcf
movl $0x1, -0x70(%rbp)
movq -0x308(%rbp), %rdx
movl -0x70(%rbp), %eax
movl -0x78(%rbp), %ecx
shll %ecx
subl $0x3, %ecx
subl 0x48(%rdx), %ecx
cmpl %ecx, %eax
jge 0x14dbf
movq -0x308(%rbp), %rsi
leaq -0x140(%rbp), %rdi
movl $0x58, %edx
callq 0x1070
movl -0x6c(%rbp), %edi
movl -0x70(%rbp), %esi
movq -0xf0(%rbp), %rcx
movq %rsp, %rax
movq %rcx, 0x50(%rax)
movups -0x100(%rbp), %xmm0
movups %xmm0, 0x40(%rax)
movups -0x140(%rbp), %xmm0
movups -0x130(%rbp), %xmm1
movups -0x120(%rbp), %xmm2
movups -0x110(%rbp), %xmm3
movups %xmm3, 0x30(%rax)
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
callq 0x12050
cmpl $0x1, %eax
jne 0x14daf
movq -0x308(%rbp), %rsi
leaq -0x198(%rbp), %rdi
movl $0x58, %edx
callq 0x1070
xorl %eax, %eax
movq -0x148(%rbp), %rcx
movq %rsp, %rax
movq %rcx, 0x50(%rax)
movups -0x158(%rbp), %xmm0
movups %xmm0, 0x40(%rax)
movups -0x198(%rbp), %xmm0
movups -0x188(%rbp), %xmm1
movups -0x178(%rbp), %xmm2
movups -0x168(%rbp), %xmm3
movups %xmm3, 0x30(%rax)
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
leaq -0x68(%rbp), %rdi
xorl %edx, %edx
movl %edx, %esi
callq 0x12530
movq -0x318(%rbp), %rdi
addq $0xe9e, %rdi            # imm = 0xE9E
leaq 0x10e26(%rip), %rsi     # 0x259db
callq 0x1130
cmpl $0x0, %eax
jne 0x14c44
movq -0x308(%rbp), %rsi
leaq -0x1f0(%rbp), %rdi
movl $0x58, %edx
callq 0x1070
movl -0x6c(%rbp), %edi
movl -0x70(%rbp), %esi
movq -0xe0(%rbp), %rdx
movq -0xe8(%rbp), %rcx
movq -0x1a0(%rbp), %r8
movq %rsp, %rax
movq %r8, 0x50(%rax)
movups -0x1b0(%rbp), %xmm0
movups %xmm0, 0x40(%rax)
movups -0x1f0(%rbp), %xmm0
movups -0x1e0(%rbp), %xmm1
movups -0x1d0(%rbp), %xmm2
movups -0x1c0(%rbp), %xmm3
movups %xmm3, 0x30(%rax)
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
callq 0xd5f0
cmpl $0x0, %eax
jne 0x14c42
jmp 0x14db1
jmp 0x14c44
movq -0x310(%rbp), %rax
movq 0x8(%rax), %rdi
movl -0x6c(%rbp), %edx
movl -0x70(%rbp), %ecx
leaq -0x68(%rbp), %rsi
callq 0xec00
movq -0x310(%rbp), %rsi
leaq -0x248(%rbp), %rdi
movl $0x58, %edx
callq 0x1070
xorl %eax, %eax
movq -0x1f8(%rbp), %rcx
movq %rsp, %rax
movq %rcx, 0x50(%rax)
movups -0x208(%rbp), %xmm0
movups %xmm0, 0x40(%rax)
movups -0x248(%rbp), %xmm0
movups -0x238(%rbp), %xmm1
movups -0x228(%rbp), %xmm2
movups -0x218(%rbp), %xmm3
movups %xmm3, 0x30(%rax)
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
leaq -0x68(%rbp), %rdi
xorl %esi, %esi
movl $0x1, %edx
callq 0x14340
movq -0x310(%rbp), %rax
movq -0x60(%rbp), %rdi
movq 0x8(%rax), %rsi
movl -0x78(%rbp), %edx
movq -0x30(%rbp), %r8
movq -0x38(%rbp), %r9
movq 0x38(%rax), %r10
movq 0x30(%rax), %rax
leaq -0xd8(%rbp), %rcx
movq %r10, (%rsp)
movq %rax, 0x8(%rsp)
callq 0xea10
movl -0xc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xc(%rbp)
leaq -0x2a8(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
movl $0x60, %edx
callq 0x1070
movq -0x8(%rbp), %rdi
movslq -0xc(%rbp), %rax
imulq $0xa8, %rax, %rax
addq %rax, %rdi
movups -0x258(%rbp), %xmm0
movq %rsp, %rax
movups %xmm0, 0x50(%rax)
movups -0x268(%rbp), %xmm0
movups %xmm0, 0x40(%rax)
movups -0x2a8(%rbp), %xmm0
movups -0x298(%rbp), %xmm1
movups -0x288(%rbp), %xmm2
movups -0x278(%rbp), %xmm3
movups %xmm3, 0x30(%rax)
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
callq 0xe9c0
movl -0x6c(%rbp), %ecx
movq -0x8(%rbp), %rax
movslq -0xc(%rbp), %rdx
imulq $0xa8, %rdx, %rdx
addq %rdx, %rax
movl %ecx, 0x4(%rax)
movl -0x70(%rbp), %ecx
movq -0x8(%rbp), %rax
movslq -0xc(%rbp), %rdx
imulq $0xa8, %rdx, %rdx
addq %rdx, %rax
movl %ecx, 0x8(%rax)
jmp 0x14db1
movl -0x70(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x70(%rbp)
jmp 0x14aa8
jmp 0x14dc1
movl -0x6c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x6c(%rbp)
jmp 0x14a84
movl -0x78(%rbp), %esi
leaq -0xd8(%rbp), %rdi
callq 0x14650
movl $0x1, -0x6c(%rbp)
movl -0x6c(%rbp), %eax
cmpl -0xc(%rbp), %eax
jg 0x14e95
movq -0x308(%rbp), %rsi
movq -0x8(%rbp), %rax
movslq -0x6c(%rbp), %rcx
imulq $0xa8, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x328(%rbp)
movq -0xe0(%rbp), %rax
movq %rax, -0x320(%rbp)
leaq -0x300(%rbp), %rdi
movl $0x58, %edx
callq 0x1070
movq -0x328(%rbp), %rdi
movq -0x320(%rbp), %rsi
movq -0x2b0(%rbp), %rcx
movq %rsp, %rax
movq %rcx, 0x50(%rax)
movups -0x2c0(%rbp), %xmm0
movups %xmm0, 0x40(%rax)
movups -0x300(%rbp), %xmm0
movups -0x2f0(%rbp), %xmm1
movups -0x2e0(%rbp), %xmm2
movups -0x2d0(%rbp), %xmm3
movups %xmm3, 0x30(%rax)
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
callq 0x11b40
movl -0x6c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x6c(%rbp)
jmp 0x14de5
movl -0xc(%rbp), %eax
addq $0x390, %rsp            # imm = 0x390
popq %rbp
retq
nopw %cs:(%rax,%rax)