// File: Altius[P]hotspot2/src/findVarWidthPeaks.cpp
// Function: getPeakBoundaries(Region const&, int&, int&, long const&)
bool getPeakBoundaries(const Region& r, int& idxL, int& idxR, const long& minWidth)
{
  float maxY(r.posns[idxL].y), halfmaxY(r.posns[idxL].y/2.0), minY(maxY);
  const float secondaryCutoff(999999. * maxY); // ensures we always return the local min when we fail to achieve half-max
  const int maxIdx = static_cast<int>(r.posns.size()) - 1; // in English: "maximum index," not "idx of max"
  int idxOfLocalMin(idxL);

  if (idxL > 0)
    idxL--; // begin our search at the first site to the left of the local maximum
  while (idxL > 0 && (r.posns[idxL].y - halfmaxY) > 0.0001) // the L boundary of the Region has index = 0
    {
      if (r.posns[idxL].y < minY || r.posns[idxL].y - minY < 0.0001) // i.e., "if y <= minY"
	{
	  minY = r.posns[idxL].y;
	  idxOfLocalMin = idxL;
	}
      if (r.posns[idxL].y - maxY > -0.0001) // i.e., "if y >= maxY"
	{
	  // While searching for the half-max point to the left of the local max,
	  // we climbed above the local max, so this is a subset of another peak...
	  // but we want to give it a chance to get called as a peak, so we backtrack to the local min.
	  idxL = idxOfLocalMin;
	  if (secondaryCutoff - r.posns[idxL].y > 0.0001)
	    break;
	  else
	    return false; // we'll actually never hit this line unless we change the algorithm
	}
      else
	idxL--;
    }
  if (halfmaxY - r.posns[idxL].y > -0.0001) // i.e., "if halfmaxY >= y"
    idxL++;
  else
    {
      if (0 == idxL && r.posns[idxL].y > minY)
	idxL = idxOfLocalMin;
    }

  idxOfLocalMin = idxR;
  minY = maxY;
  if (idxR < maxIdx)
    idxR++; // begin our search at the first site to the right of the local maximum
  while (idxR < maxIdx && (r.posns[idxR].y - halfmaxY) > 0.0001) // the R boundary of the Region has index = maxIdx
    {
      if (r.posns[idxR].y < minY || r.posns[idxR].y - minY < 0.0001) // i.e., "if y <= minY"
	{
	  minY = r.posns[idxR].y;
	  idxOfLocalMin = idxR;
	}
      if (r.posns[idxR].y - maxY > - 0.0001) // i.e., "if y >= maxY"
	{
	  // While searching for the half-max point to the left of the local max,
	  // we climbed above the local max, so this is a subset of another peak...
	  // but we want to give it a chance to get called as a peak, so we backtrack to the local min.
	  idxR = idxOfLocalMin;
	  if (secondaryCutoff - r.posns[idxR].y > 0.0001)
	    break;
	  else
	    return false; // we'll actually never hit this line unless we change the algorithm
	}
      else
	idxR++;
    }
  if (halfmaxY - r.posns[idxR].y > -0.0001) // i.e., "if halfmax >= y"
    idxR--;
  else
    {
      if (maxIdx == idxR && r.posns[idxR].y > minY)
	idxR = idxOfLocalMin;
    }

  // Require the peak to contain the posSummit received for this region.
  if (r.posSummit < r.posns[idxL].x || r.posSummit > r.posns[idxR].x)
    return false;
  if (idxR - idxL + 1 >= minWidth) // 0-based sites (100,120] are the 20 sites from 101-120; could have, e.g., idxL = 0 and idxR = 19 in this case
    return true;
  return false;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq -0x10(%rbp), %rdi
addq $0x48, %rdi
movq -0x18(%rbp), %rax
movslq (%rax), %rsi
callq 0x4ad0
movss 0x8(%rax), %xmm0
movss %xmm0, -0x2c(%rbp)
movq -0x10(%rbp), %rdi
addq $0x48, %rdi
movq -0x18(%rbp), %rax
movslq (%rax), %rsi
callq 0x4ad0
movss 0x8(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
movsd 0x790d(%rip), %xmm1     # 0xa018
divsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0x30(%rbp)
movss -0x2c(%rbp), %xmm0
movss %xmm0, -0x34(%rbp)
movss -0x2c(%rbp), %xmm0
cvtss2sd %xmm0, %xmm1
movsd 0x78dd(%rip), %xmm0     # 0xa010
mulsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0x38(%rbp)
movq -0x10(%rbp), %rdi
addq $0x48, %rdi
callq 0x4af0
subl $0x1, %eax
movl %eax, -0x3c(%rbp)
movq -0x18(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x40(%rbp)
movq -0x18(%rbp), %rax
cmpl $0x0, (%rax)
jle 0x2770
movq -0x18(%rbp), %rax
movl (%rax), %ecx
addl $-0x1, %ecx
movl %ecx, (%rax)
jmp 0x2772
movq -0x18(%rbp), %rcx
xorl %eax, %eax
cmpl $0x0, (%rcx)
movb %al, -0x41(%rbp)
jle 0x27b4
movq -0x10(%rbp), %rdi
addq $0x48, %rdi
movq -0x18(%rbp), %rax
movslq (%rax), %rsi
callq 0x4ad0
movss 0x8(%rax), %xmm0
subss -0x30(%rbp), %xmm0
cvtss2sd %xmm0, %xmm0
movsd 0x785e(%rip), %xmm1     # 0xa008
ucomisd %xmm1, %xmm0
seta %al
movb %al, -0x41(%rbp)
movb -0x41(%rbp), %al
testb $0x1, %al
jne 0x27c0
jmp 0x28c8
movq -0x10(%rbp), %rdi
addq $0x48, %rdi
movq -0x18(%rbp), %rax
movslq (%rax), %rsi
callq 0x4ad0
movss 0x8(%rax), %xmm1
movss -0x34(%rbp), %xmm0
ucomiss %xmm1, %xmm0
ja 0x2813
movq -0x10(%rbp), %rdi
addq $0x48, %rdi
movq -0x18(%rbp), %rax
movslq (%rax), %rsi
callq 0x4ad0
movss 0x8(%rax), %xmm0
subss -0x34(%rbp), %xmm0
cvtss2sd %xmm0, %xmm1
movsd 0x77fb(%rip), %xmm0     # 0xa008
ucomisd %xmm1, %xmm0
jbe 0x283a
movq -0x10(%rbp), %rdi
addq $0x48, %rdi
movq -0x18(%rbp), %rax
movslq (%rax), %rsi
callq 0x4ad0
movss 0x8(%rax), %xmm0
movss %xmm0, -0x34(%rbp)
movq -0x18(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x40(%rbp)
movq -0x10(%rbp), %rdi
addq $0x48, %rdi
movq -0x18(%rbp), %rax
movslq (%rax), %rsi
callq 0x4ad0
movss 0x8(%rax), %xmm0
subss -0x2c(%rbp), %xmm0
cvtss2sd %xmm0, %xmm0
movsd 0x77bc(%rip), %xmm1     # 0xa020
ucomisd %xmm1, %xmm0
jbe 0x28b8
movl -0x40(%rbp), %ecx
movq -0x18(%rbp), %rax
movl %ecx, (%rax)
movss -0x38(%rbp), %xmm0
movss %xmm0, -0x48(%rbp)
movq -0x10(%rbp), %rdi
addq $0x48, %rdi
movq -0x18(%rbp), %rax
movslq (%rax), %rsi
callq 0x4ad0
movss -0x48(%rbp), %xmm0
subss 0x8(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
movsd 0x7761(%rip), %xmm1     # 0xa008
ucomisd %xmm1, %xmm0
jbe 0x28af
jmp 0x28c8
movb $0x0, -0x1(%rbp)
jmp 0x2bc4
movq -0x18(%rbp), %rax
movl (%rax), %ecx
addl $-0x1, %ecx
movl %ecx, (%rax)
jmp 0x2772
movss -0x30(%rbp), %xmm0
movss %xmm0, -0x4c(%rbp)
movq -0x10(%rbp), %rdi
addq $0x48, %rdi
movq -0x18(%rbp), %rax
movslq (%rax), %rsi
callq 0x4ad0
movss -0x4c(%rbp), %xmm0
subss 0x8(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
movsd 0x7724(%rip), %xmm1     # 0xa020
ucomisd %xmm1, %xmm0
jbe 0x290f
movq -0x18(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
jmp 0x2943
movq -0x18(%rbp), %rcx
xorl %eax, %eax
cmpl (%rcx), %eax
jne 0x2941
movq -0x10(%rbp), %rdi
addq $0x48, %rdi
movq -0x18(%rbp), %rax
movslq (%rax), %rsi
callq 0x4ad0
movss 0x8(%rax), %xmm0
ucomiss -0x34(%rbp), %xmm0
jbe 0x2941
movl -0x40(%rbp), %ecx
movq -0x18(%rbp), %rax
movl %ecx, (%rax)
jmp 0x2943
movq -0x20(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x40(%rbp)
movss -0x2c(%rbp), %xmm0
movss %xmm0, -0x34(%rbp)
movq -0x20(%rbp), %rax
movl (%rax), %eax
cmpl -0x3c(%rbp), %eax
jge 0x296c
movq -0x20(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
jmp 0x296e
movq -0x20(%rbp), %rax
movl (%rax), %ecx
xorl %eax, %eax
cmpl -0x3c(%rbp), %ecx
movb %al, -0x4d(%rbp)
jge 0x29b2
movq -0x10(%rbp), %rdi
addq $0x48, %rdi
movq -0x20(%rbp), %rax
movslq (%rax), %rsi
callq 0x4ad0
movss 0x8(%rax), %xmm0
subss -0x30(%rbp), %xmm0
cvtss2sd %xmm0, %xmm0
movsd 0x7660(%rip), %xmm1     # 0xa008
ucomisd %xmm1, %xmm0
seta %al
movb %al, -0x4d(%rbp)
movb -0x4d(%rbp), %al
testb $0x1, %al
jne 0x29be
jmp 0x2ac6
movq -0x10(%rbp), %rdi
addq $0x48, %rdi
movq -0x20(%rbp), %rax
movslq (%rax), %rsi
callq 0x4ad0
movss 0x8(%rax), %xmm1
movss -0x34(%rbp), %xmm0
ucomiss %xmm1, %xmm0
ja 0x2a11
movq -0x10(%rbp), %rdi
addq $0x48, %rdi
movq -0x20(%rbp), %rax
movslq (%rax), %rsi
callq 0x4ad0
movss 0x8(%rax), %xmm0
subss -0x34(%rbp), %xmm0
cvtss2sd %xmm0, %xmm1
movsd 0x75fd(%rip), %xmm0     # 0xa008
ucomisd %xmm1, %xmm0
jbe 0x2a38
movq -0x10(%rbp), %rdi
addq $0x48, %rdi
movq -0x20(%rbp), %rax
movslq (%rax), %rsi
callq 0x4ad0
movss 0x8(%rax), %xmm0
movss %xmm0, -0x34(%rbp)
movq -0x20(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x40(%rbp)
movq -0x10(%rbp), %rdi
addq $0x48, %rdi
movq -0x20(%rbp), %rax
movslq (%rax), %rsi
callq 0x4ad0
movss 0x8(%rax), %xmm0
subss -0x2c(%rbp), %xmm0
cvtss2sd %xmm0, %xmm0
movsd 0x75be(%rip), %xmm1     # 0xa020
ucomisd %xmm1, %xmm0
jbe 0x2ab6
movl -0x40(%rbp), %ecx
movq -0x20(%rbp), %rax
movl %ecx, (%rax)
movss -0x38(%rbp), %xmm0
movss %xmm0, -0x54(%rbp)
movq -0x10(%rbp), %rdi
addq $0x48, %rdi
movq -0x20(%rbp), %rax
movslq (%rax), %rsi
callq 0x4ad0
movss -0x54(%rbp), %xmm0
subss 0x8(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
movsd 0x7563(%rip), %xmm1     # 0xa008
ucomisd %xmm1, %xmm0
jbe 0x2aad
jmp 0x2ac6
movb $0x0, -0x1(%rbp)
jmp 0x2bc4
movq -0x20(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
jmp 0x296e
movss -0x30(%rbp), %xmm0
movss %xmm0, -0x58(%rbp)
movq -0x10(%rbp), %rdi
addq $0x48, %rdi
movq -0x20(%rbp), %rax
movslq (%rax), %rsi
callq 0x4ad0
movss -0x58(%rbp), %xmm0
subss 0x8(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
movsd 0x7526(%rip), %xmm1     # 0xa020
ucomisd %xmm1, %xmm0
jbe 0x2b0d
movq -0x20(%rbp), %rax
movl (%rax), %ecx
addl $-0x1, %ecx
movl %ecx, (%rax)
jmp 0x2b42
movl -0x3c(%rbp), %eax
movq -0x20(%rbp), %rcx
cmpl (%rcx), %eax
jne 0x2b40
movq -0x10(%rbp), %rdi
addq $0x48, %rdi
movq -0x20(%rbp), %rax
movslq (%rax), %rsi
callq 0x4ad0
movss 0x8(%rax), %xmm0
ucomiss -0x34(%rbp), %xmm0
jbe 0x2b40
movl -0x40(%rbp), %ecx
movq -0x20(%rbp), %rax
movl %ecx, (%rax)
jmp 0x2b42
movq -0x10(%rbp), %rax
movq 0x40(%rax), %rax
movq %rax, -0x60(%rbp)
movq -0x10(%rbp), %rdi
addq $0x48, %rdi
movq -0x18(%rbp), %rax
movslq (%rax), %rsi
callq 0x4ad0
movq %rax, %rcx
movq -0x60(%rbp), %rax
cmpq (%rcx), %rax
jl 0x2b9a
movq -0x10(%rbp), %rax
movq 0x40(%rax), %rax
movq %rax, -0x68(%rbp)
movq -0x10(%rbp), %rdi
addq $0x48, %rdi
movq -0x20(%rbp), %rax
movslq (%rax), %rsi
callq 0x4ad0
movq %rax, %rcx
movq -0x68(%rbp), %rax
cmpq (%rcx), %rax
jle 0x2ba0
movb $0x0, -0x1(%rbp)
jmp 0x2bc4
movq -0x20(%rbp), %rax
movl (%rax), %eax
movq -0x18(%rbp), %rcx
subl (%rcx), %eax
addl $0x1, %eax
cltq
movq -0x28(%rbp), %rcx
cmpq (%rcx), %rax
jl 0x2bc0
movb $0x1, -0x1(%rbp)
jmp 0x2bc4
movb $0x0, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x70, %rsp
popq %rbp
retq
nop