// File: dcarrey[P]hgt-detection/./fonctions.cpp
// Function: findBestHGT_nombreLimite(DescTree*, DescTree*, int*, int, InputTree, InputTree, Parameters, HGT*)
int findBestHGT_nombreLimite(struct DescTree *DTSpecies,struct DescTree *DTGene,int * tab_branches,int nb_branches,struct InputTree SpeciesTree,struct InputTree GeneTree,struct Parameters param,struct HGT *aHGT){

	struct InputTree tmpTree;
	int i,j,k,l,first=1,ret=0;
	int size = SpeciesTree.size;
	int ktSpecies;
	struct CRITERIA aCrit,aCritRef;
	
	initInputTree(&tmpTree);

	//printf("\ndebut findBestHgt");
	//== compute criteria
	InitCriteria(&aCrit,size);
	InitCriteria(&aCritRef,size);
	computeCriteria(SpeciesTree.ADD,GeneTree.ADD,size,&aCrit,SpeciesTree.LONGUEUR,SpeciesTree.ARETE,GeneTree.LONGUEUR,GeneTree.ARETE);
	computeCriteria(SpeciesTree.ADD,GeneTree.ADD,size,&aCritRef,SpeciesTree.LONGUEUR,SpeciesTree.ARETE,GeneTree.LONGUEUR,GeneTree.ARETE);
	loadCriteria(aCrit,aHGT);

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

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

	/*for(i=1;i<=2*SpeciesTree.size-3-SpeciesTree.kt;i++)
		printf("\n%d-%d -->%lf",SpeciesTree.ARETE[2*i-1],SpeciesTree.ARETE[2*i-2],SpeciesTree.LONGUEUR[i-1]);
	printf("\n");*/

	//== Test all possible HGT
	for(i=1;i<=nb_branches;i++){
		for(j=1;j<=nb_branches;j++){
			if(isAValidHGT(SpeciesTree,tab_branches[i],tab_branches[j])==1 && i!=j ){
				//printf("\n%d-%d -->%d--%d",SpeciesTree.ARETE[2*tab_branches[i]-1],SpeciesTree.ARETE[2*tab_branches[i]-2],SpeciesTree.ARETE[2*tab_branches[j]-1],SpeciesTree.ARETE[2*tab_branches[j]-2]);
			
				copyInputTree(&tmpTree,SpeciesTree,0,0);

				if(strcmp(param.subtree,"yes") == 0)
					if(TestSubTreeConstraint(SpeciesTree,tab_branches[i],tab_branches[j],DTSpecies,DTGene) == 0) {
						continue;
						//FreeMemory_InputTree(&tmpTree);
						tmpTree.ADD = NULL;
						tmpTree.ARETE = NULL;
						
					}

				applyHGT(GeneTree.ADD,&tmpTree,tab_branches[i],tab_branches[j]);
				AdjustBranchLength(&tmpTree,GeneTree,0,1);
	
				computeCriteria(tmpTree.ADD,GeneTree.ADD,size,&aCrit,tmpTree.LONGUEUR,tmpTree.ARETE,GeneTree.LONGUEUR,GeneTree.ARETE);

				ret += TestCriterionAndUpdate(&first,param.criterion,aCrit,aHGT,tab_branches[i],tab_branches[j],0,0);
				if(aHGT->crit.RF == 0 /*|| aHGT->crit.LS < epsilon */|| aHGT->crit.BD == 0 || aHGT->crit.QD == 0) { i=j=(int)INFINI;}

			}
		}
		
	}
	/*if(ret > 0 )
		findListSpecies(aHGT,DTSpecies,SpeciesTree);*/
	
/*	deleteBipartition(DTSpecies,SpeciesTree);
	deleteBipartition(DTGene,GeneTree);*/
	FreeCriteria(&aCrit,size);
	FreeCriteria(&aCritRef,size);
	FreeMemory_InputTree(&tmpTree,tmpTree.size);

	//printf("\nfin findBestHgt");
	return ret;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x410, %rsp            # imm = 0x410
leaq 0xc0(%rbp), %rax
movq %rax, -0x398(%rbp)
leaq 0x68(%rbp), %rax
movq %rax, -0x388(%rbp)
leaq 0x10(%rbp), %rax
movq %rax, -0x390(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
movq %r8, -0x28(%rbp)
movl $0x1, -0x94(%rbp)
movl $0x0, -0x98(%rbp)
movl (%rax), %eax
movl %eax, -0x9c(%rbp)
leaq -0x80(%rbp), %rdi
callq 0xd040
movl -0x9c(%rbp), %esi
leaq -0x100(%rbp), %rdi
callq 0x14520
movl -0x9c(%rbp), %esi
leaq -0x160(%rbp), %rdi
callq 0x14520
movq -0x390(%rbp), %rcx
movq -0x388(%rbp), %rax
movq 0x8(%rcx), %rdi
movq 0x8(%rax), %rsi
movl -0x9c(%rbp), %edx
movq 0x38(%rcx), %r8
movq 0x30(%rcx), %r9
movq 0x38(%rax), %r10
movq 0x30(%rax), %rax
leaq -0x100(%rbp), %rcx
movq %r10, (%rsp)
movq %rax, 0x8(%rsp)
callq 0xea10
movq -0x390(%rbp), %rcx
movq -0x388(%rbp), %rax
movq 0x8(%rcx), %rdi
movq 0x8(%rax), %rsi
movl -0x9c(%rbp), %edx
movq 0x38(%rcx), %r8
movq 0x30(%rcx), %r9
movq 0x38(%rax), %r10
movq 0x30(%rax), %rax
leaq -0x160(%rbp), %rcx
movq %r10, (%rsp)
movq %rax, 0x8(%rsp)
callq 0xea10
leaq -0x1c0(%rbp), %rdi
leaq -0x100(%rbp), %rsi
movl $0x60, %edx
callq 0x1070
movq -0x28(%rbp), %rdi
movups -0x170(%rbp), %xmm0
movq %rsp, %rax
movups %xmm0, 0x50(%rax)
movups -0x180(%rbp), %xmm0
movups %xmm0, 0x40(%rax)
movups -0x1c0(%rbp), %xmm0
movups -0x1b0(%rbp), %xmm1
movups -0x1a0(%rbp), %xmm2
movups -0x190(%rbp), %xmm3
movups %xmm3, 0x30(%rax)
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
callq 0xe9c0
movl $0x1, -0x84(%rbp)
movl -0x84(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jg 0x15c6b
movl $0x1, -0x88(%rbp)
movl -0x88(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jg 0x15c55
movq -0x390(%rbp), %rsi
leaq -0x218(%rbp), %rdi
movl $0x58, %edx
callq 0x1070
movq -0x18(%rbp), %rax
movslq -0x84(%rbp), %rcx
movl (%rax,%rcx,4), %edi
movq -0x18(%rbp), %rax
movslq -0x88(%rbp), %rcx
movl (%rax,%rcx,4), %esi
movq -0x1c8(%rbp), %rcx
movq %rsp, %rax
movq %rcx, 0x50(%rax)
movups -0x1d8(%rbp), %xmm0
movups %xmm0, 0x40(%rax)
movups -0x218(%rbp), %xmm0
movups -0x208(%rbp), %xmm1
movups -0x1f8(%rbp), %xmm2
movups -0x1e8(%rbp), %xmm3
movups %xmm3, 0x30(%rax)
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
callq 0x12050
cmpl $0x1, %eax
jne 0x15c3f
movl -0x84(%rbp), %eax
cmpl -0x88(%rbp), %eax
je 0x15c3f
movq -0x390(%rbp), %rsi
leaq -0x270(%rbp), %rdi
movl $0x58, %edx
callq 0x1070
xorl %eax, %eax
movq -0x220(%rbp), %rcx
movq %rsp, %rax
movq %rcx, 0x50(%rax)
movups -0x230(%rbp), %xmm0
movups %xmm0, 0x40(%rax)
movups -0x270(%rbp), %xmm0
movups -0x260(%rbp), %xmm1
movups -0x250(%rbp), %xmm2
movups -0x240(%rbp), %xmm3
movups %xmm3, 0x30(%rax)
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
leaq -0x80(%rbp), %rdi
xorl %edx, %edx
movl %edx, %esi
callq 0x12530
movq -0x398(%rbp), %rdi
addq $0xe9e, %rdi            # imm = 0xE9E
leaq 0x1000f(%rip), %rsi     # 0x259db
callq 0x1130
cmpl $0x0, %eax
jne 0x15a6b
movq -0x390(%rbp), %rsi
leaq -0x2c8(%rbp), %rdi
movl $0x58, %edx
callq 0x1070
movq -0x18(%rbp), %rax
movslq -0x84(%rbp), %rcx
movl (%rax,%rcx,4), %edi
movq -0x18(%rbp), %rax
movslq -0x88(%rbp), %rcx
movl (%rax,%rcx,4), %esi
movq -0x8(%rbp), %rdx
movq -0x10(%rbp), %rcx
movq -0x278(%rbp), %r8
movq %rsp, %rax
movq %r8, 0x50(%rax)
movups -0x288(%rbp), %xmm0
movups %xmm0, 0x40(%rax)
movups -0x2c8(%rbp), %xmm0
movups -0x2b8(%rbp), %xmm1
movups -0x2a8(%rbp), %xmm2
movups -0x298(%rbp), %xmm3
movups %xmm3, 0x30(%rax)
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
callq 0xd5f0
cmpl $0x0, %eax
jne 0x15a69
jmp 0x15c41
jmp 0x15a6b
movq -0x388(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x18(%rbp), %rax
movslq -0x84(%rbp), %rcx
movl (%rax,%rcx,4), %edx
movq -0x18(%rbp), %rax
movslq -0x88(%rbp), %rcx
movl (%rax,%rcx,4), %ecx
leaq -0x80(%rbp), %rsi
callq 0xec00
movq -0x388(%rbp), %rsi
leaq -0x320(%rbp), %rdi
movl $0x58, %edx
callq 0x1070
xorl %eax, %eax
movq -0x2d0(%rbp), %rcx
movq %rsp, %rax
movq %rcx, 0x50(%rax)
movups -0x2e0(%rbp), %xmm0
movups %xmm0, 0x40(%rax)
movups -0x320(%rbp), %xmm0
movups -0x310(%rbp), %xmm1
movups -0x300(%rbp), %xmm2
movups -0x2f0(%rbp), %xmm3
movups %xmm3, 0x30(%rax)
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
leaq -0x80(%rbp), %rdi
xorl %esi, %esi
movl $0x1, %edx
callq 0x14340
movq -0x388(%rbp), %rax
movq -0x78(%rbp), %rdi
movq 0x8(%rax), %rsi
movl -0x9c(%rbp), %edx
movq -0x48(%rbp), %r8
movq -0x50(%rbp), %r9
movq 0x38(%rax), %r10
movq 0x30(%rax), %rax
leaq -0x100(%rbp), %rcx
movq %r10, (%rsp)
movq %rax, 0x8(%rsp)
callq 0xea10
movq -0x398(%rbp), %rax
addq $0x3fc, %rax            # imm = 0x3FC
movq %rax, -0x3a0(%rbp)
leaq -0x380(%rbp), %rdi
leaq -0x100(%rbp), %rsi
movl $0x60, %edx
callq 0x1070
movq -0x3a0(%rbp), %rsi
movq -0x28(%rbp), %rdx
movq -0x18(%rbp), %rax
movslq -0x84(%rbp), %rcx
movl (%rax,%rcx,4), %ecx
movq -0x18(%rbp), %rax
movslq -0x88(%rbp), %rdi
movl (%rax,%rdi,4), %r8d
xorl %eax, %eax
movups -0x330(%rbp), %xmm0
movq %rsp, %rax
movups %xmm0, 0x50(%rax)
movups -0x340(%rbp), %xmm0
movups %xmm0, 0x40(%rax)
movups -0x380(%rbp), %xmm0
movups -0x370(%rbp), %xmm1
movups -0x360(%rbp), %xmm2
movups -0x350(%rbp), %xmm3
movups %xmm3, 0x30(%rax)
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
movl $0x0, 0x60(%rax)
leaq -0x94(%rbp), %rdi
xorl %r9d, %r9d
callq 0x11df0
addl -0x98(%rbp), %eax
movl %eax, -0x98(%rbp)
movq -0x28(%rbp), %rax
cmpl $0x0, 0x50(%rax)
je 0x15c29
movq -0x28(%rbp), %rax
movsd 0x30(%rax), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x15c1f
jp 0x15c1f
jmp 0x15c29
movq -0x28(%rbp), %rax
cmpl $0x0, 0x54(%rax)
jne 0x15c3d
movl $0xf423f, -0x88(%rbp)   # imm = 0xF423F
movl $0xf423f, -0x84(%rbp)   # imm = 0xF423F
jmp 0x15c3f
jmp 0x15c41
movl -0x88(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x88(%rbp)
jmp 0x158a5
jmp 0x15c57
movl -0x84(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x84(%rbp)
jmp 0x1588c
movl -0x9c(%rbp), %esi
leaq -0x100(%rbp), %rdi
callq 0x14650
movl -0x9c(%rbp), %esi
leaq -0x160(%rbp), %rdi
callq 0x14650
movl -0x80(%rbp), %esi
leaq -0x80(%rbp), %rdi
callq 0x13810
movl -0x98(%rbp), %eax
addq $0x410, %rsp            # imm = 0x410
popq %rbp
retq
nopw (%rax,%rax)