// File: /workspace/github_cpp_makefile_star2_O2/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:
movslq (%rsi), %r9
movq %r9, %r10
shlq $0x4, %r10
movq 0x48(%rdi), %rax
movq 0x50(%rdi), %r8
subq %rax, %r8
shrq $0x4, %r8
movss 0x8(%rax,%r10), %xmm1
movl %r9d, %r11d
testq %r9, %r9
jle 0x24ee
leal -0x1(%r9), %r11d
movl %r11d, (%rsi)
pushq %rbp
pushq %r14
pushq %rbx
decl %r8d
movss 0x2b3b(%rip), %xmm0     # 0x5038
mulss %xmm1, %xmm0
movss 0x2b33(%rip), %xmm2     # 0x503c
mulss %xmm1, %xmm2
movl %r11d, %r14d
leaq 0x8(%rax), %rbx
shlq $0x4, %r14
movsd 0x2b00(%rip), %xmm3     # 0x5020
movsd 0x2b00(%rip), %xmm4     # 0x5028
movl %r11d, %r10d
movaps %xmm1, %xmm5
testl %r10d, %r10d
jle 0x2584
movss (%rbx,%r14), %xmm6
movaps %xmm6, %xmm7
subss %xmm0, %xmm7
cvtss2sd %xmm7, %xmm7
ucomisd %xmm3, %xmm7
jbe 0x2584
ucomiss %xmm6, %xmm5
ja 0x2560
movaps %xmm6, %xmm7
subss %xmm5, %xmm7
cvtss2sd %xmm7, %xmm7
ucomisd %xmm7, %xmm3
jbe 0x2566
movaps %xmm6, %xmm5
movl %r10d, %r9d
subss %xmm1, %xmm6
cvtss2sd %xmm6, %xmm6
ucomisd %xmm4, %xmm6
ja 0x26aa
decl %r10d
movl %r10d, (%rsi)
addq $-0x10, %rbx
jmp 0x252e
movslq %r11d, %r11
shlq $0x4, %r11
movss (%rbx,%r11), %xmm6
movaps %xmm0, %xmm7
subss %xmm6, %xmm7
cvtss2sd %xmm7, %xmm6
ucomisd 0x2a84(%rip), %xmm6     # 0x5028
jbe 0x25b1
incl %r10d
movl %r10d, %r9d
movl %r9d, (%rsi)
jmp 0x25c0
testl %r10d, %r10d
jne 0x25c0
movss 0x8(%rax), %xmm6
ucomiss %xmm5, %xmm6
ja 0x25ac
movl (%rdx), %r9d
movl %r9d, %r10d
cmpl %r8d, %r9d
jge 0x25d2
leal 0x1(%r9), %r10d
movl %r10d, (%rdx)
movslq %r10d, %r10
movslq %r8d, %r11
movq %r10, %rbx
shlq $0x4, %rbx
addq %rax, %rbx
addq $0x8, %rbx
movaps %xmm1, %xmm5
cmpq %r11, %r10
jge 0x2640
movss (%rbx), %xmm6
movaps %xmm6, %xmm7
subss %xmm0, %xmm7
cvtss2sd %xmm7, %xmm7
ucomisd %xmm3, %xmm7
jbe 0x2640
ucomiss %xmm6, %xmm5
ja 0x2619
movaps %xmm6, %xmm7
subss %xmm5, %xmm7
cvtss2sd %xmm7, %xmm7
ucomisd %xmm7, %xmm3
jbe 0x261f
movaps %xmm6, %xmm5
movl %r10d, %r9d
subss %xmm1, %xmm6
cvtss2sd %xmm6, %xmm6
ucomisd %xmm4, %xmm6
ja 0x26d9
leal 0x1(%r10), %ebp
incq %r10
movl %ebp, (%rdx)
addq $0x10, %rbx
jmp 0x25e9
movslq %r10d, %r11
shlq $0x4, %r11
movss 0x8(%rax,%r11), %xmm1
subss %xmm1, %xmm0
cvtss2sd %xmm0, %xmm0
ucomisd 0x29ca(%rip), %xmm0     # 0x5028
jbe 0x2668
decl %r10d
movl %r10d, %r9d
jmp 0x2672
cmpl %r10d, %r8d
jne 0x2678
ucomiss %xmm5, %xmm1
jbe 0x2678
movl %r9d, (%rdx)
movl %r9d, %r10d
movq 0x40(%rdi), %rdi
movslq (%rsi), %rdx
movq %rdx, %rsi
shlq $0x4, %rsi
cmpq (%rax,%rsi), %rdi
jl 0x2703
movslq %r10d, %rsi
shlq $0x4, %rsi
cmpq (%rax,%rsi), %rdi
jg 0x2703
subl %edx, %r10d
incl %r10d
movslq %r10d, %rax
cmpq %rax, (%rcx)
setle %al
jmp 0x2705
movl %r9d, (%rsi)
movslq %r9d, %r10
shlq $0x4, %r10
movss 0x8(%rax,%r10), %xmm6
movaps %xmm2, %xmm7
subss %xmm6, %xmm7
cvtss2sd %xmm7, %xmm7
ucomisd 0x2952(%rip), %xmm7     # 0x5020
movl %r9d, %r10d
ja 0x2591
jmp 0x2703
movl %r9d, (%rdx)
movslq %r9d, %r10
shlq $0x4, %r10
movss 0x8(%rax,%r10), %xmm1
subss %xmm1, %xmm2
cvtss2sd %xmm2, %xmm2
ucomisd 0x2926(%rip), %xmm2     # 0x5020
movl %r9d, %r10d
ja 0x264e
xorl %eax, %eax
popq %rbx
popq %r14
popq %rbp
retq