// File: /workspace/github_c_makefile_star2_O0/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
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x40(%rbp)
addq $0x2368, %rdi           # imm = 0x2368
callq 0x5ae0
movq %rax, -0x10(%rbp)
callq 0x2080
cltq
xorl %ecx, %ecx
movl %ecx, %edx
divq -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movl $0x0, -0x24(%rbp)
movq -0x40(%rbp), %rdi
addq $0x2368, %rdi           # imm = 0x2368
movq -0x18(%rbp), %rsi
callq 0x5b10
movq %rax, %rdi
callq 0x10880
cmpq $0x0, %rax
setne %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x34f9
jmp 0x3565
cmpq $0x2, -0x10(%rbp)
jne 0x3515
cmpq $0x0, -0x18(%rbp)
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movq %rax, -0x18(%rbp)
jmp 0x3528
callq 0x2080
cltq
xorl %ecx, %ecx
movl %ecx, %edx
divq -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movl -0x24(%rbp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, -0x24(%rbp)
movl %eax, %eax
imulq $0xa, -0x10(%rbp), %rcx
cmpq %rcx, %rax
jae 0x3541
jmp 0x3560
leaq 0x18c5a(%rip), %rdi     # 0x1c1a2
leaq 0x18c0c(%rip), %rsi     # 0x1c15b
movl $0xe4, %edx
leaq 0x18c5e(%rip), %rcx     # 0x1c1b9
callq 0x2180
jmp 0x34ce
cmpq $0x2, -0x10(%rbp)
jne 0x3581
cmpq $0x0, -0x18(%rbp)
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movq %rax, -0x20(%rbp)
jmp 0x35b1
callq 0x2080
cltq
movq -0x10(%rbp), %rcx
subq $0x1, %rcx
xorl %edx, %edx
divq %rcx
movq %rdx, -0x30(%rbp)
movq -0x18(%rbp), %rax
addq -0x30(%rbp), %rax
addq $0x1, %rax
xorl %ecx, %ecx
movl %ecx, %edx
divq -0x10(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x18(%rbp), %rax
cmpq -0x20(%rbp), %rax
je 0x35bd
jmp 0x35dc
leaq 0x18c10(%rip), %rdi     # 0x1c1d4
leaq 0x18b90(%rip), %rsi     # 0x1c15b
movl $0xed, %edx
leaq 0x18be2(%rip), %rcx     # 0x1c1b9
callq 0x2180
movq -0x40(%rbp), %rdi
addq $0x2368, %rdi           # imm = 0x2368
movq -0x18(%rbp), %rsi
callq 0x5b10
movq -0x40(%rbp), %rsi
movq %rax, %rdi
addq $0x2438, %rsi           # imm = 0x2438
callq 0x11260
movq -0x40(%rbp), %rdi
movq %rax, -0x38(%rbp)
addq $0x2368, %rdi           # imm = 0x2368
movq -0x20(%rbp), %rsi
callq 0x5b10
movq %rax, %rdi
movq -0x38(%rbp), %rsi
callq 0x10f90
movq -0x40(%rbp), %rdi
addq $0x2368, %rdi           # imm = 0x2368
movq -0x18(%rbp), %rsi
callq 0x5b10
movq %rax, %rdi
movq -0x38(%rbp), %rsi
callq 0x11100
movq -0x40(%rbp), %rax
movq -0x18(%rbp), %rcx
movq %rcx, 0x3c18(%rax)
movq -0x20(%rbp), %rcx
movq %rcx, 0x3c20(%rax)
movq -0x38(%rbp), %rcx
movq %rcx, 0x3c28(%rax)
addq $0x40, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)