// File: /workspace/github_c_makefile_star2_O2/waynebhayes[P]SAHap/src/Genome.cpp
// Function: SAHap::Genome::move()
void Genome::move() {
	// Perform a random move, saving enough information so we can revert later

	auto ploidy = this->haplotypes.size();
	size_t moveFrom = rand() % ploidy;
	size_t moveTo;
	// FIXME1: why are we picking the source haplotype FIRST when it's possible there's no
	// reads in it? This while() loop checks for this condition and keeps looping until it finds a haplotype
	// with reads in it... but it's probably better to pick a READ from the entire universe first, the FIND
	// it's haploptype, then choose ANOTHER haplotype to move it to.
	// In any case the current code *should* work... but it's ugly.
	// It's also bad in a WINDOWING system because if the read we pick is one we shouldn't touch, we have to
	// come back all the way to here to start again... which means TWO nested while loops. Very bad.
	// FIXME1: so, pick the read FIRST.
	unsigned numTries = 0;
	while (!this->haplotypes[moveFrom].numReads()) { // chose moveFrom (keep choosing until we find a non-empty haplotype)
		if (ploidy == 2) {
			moveFrom = !moveFrom;
		} else {
			moveFrom = rand() % ploidy;
		}
		assert(numTries++ < 10*ploidy); // this should be MORE than enough to NEVER iterate forever
	}
	// now choose where to move *to* (someplace other than from)
	if (ploidy == 2) {
		moveTo = !moveFrom;
	} else {
		size_t moveOffset = rand() % (ploidy - 1);
		moveTo = (moveFrom + moveOffset + 1) % ploidy;
	}
	assert(moveFrom != moveTo);
	// Move this "pick the read" up above FIXME1, but choose among the entire universe of reads, not just those on
	// "moveFrom". Instead, pick the read, then set moveFrom to it's current haplotype, then choose moveTo as above.
	Read * r = this->haplotypes[moveFrom].randomRead(this->randomEngine);
	// HERE is where you put your code to check if this read shouldn't be touched because it has substantial
	// overlap with the previous window. (And you can make that decision even before looking at it's haplotype.

#if SAHAP_GENOME_DEBUG
	printf("move read %p from %d to %d\n", r, moveFrom, moveTo);
	if (!r) {
		cerr << "DEBUG: Haplotype " << moveFrom << " has no reads remaining" << endl;
		std::raise(SIGINT);
		r = this->haplotypes[moveFrom].randomRead(this->randomEngine);
	}
#endif

	// std::cout << "From: " << moveFrom << ", To: " << moveTo << std::endl;

	this->haplotypes[moveTo].add(r);
	this->haplotypes[moveFrom].remove(r);

	this->lastMove.from = moveFrom;
	this->lastMove.to = moveTo;
	this->lastMove.read = r;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
movq 0x2370(%rdi), %r12
subq 0x2368(%rdi), %r12
movl $0xf8, %ecx
movq %r12, %rax
cqto
idivq %rcx
movq %rax, %r15
callq 0x2070
cltq
xorl %ebp, %ebp
xorl %edx, %edx
divq %r15
movq %rdx, %r14
movq %r15, (%rsp)
imulq $0xa, %r15, %r15
imulq $0xf8, %r14, %r13
movq 0x2368(%rbx), %rdi
addq %r13, %rdi
callq 0x6638
testq %rax, %rax
jne 0x2f02
cmpq $0x1f0, %r12            # imm = 0x1F0
jne 0x2eca
xorl %eax, %eax
testq %r14, %r14
sete %al
movq %rax, %r14
jmp 0x2eda
callq 0x2070
cltq
xorl %edx, %edx
divq (%rsp)
movq %rdx, %r14
movl %ebp, %eax
incl %ebp
cmpq %rax, %r15
ja 0x2e99
leaq 0x7320(%rip), %rdi      # 0xa20a
leaq 0x72d2(%rip), %rsi      # 0xa1c3
leaq 0x7329(%rip), %rcx      # 0xa221
movl $0xe4, %edx
callq 0x2180
cmpq $0x1f0, %r12            # imm = 0x1F0
jne 0x2f17
xorl %r15d, %r15d
testq %r14, %r14
sete %r15b
jmp 0x2f3c
callq 0x2070
cltq
movq (%rsp), %rsi
movq %rsi, %rcx
decq %rcx
xorl %edx, %edx
divq %rcx
leaq (%r14,%rdx), %rax
incq %rax
xorl %edx, %edx
divq %rsi
movq %rdx, %r15
cmpq %r15, %r14
je 0x2fa6
movq 0x2368(%rbx), %rdi
addq %r13, %rdi
leaq 0x2438(%rbx), %rsi
callq 0x6b56
movq %rax, %r12
imulq $0xf8, %r15, %rdi
addq 0x2368(%rbx), %rdi
movq %rax, %rsi
callq 0x6986
addq 0x2368(%rbx), %r13
movq %r13, %rdi
movq %r12, %rsi
callq 0x6a52
movq %r14, 0x3c18(%rbx)
movq %r15, 0x3c20(%rbx)
movq %r12, 0x3c28(%rbx)
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x728f(%rip), %rdi      # 0xa23c
leaq 0x720f(%rip), %rsi      # 0xa1c3
leaq 0x7266(%rip), %rcx      # 0xa221
movl $0xed, %edx
callq 0x2180
nop