// File: /workspace/github_cpp_makefile_star2_O2/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 $0x138, %rsp            # imm = 0x138
movq %rdi, %rbx
leaq 0x68(%rbp), %r15
leaq 0x10(%rbp), %r12
leaq -0x108(%rbp), %rax
andq $0x0, 0x8(%rax)
xorps %xmm0, %xmm0
andq $0x0, 0x38(%rax)
movups %xmm0, 0x28(%rax)
orl $-0x1, 0x20(%rax)
movslq (%r12), %r13
orl $-0x1, (%rax)
andl $0x0, 0x48(%rax)
movups %xmm0, 0x10(%rax)
leaq -0xb0(%rbp), %rdi
movl %r13d, %esi
callq 0xa979
movslq (%r15), %r14
imulq $0x30, %r14, %rdi
callq 0x1130
movq %rax, %r8
movq 0x30(%r15), %rdi
movq 0x8(%r15), %rsi
movl 0x20(%r15), %edx
movq 0x28(%r15), %rcx
movl 0x48(%r15), %eax
movl %eax, (%rsp)
movq %rsi, -0x50(%rbp)
movq %r8, -0x48(%rbp)
movl %r14d, %r9d
callq 0x4769
leal (,%r13,2), %r15d
imulq $0x30, %r13, %rdi
callq 0x1130
movq 0x30(%r12), %rdi
movq 0x8(%r12), %rsi
movl 0x20(%r12), %edx
movq 0x28(%r12), %rcx
movl 0x48(%r12), %r14d
movl %r14d, (%rsp)
movq %rax, -0x38(%rbp)
movq %rax, %r8
movq %r13, -0x40(%rbp)
movl %r13d, %r9d
callq 0x4769
subl %r14d, %r15d
addl $-0x3, %r15d
movl %r15d, -0x30(%rbp)
movl $0x0, -0x2c(%rbp)
pushq $0x1
popq %r14
pushq $0xb
popq %r13
cmpl -0x30(%rbp), %r14d
jge 0xadff
pushq $0x1
popq %r12
cmpl -0x30(%rbp), %r12d
jge 0xadf3
movq %r13, %rcx
movq %rsp, %rdi
leaq 0x10(%rbp), %r15
movq %r15, %rsi
rep  movsq (%rsi), %es:(%rdi)
movl %r14d, %edi
movl %r12d, %esi
callq 0x9610
testl %eax, %eax
je 0xade7
movq %r13, %rcx
movq %rsp, %rdi
movq %r15, %rsi
rep  movsq (%rsi), %es:(%rdi)
leaq -0x108(%rbp), %r15
movq %r15, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x976c
leaq 0xf5e(%rbp), %rax
cmpl $0x736579, (%rax)       # imm = 0x736579
jne 0xad5c
movq %r13, %rcx
movq %rsp, %rdi
leaq 0x10(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
movl %r14d, %edi
movl %r12d, %esi
movq -0x38(%rbp), %rdx
movq -0x48(%rbp), %rcx
callq 0x735d
testl %eax, %eax
je 0xade7
movq %r15, %rsi
movl %r14d, %edx
movl %r12d, %ecx
callq 0x804e
movq %r13, %rcx
movq %rsp, %rdi
leaq 0x68(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
movq %r15, %rdi
xorl %esi, %esi
pushq $0x1
popq %rdx
callq 0xa854
movq -0x100(%rbp), %rdi
movq -0x50(%rbp), %rsi
movq -0x40(%rbp), %rdx
leaq -0xb0(%rbp), %rcx
callq 0x7f5c
movl -0x2c(%rbp), %ecx
incl %ecx
movsd -0xb0(%rbp), %xmm0
movsd -0xa0(%rbp), %xmm1
movq -0x80(%rbp), %rax
movl %ecx, -0x2c(%rbp)
movslq %ecx, %rcx
imulq $0xa8, %rcx, %rcx
movsd %xmm0, 0x20(%rbx,%rcx)
movq %rax, 0x50(%rbx,%rcx)
movsd %xmm1, 0x30(%rbx,%rcx)
movl $0x1, (%rbx,%rcx)
movl %r14d, 0x4(%rbx,%rcx)
movl %r12d, 0x8(%rbx,%rcx)
incl %r12d
pushq $0xb
popq %r13
jmp 0xacd9
incl %r14d
leaq 0x10(%rbp), %r12
jmp 0xaccb
leaq -0xb0(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0xaa34
xorl %r15d, %r15d
movl -0x2c(%rbp), %eax
testl %eax, %eax
cmovgl %eax, %r15d
addq $0xa8, %rbx
pushq $0xb
popq %r14
subq $0x1, %r15
jb 0xae4d
movq %r14, %rcx
movq %rsp, %rdi
movq %r12, %rsi
rep  movsq (%rsi), %es:(%rdi)
movq %rbx, %rdi
movq -0x38(%rbp), %rsi
callq 0x934f
addq $0xa8, %rbx
jmp 0xae26
movl -0x2c(%rbp), %eax
addq $0x138, %rsp            # imm = 0x138
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq