// File: /workspace/github_cpp_makefile_star2_O1/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 %rbx
movslq (%rsi), %r9
movq %r9, %r10
shlq $0x4, %r10
movq 0x48(%rdi), %rax
movq 0x50(%rdi), %r8
movss 0x8(%rax,%r10), %xmm1
testq %r9, %r9
jle 0x2540
leal -0x1(%r9), %r10d
movl %r10d, (%rsi)
movss 0x3af0(%rip), %xmm0     # 0x6038
mulss %xmm1, %xmm0
movss 0x3ae8(%rip), %xmm2     # 0x603c
mulss %xmm1, %xmm2
movslq (%rsi), %r10
testq %r10, %r10
jle 0x25d8
movq %r10, %r11
shlq $0x4, %r11
addq %rax, %r11
addq $0x8, %r11
movsd 0x3aaa(%rip), %xmm4     # 0x6020
movsd 0x3aaa(%rip), %xmm5     # 0x6028
movaps %xmm1, %xmm3
movss (%r11), %xmm6
subss %xmm0, %xmm6
cvtss2sd %xmm6, %xmm6
ucomisd %xmm4, %xmm6
jbe 0x2603
movss (%r11), %xmm6
ucomiss %xmm6, %xmm3
ja 0x25af
movaps %xmm6, %xmm7
subss %xmm3, %xmm7
cvtss2sd %xmm7, %xmm7
ucomisd %xmm7, %xmm4
jbe 0x25b5
movaps %xmm6, %xmm3
movl %r10d, %r9d
subss %xmm1, %xmm6
cvtss2sd %xmm6, %xmm6
ucomisd %xmm5, %xmm6
ja 0x25dd
leaq -0x1(%r10), %rbx
movl %ebx, (%rsi)
addq $-0x10, %r11
cmpq $0x1, %r10
movq %rbx, %r10
jg 0x2581
jmp 0x2603
movaps %xmm1, %xmm3
jmp 0x2603
movl %r9d, (%rsi)
movslq %r9d, %r10
shlq $0x4, %r10
movaps %xmm2, %xmm4
subss 0x8(%rax,%r10), %xmm4
cvtss2sd %xmm4, %xmm4
ucomisd 0x3a23(%rip), %xmm4     # 0x6020
jbe 0x2762
subq %rax, %r8
shrq $0x4, %r8
decl %r8d
movslq (%rsi), %r10
movq %r10, %r11
shlq $0x4, %r11
movaps %xmm0, %xmm4
subss 0x8(%rax,%r11), %xmm4
cvtss2sd %xmm4, %xmm4
ucomisd 0x39fb(%rip), %xmm4     # 0x6028
jbe 0x2638
leal 0x1(%r10), %r9d
movl %r9d, (%rsi)
jmp 0x2647
testl %r10d, %r10d
jne 0x2647
movss 0x8(%rax), %xmm4
ucomiss %xmm3, %xmm4
ja 0x2633
movl (%rdx), %r9d
cmpl %r8d, %r9d
jge 0x2656
leal 0x1(%r9), %r10d
movl %r10d, (%rdx)
movl (%rdx), %r10d
cmpl %r8d, %r10d
jge 0x26d0
movslq %r10d, %r11
shlq $0x4, %r11
addq %rax, %r11
addq $0x8, %r11
movsd 0x39ac(%rip), %xmm4     # 0x6020
movsd 0x39ac(%rip), %xmm5     # 0x6028
movaps %xmm1, %xmm3
movss (%r11), %xmm6
movaps %xmm6, %xmm7
subss %xmm0, %xmm7
cvtss2sd %xmm7, %xmm7
ucomisd %xmm4, %xmm7
jbe 0x26d3
ucomiss %xmm6, %xmm3
ja 0x26ab
movaps %xmm6, %xmm7
subss %xmm3, %xmm7
cvtss2sd %xmm7, %xmm7
ucomisd %xmm7, %xmm4
jbe 0x26b1
movaps %xmm6, %xmm3
movl %r10d, %r9d
subss %xmm1, %xmm6
cvtss2sd %xmm6, %xmm6
ucomisd %xmm5, %xmm6
ja 0x273c
incl %r10d
movl %r10d, (%rdx)
addq $0x10, %r11
cmpl %r10d, %r8d
jne 0x267f
jmp 0x26d3
movaps %xmm1, %xmm3
movslq (%rdx), %r10
movq %r10, %r11
shlq $0x4, %r11
movss 0x8(%rax,%r11), %xmm1
subss %xmm1, %xmm0
cvtss2sd %xmm0, %xmm0
ucomisd 0x3934(%rip), %xmm0     # 0x6028
jbe 0x26fc
leal -0x1(%r10), %r9d
jmp 0x2706
cmpl %r10d, %r8d
jne 0x2709
ucomiss %xmm3, %xmm1
jbe 0x2709
movl %r9d, (%rdx)
movq 0x40(%rdi), %rdi
movslq (%rsi), %rsi
movq %rsi, %r8
shlq $0x4, %r8
cmpq (%rax,%r8), %rdi
jl 0x2762
movslq (%rdx), %rdx
movq %rdx, %r8
shlq $0x4, %r8
cmpq (%rax,%r8), %rdi
jg 0x2762
subl %esi, %edx
incl %edx
movslq %edx, %rax
cmpq %rax, (%rcx)
setle %al
jmp 0x2764
movl %r9d, (%rdx)
movslq %r9d, %r10
shlq $0x4, %r10
subss 0x8(%rax,%r10), %xmm2
xorps %xmm1, %xmm1
cvtss2sd %xmm2, %xmm1
ucomisd 0x38c4(%rip), %xmm1     # 0x6020
ja 0x26d3
xorl %eax, %eax
popq %rbx
retq