// File: /workspace/github_cpp_makefile_star2_O2/Altius[P]hotspot2/src/hotspot2_part1.cpp
// Function: parseAndProcessInput(int const&, int const&, int const&, std::basic_ofstream<char, std::char_traits<char>>&)
bool parseAndProcessInput(const int& windowSize, const int& samplingInterval, const int& MAlength,
			  ofstream& ofsPvalData)
{
  const int BUFSIZE(1000);
  char buf[BUFSIZE], *p;
  long linenum(0);
  int fieldnum;
  const int halfWindowSize(windowSize / 2); // integer division
  SiteRange curSite, prevSite;
  
  BackgroundRegionManager brm(samplingInterval, MAlength);
  SiteManager sm(ofsPvalData);

  prevSite.chrom = NULL;
  prevSite.endPos = -1;
  curSite.ID = NULL;
  curSite.hasPval = false;
  curSite.pval = -1.;
#ifdef DEBUG
  curSite.sampled = false;
#endif

  long start, end;

  while (cin.getline(buf, BUFSIZE))
    {
      linenum++;
      fieldnum = 1;
      p = strtok(buf, "\t");
      curSite.chrom = intern(string(p));
      fieldnum++;
      if (!(p = strtok(NULL, "\t")))
        {
        MissingField:
          cerr << "Error:  Missing required field " << fieldnum
               << " on line " << linenum << "." << endl
               << endl;
          return false;
        }
      start = atol(p);
      fieldnum++;
      if (!(p = strtok(NULL, "\t")))
        goto MissingField;
      end = atol(p);
      fieldnum++;
      if (!(p = strtok(NULL, "\t")))
        goto MissingField;
      //curSite.ID = intern(string(p));
      fieldnum++;
      if (!(p = strtok(NULL, "\t")))
        goto MissingField;
      curSite.count = atoi(p);
      // ignore any further fields

      // When contiguous stretches of sites with identical counts are observed
      // within a line of input, they need to be processed one site at a time,
      // for statistical reasons.
      for (int siteEnd = start + 1; siteEnd <= end; siteEnd++)
        {
          curSite.endPos = siteEnd;
	  curSite.begPos = curSite.endPos - 1;

          if (curSite.chrom != prevSite.chrom || curSite.endPos > prevSite.endPos + halfWindowSize)
            {
              brm.computePandFlush(sm); // Compute P-values for all unprocessed sites in the window.
	      // Writes values to disk.
              // This method removes all count data from brm.
              brm.setBounds(curSite.chrom, curSite.endPos, curSite.endPos + windowSize - 1);
            }

          if (!brm.isSliding() && curSite.endPos < brm.getRightEdge())
            {
              brm.add(curSite);
              sm.addSite(curSite);
            }
          else
            brm.slideAndCompute(curSite, sm); // calls sm.addSite(curSite)

          prevSite = curSite;
        }
    }

  brm.computePandFlush(sm); // See explanatory comment above.
  sm.writeLastUnreportedSite();

  return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x658, %rsp            # imm = 0x658
movq %rcx, %rbx
movq %rdi, 0x18(%rsp)
movl (%rdi), %ebp
leaq 0xe0(%rsp), %rdi
callq 0x2a98
leaq 0x68(%rsp), %rdi
callq 0x61e4
pushq $0x2
popq %rcx
movl %ebp, %eax
cltd
idivl %ecx
leaq 0x20(%rsp), %rcx
andq $0x0, 0x8(%rcx)
leaq 0x68(%rsp), %rdx
movq %rbx, 0x50(%rdx)
movb $0x0, 0x38(%rcx)
fld1
fchs
fstpt 0x30(%rsp)
movslq %eax, %r14
pushq $-0x1
popq %r15
xorl %ebx, %ebx
leaq 0x270(%rsp), %r13
leaq 0xe0(%rsp), %rbp
xorl %r12d, %r12d
movl $0x3e8, %edx            # imm = 0x3E8
movq 0x6f5f(%rip), %rdi      # 0xbfd8
movq %r13, %rsi
callq 0x2080
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movl 0x20(%rax,%rcx), %eax
movl %eax, 0x14(%rsp)
testb $0x5, %al
jne 0x5219
movq %r13, %rdi
leaq 0x3792(%rip), %rsi      # 0x8834
callq 0x22f0
leaq 0xc0(%rsp), %r13
movq %r13, %rdi
movq %rax, %rsi
leaq 0x7(%rsp), %rdx
callq 0x5e7e
movq %r13, %rdi
callq 0x255c
incq %rbx
movq %rax, 0x20(%rsp)
movq %r13, %rdi
callq 0x20d0
xorl %edi, %edi
leaq 0x3754(%rip), %r13      # 0x8834
movq %r13, %rsi
callq 0x22f0
testq %rax, %rax
je 0x5237
movq %rax, %rdi
callq 0x2270
movq %r13, %rsi
movq %rax, %r13
xorl %edi, %edi
callq 0x22f0
testq %rax, %rax
je 0x523b
movq %rbx, 0x8(%rsp)
movq %rax, %rdi
callq 0x2270
movq %rax, %rbx
xorl %edi, %edi
leaq 0x370c(%rip), %rsi      # 0x8834
callq 0x22f0
testq %rax, %rax
je 0x5240
xorl %edi, %edi
leaq 0x36f5(%rip), %rsi      # 0x8834
callq 0x22f0
testq %rax, %rax
je 0x5244
movq %rax, %rdi
callq 0x22e0
movl %eax, 0x50(%rsp)
incl %r13d
movslq %r13d, %rax
cmpq %rax, %rbx
jl 0x5207
movq %rax, 0x48(%rsp)
leaq -0x1(%rax), %rcx
movq %rcx, 0x40(%rsp)
cmpq %r12, 0x20(%rsp)
jne 0x5185
addq %r14, %r15
cmpq %rax, %r15
jge 0x51af
movq %rbp, %rdi
leaq 0x68(%rsp), %rsi
callq 0x3a98
movq 0x20(%rsp), %rsi
movl 0x48(%rsp), %edx
movq 0x18(%rsp), %rax
movl (%rax), %eax
leal (%rdx,%rax), %ecx
decl %ecx
movq %rbp, %rdi
callq 0x2bae
cmpb $0x0, 0x1f8(%rsp)
jne 0x51e6
movslq 0xe4(%rsp), %rax
cmpq %rax, 0x48(%rsp)
jge 0x51e6
movq %rbp, %rdi
leaq 0x20(%rsp), %rsi
callq 0x2c3c
leaq 0x68(%rsp), %rdi
leaq 0x20(%rsp), %rsi
callq 0x5c54
jmp 0x51f8
movq %rbp, %rdi
leaq 0x20(%rsp), %rsi
leaq 0x68(%rsp), %rdx
callq 0x3c3c
movq 0x20(%rsp), %r12
movq 0x48(%rsp), %r15
jmp 0x5159
movq 0x8(%rsp), %rbx
leaq 0x270(%rsp), %r13
jmp 0x506d
leaq 0xe0(%rsp), %rdi
leaq 0x68(%rsp), %rsi
callq 0x3a98
leaq 0x68(%rsp), %rdi
callq 0x5cce
jmp 0x52a2
pushq $0x2
jmp 0x523d
pushq $0x3
popq %rbp
jmp 0x524c
pushq $0x4
jmp 0x5246
pushq $0x5
popq %rbp
movq 0x8(%rsp), %rbx
movq 0x6d9d(%rip), %rdi      # 0xbff0
leaq 0x35dc(%rip), %rsi      # 0x8836
callq 0x21e0
movq %rax, %rdi
movl %ebp, %esi
callq 0x2340
leaq 0x34cf(%rip), %rsi      # 0x873f
movq %rax, %rdi
callq 0x21e0
movq %rax, %rdi
movq %rbx, %rsi
callq 0x21d0
leaq 0x353c(%rip), %rsi      # 0x87c6
movq %rax, %rdi
callq 0x21e0
movq %rax, %rdi
callq 0x20e0
movq %rax, %rdi
callq 0x20e0
testb $0x5, 0x14(%rsp)
setne %bl
leaq 0x68(%rsp), %rdi
callq 0x63f0
leaq 0xe0(%rsp), %rdi
callq 0x5eba
movl %ebx, %eax
addq $0x658, %rsp            # imm = 0x658
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
jmp 0x52ff
jmp 0x52f2
movq %rax, %rbx
leaq 0xc0(%rsp), %rdi
callq 0x20d0
jmp 0x52f5
jmp 0x52f2
jmp 0x52f2
movq %rax, %rbx
leaq 0x68(%rsp), %rdi
callq 0x63f0
leaq 0xe0(%rsp), %rdi
callq 0x5eba
movq %rbx, %rdi
callq 0x2350