// File: /workspace/github_cpp_makefile_star2_O2/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1c8, %rsp            # imm = 0x1C8
movq %r8, %rbx
movl %ecx, -0x34(%rbp)
movq %rdx, -0x40(%rbp)
movq %rsi, -0x60(%rbp)
movq %rdi, -0x58(%rbp)
leaq 0x10(%rbp), %r12
pushq $0x1
popq %rcx
leaq -0x50(%rbp), %rax
movl %ecx, (%rax)
leaq -0xc8(%rbp), %rax
andq $0x0, 0x8(%rax)
xorps %xmm0, %xmm0
andq $0x0, 0x38(%rax)
movups %xmm0, 0x28(%rax)
orl $-0x1, 0x20(%rax)
movl (%r12), %r14d
orl $-0x1, (%rax)
andl $0x0, 0x48(%rax)
movups %xmm0, 0x10(%rax)
leaq -0x188(%rbp), %r15
movq %r15, %rdi
movl %r14d, %esi
callq 0xa979
leaq -0x128(%rbp), %rdi
movl %r14d, %esi
callq 0xa979
movq 0x8(%r12), %r13
leaq 0x68(%rbp), %rax
movq 0x8(%rax), %r12
movq %r13, %rdi
movq %r12, %rsi
movl %r14d, %edx
movq %r15, %rcx
callq 0x7f5c
movq %r13, %rdi
movq %r12, -0x68(%rbp)
movq %r12, %rsi
movl %r14d, -0x30(%rbp)
movl %r14d, %edx
leaq -0x128(%rbp), %rcx
callq 0x7f5c
leaq 0x10(%rbp), %r13
movsd (%r15), %xmm0
movsd 0x10(%r15), %xmm1
movq 0x30(%r15), %rax
movsd %xmm0, 0x20(%rbx)
movq %rax, 0x50(%rbx)
movsd %xmm1, 0x30(%rbx)
movq %rbx, -0x70(%rbp)
pushq $0x1
popq %r14
movl %r14d, (%rbx)
xorl %r12d, %r12d
pushq $0xb
popq %r15
cmpl -0x34(%rbp), %r14d
jg 0xb504
pushq $0x1
popq %rbx
cmpl -0x34(%rbp), %ebx
jg 0xb4fc
movl %r12d, -0x2c(%rbp)
movslq %r14d, %r12
movq -0x40(%rbp), %rcx
movl (%rcx,%r12,4), %eax
movslq %ebx, %rdx
movq %rdx, -0x48(%rbp)
movl (%rcx,%rdx,4), %edx
movq %r15, %rcx
movq %rsp, %rdi
movq %r13, %rsi
rep  movsq (%rsi), %es:(%rdi)
movl %eax, %edi
movl %edx, %esi
callq 0x9610
testl %eax, %eax
sete %al
cmpl %ebx, %r12d
sete %cl
orb %al, %cl
je 0xb3b4
movl -0x2c(%rbp), %r12d
jmp 0xb4d6
movq %r15, %rcx
movq %rsp, %rdi
movq %r13, %rsi
rep  movsq (%rsi), %es:(%rdi)
leaq -0xc8(%rbp), %r13
movq %r13, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x976c
leaq 0xf5e(%rbp), %rax
cmpl $0x736579, (%rax)       # imm = 0x736579
jne 0xb417
movq -0x40(%rbp), %rcx
movl (%rcx,%r12,4), %eax
movq -0x48(%rbp), %rdx
movl (%rcx,%rdx,4), %edx
movq %r15, %rcx
movq %rsp, %rdi
leaq 0x10(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
movl %eax, %edi
movl %edx, %esi
movq -0x58(%rbp), %rdx
movq -0x60(%rbp), %rcx
callq 0x735d
testl %eax, %eax
je 0xb4f2
movl %r14d, -0x4c(%rbp)
movq -0x40(%rbp), %r14
movl (%r14,%r12,4), %edx
movq -0x48(%rbp), %rax
movl (%r14,%rax,4), %ecx
movq %r13, %rsi
callq 0x804e
movq %r15, %rcx
movq %rsp, %rdi
leaq 0x68(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
movq %r13, %rdi
xorl %esi, %esi
pushq $0x1
popq %rdx
callq 0xa854
movq -0xc0(%rbp), %rdi
movq -0x68(%rbp), %rsi
movl -0x30(%rbp), %edx
leaq -0x188(%rbp), %r13
movq %r13, %rcx
callq 0x7f5c
movl (%r14,%r12,4), %eax
movq -0x48(%rbp), %rcx
movl (%r14,%rcx,4), %r8d
pushq $0xc
popq %rcx
movq %rsp, %rdi
movq %r13, %rsi
rep  movsq (%rsi), %es:(%rdi)
andl $0x0, 0x60(%rsp)
leaq -0x50(%rbp), %rdi
leaq 0x4bc(%rbp), %rsi
movq -0x70(%rbp), %r14
movq %r14, %rdx
movl %eax, %ecx
xorl %r9d, %r9d
callq 0x9471
movl %eax, %r12d
addl -0x2c(%rbp), %r12d
cmpl $0x0, 0x50(%r14)
je 0xb4c3
movsd 0x30(%r14), %xmm0
ucomisd 0x8bb1(%rip), %xmm0     # 0x14070
jne 0xb4dd
jp 0xb4dd
movl $0xf423f, %ebx          # imm = 0xF423F
movl $0xf423f, %r14d         # imm = 0xF423F
leaq 0x10(%rbp), %r13
pushq $0xb
popq %r15
incl %ebx
jmp 0xb365
cmpl $0x0, 0x54(%r14)
je 0xb4c3
leaq 0x10(%rbp), %r13
pushq $0xb
popq %r15
movl -0x4c(%rbp), %r14d
jmp 0xb4d6
movl -0x2c(%rbp), %r12d
leaq 0x10(%rbp), %r13
jmp 0xb4d6
incl %r14d
jmp 0xb358
leaq -0x188(%rbp), %rdi
movl -0x30(%rbp), %ebx
movl %ebx, %esi
callq 0xaa34
leaq -0x128(%rbp), %rdi
movl %ebx, %esi
callq 0xaa34
leaq -0xc8(%rbp), %rdi
movl (%rdi), %esi
callq 0xa1b9
movl %r12d, %eax
addq $0x1c8, %rsp            # imm = 0x1C8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq