// File: tplinderoth[P]introDist/introDist.cpp
// Function: avgIndPopDist(std::basic_fstream<char, std::char_traits<char>>&, std::basic_fstream<char, std::char_traits<char>>&)
int avgIndPopDist (std::fstream &freqfile, std::fstream &genofile) {
	/*
	 * this calculates the genetic distance between an individual and population2
	 * D = 1/N_G * sum_from=1_to=N_G |g_i - E[g_p2]|/2
	 * where N_G is the number of sites in the genome
	 */

	if (!freqfile) {
		std::cerr << "No allele frequency file stream in call to avgIndPopDist\n";
		return -1;
	}

	if (!genofile) {
		std::cerr << "No genotype file stream in call to avgIndPopDist\n";
		return -1;
	}

	std::stringstream ss;

	std::string(fline);
	std::string(fchr);
	unsigned int fpos;
	double p1f = 0.0;
	double p2f = 0.0;

	std::string(gline);
	std::string(gchr);
	unsigned int gpos;
	double geno;

	double dist = 0.0;
	unsigned int nsites = 0;

	getline(freqfile, fline);
	getline(genofile, gline);

	while (!fline.empty()) {
		// parse frequency file line
		ss.str(std::string());
		ss.clear();
		ss.str(fline);
		ss >> fchr >> fpos >> p1f >> p2f;

		// parse genotype file line
		ss.str(std::string());
		ss.clear();
		ss.str(gline);
		ss >> gchr >> gpos >> geno;

		if (gchr.compare(fchr) != 0 || gpos != fpos) {
			std::cerr << "Positions in input files differ\n";
			return -1;
		}

		if (geno >= 0) {
			// update distance statistic
			dist += expectIndPopDist(geno, p2f);
			++nsites;
		}

		getline(freqfile, fline);
		getline(genofile, gline);
	}

	// print distance
	dist /= double(nsites);
	std::cout << dist << "\t" << nsites << "\n";

	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x320, %rsp            # imm = 0x320
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x10(%rbp), %rdi
movq (%rdi), %rax
addq -0x18(%rax), %rdi
callq 0x3170
testb $0x1, %al
jne 0x5e29
jmp 0x5e48
movq 0xf1c0(%rip), %rdi      # 0x14ff0
leaq 0x94ee(%rip), %rsi      # 0xf325
callq 0x32c0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x62fd
movq -0x18(%rbp), %rdi
movq (%rdi), %rax
addq -0x18(%rax), %rdi
callq 0x3170
testb $0x1, %al
jne 0x5e5e
jmp 0x5e7d
movq 0xf18b(%rip), %rdi      # 0x14ff0
leaq 0x94f3(%rip), %rsi      # 0xf35f
callq 0x32c0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x62fd
leaq -0x1a0(%rbp), %rdi
callq 0x31f0
leaq -0x1c0(%rbp), %rdi
movq %rdi, -0x2b8(%rbp)
callq 0x33d0
leaq -0x1e0(%rbp), %rdi
callq 0x33d0
movq $0x0, -0x1f0(%rbp)
movq $0x0, -0x1f8(%rbp)
leaq -0x218(%rbp), %rdi
callq 0x33d0
leaq -0x238(%rbp), %rdi
callq 0x33d0
movq -0x2b8(%rbp), %rsi
movq $0x0, -0x250(%rbp)
movl $0x0, -0x254(%rbp)
movq -0x10(%rbp), %rdi
callq 0x30b0
jmp 0x5efd
movq -0x18(%rbp), %rdi
leaq -0x218(%rbp), %rsi
callq 0x30b0
jmp 0x5f0f
jmp 0x5f11
leaq -0x1c0(%rbp), %rdi
callq 0x3470
xorb $-0x1, %al
testb $0x1, %al
jne 0x5f28
jmp 0x61e8
leaq -0x288(%rbp), %rdi
movq %rdi, -0x2c0(%rbp)
callq 0x33d0
movq -0x2c0(%rbp), %rsi
leaq -0x1a0(%rbp), %rdi
callq 0x3340
jmp 0x5f50
leaq -0x288(%rbp), %rdi
callq 0x31b0
movq -0x1a0(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x1a0(%rbp,%rax), %rdi
xorl %esi, %esi
callq 0x3480
jmp 0x5f78
leaq -0x1a0(%rbp), %rdi
leaq -0x1c0(%rbp), %rsi
callq 0x3340
jmp 0x5f8d
leaq -0x1a0(%rbp), %rdi
leaq -0x1e0(%rbp), %rsi
callq 0x33a0
movq %rax, -0x2c8(%rbp)
jmp 0x5fa9
movq -0x2c8(%rbp), %rdi
leaq -0x1e4(%rbp), %rsi
callq 0x3060
movq %rax, -0x2d0(%rbp)
jmp 0x5fc5
movq -0x2d0(%rbp), %rdi
leaq -0x1f0(%rbp), %rsi
callq 0x3250
movq %rax, -0x2d8(%rbp)
jmp 0x5fe1
movq -0x2d8(%rbp), %rdi
leaq -0x1f8(%rbp), %rsi
callq 0x3250
jmp 0x5ff6
leaq -0x2a8(%rbp), %rdi
movq %rdi, -0x2e0(%rbp)
callq 0x33d0
movq -0x2e0(%rbp), %rsi
leaq -0x1a0(%rbp), %rdi
callq 0x3340
jmp 0x601e
leaq -0x2a8(%rbp), %rdi
callq 0x31b0
movq -0x1a0(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x1a0(%rbp,%rax), %rdi
xorl %esi, %esi
callq 0x3480
jmp 0x6046
leaq -0x1a0(%rbp), %rdi
leaq -0x218(%rbp), %rsi
callq 0x3340
jmp 0x605b
leaq -0x1a0(%rbp), %rdi
leaq -0x238(%rbp), %rsi
callq 0x33a0
movq %rax, -0x2e8(%rbp)
jmp 0x6077
movq -0x2e8(%rbp), %rdi
leaq -0x23c(%rbp), %rsi
callq 0x3060
movq %rax, -0x2f0(%rbp)
jmp 0x6093
movq -0x2f0(%rbp), %rdi
leaq -0x248(%rbp), %rsi
callq 0x3250
jmp 0x60a8
leaq -0x238(%rbp), %rdi
leaq -0x1e0(%rbp), %rsi
callq 0x3040
movl %eax, -0x2f4(%rbp)
jmp 0x60c3
movl -0x2f4(%rbp), %eax
cmpl $0x0, %eax
jne 0x60e0
movl -0x23c(%rbp), %eax
cmpl -0x1e4(%rbp), %eax
je 0x6168
movq 0xef09(%rip), %rdi      # 0x14ff0
leaq 0x92a3(%rip), %rsi      # 0xf391
callq 0x32c0
jmp 0x60f5
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
movl $0x1, -0x2ac(%rbp)
jmp 0x6281
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x260(%rbp)
movl %eax, -0x264(%rbp)
jmp 0x62bf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x260(%rbp)
movl %eax, -0x264(%rbp)
leaq -0x288(%rbp), %rdi
callq 0x31b0
jmp 0x62bf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x260(%rbp)
movl %eax, -0x264(%rbp)
leaq -0x2a8(%rbp), %rdi
callq 0x31b0
jmp 0x62bf
movsd -0x248(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jb 0x61bf
movsd -0x248(%rbp), %xmm0
movsd -0x1f8(%rbp), %xmm1
callq 0x63d0
movsd %xmm0, -0x300(%rbp)
jmp 0x6198
movsd -0x300(%rbp), %xmm0
addsd -0x250(%rbp), %xmm0
movsd %xmm0, -0x250(%rbp)
movl -0x254(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x254(%rbp)
movq -0x10(%rbp), %rdi
leaq -0x1c0(%rbp), %rsi
callq 0x30b0
jmp 0x61d1
movq -0x18(%rbp), %rdi
leaq -0x218(%rbp), %rsi
callq 0x30b0
jmp 0x61e3
jmp 0x5f11
movl -0x254(%rbp), %eax
cvtsi2sd %rax, %xmm1
movsd -0x250(%rbp), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, -0x250(%rbp)
movsd -0x250(%rbp), %xmm0
movq 0xedb2(%rip), %rdi      # 0x14fc8
callq 0x3530
movq %rax, -0x308(%rbp)
jmp 0x6224
movq -0x308(%rbp), %rdi
leaq 0x90f1(%rip), %rsi      # 0xf323
callq 0x32c0
movq %rax, -0x310(%rbp)
jmp 0x6240
movq -0x310(%rbp), %rdi
movl -0x254(%rbp), %esi
callq 0x33b0
movq %rax, -0x318(%rbp)
jmp 0x625b
movq -0x318(%rbp), %rdi
leaq 0x9983(%rip), %rsi      # 0xfbec
callq 0x32c0
jmp 0x6270
movl $0x0, -0x4(%rbp)
movl $0x1, -0x2ac(%rbp)
leaq -0x238(%rbp), %rdi
callq 0x31b0
leaq -0x218(%rbp), %rdi
callq 0x31b0
leaq -0x1e0(%rbp), %rdi
callq 0x31b0
leaq -0x1c0(%rbp), %rdi
callq 0x31b0
leaq -0x1a0(%rbp), %rdi
callq 0x3210
jmp 0x62fd
leaq -0x238(%rbp), %rdi
callq 0x31b0
leaq -0x218(%rbp), %rdi
callq 0x31b0
leaq -0x1e0(%rbp), %rdi
callq 0x31b0
leaq -0x1c0(%rbp), %rdi
callq 0x31b0
leaq -0x1a0(%rbp), %rdi
callq 0x3210
jmp 0x6309
movl -0x4(%rbp), %eax
addq $0x320, %rsp            # imm = 0x320
popq %rbp
retq
movq -0x260(%rbp), %rdi
callq 0x34c0
nopw %cs:(%rax,%rax)