// File: Altius[P]hotspot2/src/findVarWidthPeaks.cpp
// Function: processRegionAndFlushIt(Region&, long const&, std::vector<Range, std::allocator<Range>>&)
void processRegionAndFlushIt(Region& reg, const long& minWidth, vector<Range>& peaks)
{
  if (reg.localMaxima.empty())
    {
      if (!reg.posns.empty())
	reg.posns.clear();
      return;
    }

  reg.localMaxima.sort(Height_GT);
  // Local maxima are now sorted in descending order by y-value (height), if there are 2 or more of them.
  // Local maxima with equal y-values, if any, are sorted from L to R in genomic order.
  // We traverse the list of local maxima in this order, tracing the shape of each down to half of its maximum.
  list<Range>::iterator it1 = reg.localMaxima.begin(), it2;
  while (it1 != reg.localMaxima.end())
    {
      int idxL(it1->beg.idx), idxR(it1->end.idx);
 
      it1->maxY = it1->beg.y;
      it1->x_of_maxY = static_cast<int>(floor(0.5*static_cast<double>(it1->beg.x + it1->end.x))); // important to use double, since x can have many digits
      if (!getPeakBoundaries(reg, idxL, idxR, minWidth)) // idxL and idxR will be changed upon return
	{
	  // The criteria for being called a "peak" were not met by this local maximum:
	  // it's too narrow (narrower than midWidth), or it doesn't contain reg.posSummit.
	  it2 = it1;
	  it1++;
	  reg.localMaxima.erase(it2);
	  continue;
	}
      it1->beg = reg.posns[idxL];
      it1->end = reg.posns[idxR];
      it1->inputSummit = reg.posSummit;
      it1->summitSeparation = labs(it1->x_of_maxY - it1->inputSummit);
      it1++;
    }

  // We now have 0, 1, or more peaks that are at least minWidth bp wide
  // and contain reg.posSummit.
  if (reg.localMaxima.empty())
    {
      reg.posns.clear();
      return;
    }

  long minSeparation = reg.localMaxima.begin()->summitSeparation;
  it1 = it2 = reg.localMaxima.begin();
  it2++;
  while (it2 != reg.localMaxima.end())
    {
      if (it2->summitSeparation < minSeparation)
	{
	  minSeparation = it2->summitSeparation;
	  it1 = it2;
	}
      it2++;
    }

  it1->chrom = reg.chrom;
  it1->id = reg.id;
  peaks.push_back(*it1);
  reg.posns.clear();
  reg.localMaxima.clear();
  return;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xf0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rdi
addq $0x60, %rdi
callq 0x4b10
testb $0x1, %al
jne 0x2bfa
jmp 0x2c1d
movq -0x8(%rbp), %rdi
addq $0x48, %rdi
callq 0x4b30
testb $0x1, %al
jne 0x2c18
movq -0x8(%rbp), %rdi
addq $0x48, %rdi
callq 0x4b70
jmp 0x2fde
movq -0x8(%rbp), %rdi
addq $0x60, %rdi
leaq -0x6ec(%rip), %rsi      # 0x2540
callq 0x4b90
movq -0x8(%rbp), %rdi
addq $0x60, %rdi
callq 0x4fa0
movq %rax, -0x20(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x4fd0
movq -0x8(%rbp), %rdi
addq $0x60, %rdi
callq 0x5020
movq %rax, -0x30(%rbp)
leaq -0x20(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x4ff0
testb $0x1, %al
jne 0x2c72
jmp 0x2e78
leaq -0x20(%rbp), %rdi
callq 0x5050
movl 0x4c(%rax), %eax
movl %eax, -0x34(%rbp)
leaq -0x20(%rbp), %rdi
callq 0x5050
movl 0x5c(%rax), %eax
movl %eax, -0x38(%rbp)
leaq -0x20(%rbp), %rdi
callq 0x5050
movss 0x48(%rax), %xmm0
movss %xmm0, -0x9c(%rbp)
leaq -0x20(%rbp), %rdi
callq 0x5050
movss -0x9c(%rbp), %xmm0
movss %xmm0, 0x60(%rax)
leaq -0x20(%rbp), %rdi
callq 0x5050
movq 0x40(%rax), %rax
movq %rax, -0x98(%rbp)
leaq -0x20(%rbp), %rdi
callq 0x5050
movq %rax, %rcx
movq -0x98(%rbp), %rax
addq 0x50(%rcx), %rax
cvtsi2sd %rax, %xmm1
movsd 0x7334(%rip), %xmm0     # 0xa028
mulsd %xmm1, %xmm0
callq 0x2380
cvttsd2si %xmm0, %eax
cltq
movq %rax, -0x90(%rbp)
leaq -0x20(%rbp), %rdi
callq 0x5050
movq -0x90(%rbp), %rcx
movq %rcx, 0x68(%rax)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rcx
leaq -0x34(%rbp), %rsi
leaq -0x38(%rbp), %rdx
callq 0x26b0
testb $0x1, %al
jne 0x2d83
movq -0x20(%rbp), %rax
movq %rax, -0x28(%rbp)
leaq -0x20(%rbp), %rdi
xorl %esi, %esi
callq 0x5070
movq %rax, -0x40(%rbp)
movq -0x8(%rbp), %rax
addq $0x60, %rax
movq %rax, -0xa8(%rbp)
leaq -0x48(%rbp), %rdi
leaq -0x28(%rbp), %rsi
callq 0x50f0
movq -0xa8(%rbp), %rdi
movq -0x48(%rbp), %rsi
callq 0x50a0
movq %rax, -0x50(%rbp)
jmp 0x2c4b
movq -0x8(%rbp), %rdi
addq $0x48, %rdi
movslq -0x34(%rbp), %rsi
callq 0x5110
movq %rax, -0xd0(%rbp)
leaq -0x20(%rbp), %rdi
callq 0x5050
movq -0xd0(%rbp), %rcx
movq (%rcx), %rdx
movq %rdx, 0x40(%rax)
movq 0x8(%rcx), %rcx
movq %rcx, 0x48(%rax)
movq -0x8(%rbp), %rdi
addq $0x48, %rdi
movslq -0x38(%rbp), %rsi
callq 0x5110
movq %rax, -0xc8(%rbp)
leaq -0x20(%rbp), %rdi
callq 0x5050
movq -0xc8(%rbp), %rcx
movq (%rcx), %rdx
movq %rdx, 0x50(%rax)
movq 0x8(%rcx), %rcx
movq %rcx, 0x58(%rax)
movq -0x8(%rbp), %rax
movq 0x40(%rax), %rax
movq %rax, -0xc0(%rbp)
leaq -0x20(%rbp), %rdi
callq 0x5050
movq -0xc0(%rbp), %rcx
movq %rcx, 0x70(%rax)
leaq -0x20(%rbp), %rdi
callq 0x5050
movq 0x68(%rax), %rax
movq %rax, -0xb8(%rbp)
leaq -0x20(%rbp), %rdi
callq 0x5050
movq %rax, %rcx
movq -0xb8(%rbp), %rax
subq 0x70(%rcx), %rax
movq %rax, %rcx
negq %rcx
cmovnsq %rcx, %rax
movq %rax, -0xb0(%rbp)
leaq -0x20(%rbp), %rdi
callq 0x5050
movq -0xb0(%rbp), %rcx
movq %rcx, 0x78(%rax)
leaq -0x20(%rbp), %rdi
xorl %esi, %esi
callq 0x5070
movq %rax, -0x58(%rbp)
jmp 0x2c4b
movq -0x8(%rbp), %rdi
addq $0x60, %rdi
callq 0x4b10
testb $0x1, %al
jne 0x2e8b
jmp 0x2e9d
movq -0x8(%rbp), %rdi
addq $0x48, %rdi
callq 0x4b70
jmp 0x2fde
movq -0x8(%rbp), %rdi
addq $0x60, %rdi
callq 0x4fa0
movq %rax, -0x68(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x5050
movq 0x78(%rax), %rax
movq %rax, -0x60(%rbp)
movq -0x8(%rbp), %rdi
addq $0x60, %rdi
callq 0x4fa0
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x20(%rbp)
leaq -0x28(%rbp), %rdi
xorl %esi, %esi
callq 0x5070
movq %rax, -0x78(%rbp)
movq -0x8(%rbp), %rdi
addq $0x60, %rdi
callq 0x5020
movq %rax, -0x80(%rbp)
leaq -0x28(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x4ff0
testb $0x1, %al
jne 0x2f13
jmp 0x2f53
leaq -0x28(%rbp), %rdi
callq 0x5050
movq 0x78(%rax), %rax
cmpq -0x60(%rbp), %rax
jge 0x2f3f
leaq -0x28(%rbp), %rdi
callq 0x5050
movq 0x78(%rax), %rax
movq %rax, -0x60(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x20(%rbp)
leaq -0x28(%rbp), %rdi
xorl %esi, %esi
callq 0x5070
movq %rax, -0x88(%rbp)
jmp 0x2eef
movq -0x8(%rbp), %rax
movq %rax, -0xe8(%rbp)
leaq -0x20(%rbp), %rdi
callq 0x5050
movq -0xe8(%rbp), %rsi
movq %rax, %rdi
callq 0x2040
movq -0x8(%rbp), %rax
addq $0x20, %rax
movq %rax, -0xe0(%rbp)
leaq -0x20(%rbp), %rdi
callq 0x5050
movq -0xe0(%rbp), %rsi
movq %rax, %rdi
addq $0x20, %rdi
callq 0x2040
movq -0x18(%rbp), %rax
movq %rax, -0xd8(%rbp)
leaq -0x20(%rbp), %rdi
callq 0x51a0
movq -0xd8(%rbp), %rdi
movq %rax, %rsi
callq 0x5130
movq -0x8(%rbp), %rdi
addq $0x48, %rdi
callq 0x4b70
movq -0x8(%rbp), %rdi
addq $0x60, %rdi
callq 0x51c0
addq $0xf0, %rsp
popq %rbp
retq
nopw (%rax,%rax)