// File: schneebergerlab[P]DrLink/detect_recombsite.cpp
// Function: get_var_ref_barcode(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>*, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::multimap<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, unsigned long, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, unsigned long>>>*)
bool get_var_ref_barcode(string                formatInfo, 
                         string                barcodeString, 
                         vector<string>*       vbc, 
                         vector<string>*       rbc,
                         string                this_chr,
                         string                this_pos,
                         multimap<string, unsigned long>* HeteroBarcode)
{
    //    2017-10-30: filter interleaving reads
    //                check if there are same barcode-reads covering the same allele at some variants!!!
    //                more possibly, these reads are from molecules with the same chr#barcode but from different plants.
    
    // formatInfo   : GT:DP:RO:QR:AO:QA:GL:BX:PS - can be different but must contain 'BX' flag
    // barcodeString: real values corresponding to the above format
    // vbc          : barcodes related to variant   allele
    // rbc          : barcodes related to reference allele
    vector<string> fmt = split_string(formatInfo, ':');
    int pos = -1;
    for(int i = 0; i < fmt.size(); i ++)
    {
        if(fmt[i].compare("BX") == 0)
        {
            pos = i;
            break;
        }
    }
    if(pos < 0)
    {
        cout << "   Error: no BX found in FORMAT. " << endl;
        return false;
    }
    vector<string> bcode = split_string(barcodeString, ':');
    if(bcode.size() != fmt.size())
    {
        cout << "   Error: sizes of FORMAT and VALUE mismatched." << endl;
        return false;
    }
    // find barcodes related to all alleles
    string b_all     = bcode[pos];
    // find barcodes related to alternative allele, after ',': "bcr1-;bcr2-,bcv1-;bcv2-;bcv3-"
    size_t seRefAlt  = b_all.find(",");
    assert(seRefAlt != std::string::npos);    
    //
    string b_var     = b_all.substr(seRefAlt+1);
    if(b_var.size()>15)
    {
        (*vbc)           = split_string(b_var, ';');
        // remove redundant info
        vector<string>::iterator itr;
        vector<string>::iterator itr_end;
        itr        = (*vbc).begin();
        itr_end    = (*vbc).end();  
        while(itr != itr_end)
        {
            string tmp      = *itr;
            size_t trashpos = tmp.find("-");
            if(trashpos == std::string::npos)
            {
                trashpos = tmp.size();
            }
            if(trashpos > 0)
            (*itr)          = tmp.substr(0, trashpos);
            itr             ++;
        }
    }
    else
    {
        (*vbc).clear(); // possibly no variant barcode? no!
    }
    // find barcodes related to reference allele, before ',': "bcr1-;bcr2-,bcv1-;bcv2-;bcv3-"
    string b_ref     = b_all.substr(0, seRefAlt);
    if(b_ref.size()>15)
    {
        (*rbc)           = split_string(b_ref, ';');
        // remove redundant info
        vector<string>::iterator itr;
        vector<string>::iterator itr_end;        
        itr        = (*rbc).begin();
        itr_end    = (*rbc).end();
        while(itr != (*rbc).end()) // note that (*rbc).end() is changing, so itr_end cannot be used here!!!
        {
            string tmp      = *itr;
            size_t trashpos = tmp.find("-");
            if(trashpos == std::string::npos)
            {
                trashpos = tmp.size();
            }
            if(trashpos > 0)
            (*itr)          = tmp.substr(0, trashpos);
            vector<string>::iterator overlapitr = std::find((*vbc).begin(), (*vbc).end(), *itr);
            if(overlapitr != (*vbc).end())
            {
                if(badBarcodeCov == 0)
                {
                    cout << "   Info: barcode " <<  *itr << " of "     << barcodeString 
                         << " covers both reference and alternative. " << endl;
                    cout << "   Warning: molecules with such barcodes removed (a total number given in the end). " 
                         << endl;
                }
                else
                {
                    if(false)
                    {
                        cout << "   Info: barcode " <<  *itr << " of " 
                             << barcodeString << " covers both reference and alternative. " << endl;
                    }
                }
                // count
                badBarcodeCov ++;
                // this is the barcode for removing falsely merged molecule covering the heterozgous mkr pos
                //(*vbc).erase(overlapitr);
                //itr = (*rbc).erase(itr);
                unsigned long mkrposwithbadbc = strtoul(this_pos.c_str(), NULL, 0);
                (*HeteroBarcode).insert(std::pair<string, unsigned long>(this_chr+"#"+(*itr), mkrposwithbadbc));
            }
            // next barcode
            itr ++;
        }
    }
    else
    {
        (*rbc).clear(); // possibly no variant barcode? yes!
    }
    return true;
}

// Assembly:
subq $0x338, %rsp            # imm = 0x338
movq %r9, 0x68(%rsp)
movq %r8, 0x70(%rsp)
movq %rsi, %rax
movq %rax, 0x78(%rsp)
movq %rdi, %rsi
movq 0x340(%rsp), %rdi
movq %rsi, 0x328(%rsp)
movq %rax, 0x320(%rsp)
movq %rdx, 0x318(%rsp)
movq %rcx, 0x310(%rsp)
movq %r8, 0x308(%rsp)
movq %r9, 0x300(%rsp)
movb $0x3a, 0x2e7(%rsp)
leaq 0x2e8(%rsp), %rdi
leaq 0x2e7(%rsp), %rdx
callq 0x60790
movl $0xffffffff, 0x2e0(%rsp) # imm = 0xFFFFFFFF
movl $0x0, 0x2dc(%rsp)
movslq 0x2dc(%rsp), %rax
movq %rax, 0x60(%rsp)
leaq 0x2e8(%rsp), %rdi
callq 0xfbb0
movq %rax, %rcx
movq 0x60(%rsp), %rax
cmpq %rcx, %rax
jae 0x2bfcc
movslq 0x2dc(%rsp), %rsi
leaq 0x2e8(%rsp), %rdi
callq 0x88f0
movq %rax, %rdi
leaq 0x3cc24(%rip), %rsi     # 0x68bc1
callq 0x5140
cmpl $0x0, %eax
jne 0x2bfb7
movl 0x2dc(%rsp), %eax
movl %eax, 0x2e0(%rsp)
jmp 0x2bfcc
jmp 0x2bfb9
movl 0x2dc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x2dc(%rsp)
jmp 0x2bf57
cmpl $0x0, 0x2e0(%rsp)
jge 0x2c034
movq 0x58feb(%rip), %rdi     # 0x84fc8
leaq 0x3cbe0(%rip), %rsi     # 0x68bc4
callq 0x5460
movq %rax, 0x58(%rsp)
jmp 0x2bff0
movq 0x58(%rsp), %rdi
movq 0x58fb4(%rip), %rsi     # 0x84fb0
callq 0x54b0
jmp 0x2c003
movb $0x0, 0x337(%rsp)
movl $0x1, 0x2c8(%rsp)
jmp 0x2c938
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2d0(%rsp)
movl %eax, 0x2cc(%rsp)
jmp 0x2c956
movq 0x78(%rsp), %rsi
movb $0x3a, 0x2af(%rsp)
leaq 0x2b0(%rsp), %rdi
leaq 0x2af(%rsp), %rdx
callq 0x60790
jmp 0x2c058
leaq 0x2b0(%rsp), %rdi
callq 0xfbb0
movq %rax, 0x50(%rsp)
leaq 0x2e8(%rsp), %rdi
callq 0xfbb0
movq %rax, %rcx
movq 0x50(%rsp), %rax
cmpq %rcx, %rax
je 0x2c0e2
movq 0x58f3d(%rip), %rdi     # 0x84fc8
leaq 0x3cb54(%rip), %rsi     # 0x68be6
callq 0x5460
movq %rax, 0x48(%rsp)
jmp 0x2c09e
movq 0x48(%rsp), %rdi
movq 0x58f06(%rip), %rsi     # 0x84fb0
callq 0x54b0
jmp 0x2c0b1
movb $0x0, 0x337(%rsp)
movl $0x1, 0x2c8(%rsp)
jmp 0x2c91a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2d0(%rsp)
movl %eax, 0x2cc(%rsp)
jmp 0x2c929
movslq 0x2e0(%rsp), %rsi
leaq 0x2b0(%rsp), %rdi
callq 0x88f0
movq %rax, %rsi
leaq 0x288(%rsp), %rdi
callq 0x51f0
jmp 0x2c109
leaq 0x288(%rsp), %rdi
leaq 0x3ad88(%rip), %rsi     # 0x66ea0
xorl %eax, %eax
movl %eax, %edx
callq 0x5870
movq %rax, 0x280(%rsp)
cmpq $-0x1, 0x280(%rsp)
je 0x2c136
jmp 0x2c155
leaq 0x3cad9(%rip), %rdi     # 0x68c16
leaq 0x3bdf9(%rip), %rsi     # 0x67f3d
movl $0x6c8, %edx            # imm = 0x6C8
leaq 0x3cae4(%rip), %rcx     # 0x68c34
callq 0x52d0
movq 0x280(%rsp), %rdx
incq %rdx
leaq 0x260(%rsp), %rdi
leaq 0x288(%rsp), %rsi
movq $-0x1, %rcx
callq 0x5490
jmp 0x2c17e
leaq 0x260(%rsp), %rdi
callq 0x5310
cmpq $0xf, %rax
jbe 0x2c39e
movb $0x3b, 0x247(%rsp)
leaq 0x248(%rsp), %rdi
leaq 0x260(%rsp), %rsi
leaq 0x247(%rsp), %rdx
callq 0x60790
jmp 0x2c1bc
movq 0x318(%rsp), %rdi
leaq 0x248(%rsp), %rsi
callq 0x2e2d0
leaq 0x248(%rsp), %rdi
callq 0x8910
leaq 0x238(%rsp), %rdi
callq 0x2de30
leaq 0x230(%rsp), %rdi
callq 0x2de30
movq 0x318(%rsp), %rdi
callq 0x2d110
movq %rax, 0x228(%rsp)
movq 0x228(%rsp), %rax
movq %rax, 0x238(%rsp)
movq 0x318(%rsp), %rdi
callq 0x2d140
movq %rax, 0x220(%rsp)
movq 0x220(%rsp), %rax
movq %rax, 0x230(%rsp)
leaq 0x238(%rsp), %rdi
leaq 0x230(%rsp), %rsi
callq 0x2d170
testb $0x1, %al
jne 0x2c260
jmp 0x2c39c
leaq 0x238(%rsp), %rdi
callq 0x2d1b0
movq %rax, %rsi
leaq 0x200(%rsp), %rdi
callq 0x51f0
jmp 0x2c27f
leaq 0x200(%rsp), %rdi
leaq 0x3a320(%rip), %rsi     # 0x665ae
xorl %eax, %eax
movl %eax, %edx
callq 0x5870
movq %rax, 0x1f8(%rsp)
cmpq $-0x1, 0x1f8(%rsp)
jne 0x2c2f3
leaq 0x200(%rsp), %rdi
callq 0x5310
movq %rax, 0x1f8(%rsp)
jmp 0x2c2f3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2d0(%rsp)
movl %eax, 0x2cc(%rsp)
jmp 0x2c90b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2d0(%rsp)
movl %eax, 0x2cc(%rsp)
jmp 0x2c8fe
cmpq $0x0, 0x1f8(%rsp)
jbe 0x2c373
movq 0x1f8(%rsp), %rcx
xorl %eax, %eax
movl %eax, %edx
leaq 0x1d8(%rsp), %rdi
leaq 0x200(%rsp), %rsi
callq 0x5490
jmp 0x2c321
leaq 0x238(%rsp), %rdi
callq 0x2d1b0
movq %rax, %rdi
leaq 0x1d8(%rsp), %rsi
callq 0x5550
leaq 0x1d8(%rsp), %rdi
callq 0x58b8
jmp 0x2c373
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2d0(%rsp)
movl %eax, 0x2cc(%rsp)
leaq 0x200(%rsp), %rdi
callq 0x58b8
jmp 0x2c8fe
leaq 0x238(%rsp), %rdi
xorl %esi, %esi
callq 0x2d340
movq %rax, 0x1d0(%rsp)
leaq 0x200(%rsp), %rdi
callq 0x58b8
jmp 0x2c242
jmp 0x2c3ab
movq 0x318(%rsp), %rdi
callq 0x2e310
movq 0x280(%rsp), %rcx
xorl %eax, %eax
movl %eax, %edx
leaq 0x1b0(%rsp), %rdi
leaq 0x288(%rsp), %rsi
callq 0x5490
jmp 0x2c3ce
leaq 0x1b0(%rsp), %rdi
callq 0x5310
cmpq $0xf, %rax
jbe 0x2c8a8
movb $0x3b, 0x197(%rsp)
leaq 0x198(%rsp), %rdi
leaq 0x1b0(%rsp), %rsi
leaq 0x197(%rsp), %rdx
callq 0x60790
jmp 0x2c40c
movq 0x310(%rsp), %rdi
leaq 0x198(%rsp), %rsi
callq 0x2e2d0
leaq 0x198(%rsp), %rdi
callq 0x8910
leaq 0x188(%rsp), %rdi
callq 0x2de30
leaq 0x180(%rsp), %rdi
callq 0x2de30
movq 0x310(%rsp), %rdi
callq 0x2d110
movq %rax, 0x178(%rsp)
movq 0x178(%rsp), %rax
movq %rax, 0x188(%rsp)
movq 0x310(%rsp), %rdi
callq 0x2d140
movq %rax, 0x170(%rsp)
movq 0x170(%rsp), %rax
movq %rax, 0x180(%rsp)
movq 0x310(%rsp), %rdi
callq 0x2d140
movq %rax, 0x168(%rsp)
leaq 0x188(%rsp), %rdi
leaq 0x168(%rsp), %rsi
callq 0x2d170
testb $0x1, %al
jne 0x2c4c5
jmp 0x2c8a6
leaq 0x188(%rsp), %rdi
callq 0x2d1b0
movq %rax, %rsi
leaq 0x148(%rsp), %rdi
callq 0x51f0
jmp 0x2c4e4
leaq 0x148(%rsp), %rdi
leaq 0x3a0bb(%rip), %rsi     # 0x665ae
xorl %eax, %eax
movl %eax, %edx
callq 0x5870
movq %rax, 0x140(%rsp)
cmpq $-0x1, 0x140(%rsp)
jne 0x2c53f
leaq 0x148(%rsp), %rdi
callq 0x5310
movq %rax, 0x140(%rsp)
jmp 0x2c53f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2d0(%rsp)
movl %eax, 0x2cc(%rsp)
jmp 0x2c8f1
cmpq $0x0, 0x140(%rsp)
jbe 0x2c5b2
movq 0x140(%rsp), %rcx
xorl %eax, %eax
movl %eax, %edx
leaq 0x120(%rsp), %rdi
leaq 0x148(%rsp), %rsi
callq 0x5490
jmp 0x2c56d
leaq 0x188(%rsp), %rdi
callq 0x2d1b0
movq %rax, %rdi
leaq 0x120(%rsp), %rsi
callq 0x5550
leaq 0x120(%rsp), %rdi
callq 0x58b8
jmp 0x2c5b2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2d0(%rsp)
movl %eax, 0x2cc(%rsp)
jmp 0x2c897
movq 0x318(%rsp), %rdi
callq 0x2d110
movq %rax, 0x110(%rsp)
movq 0x318(%rsp), %rdi
callq 0x2d140
movq %rax, 0x108(%rsp)
leaq 0x188(%rsp), %rdi
callq 0x2d1b0
movq %rax, %rdx
movq 0x110(%rsp), %rdi
movq 0x108(%rsp), %rsi
callq 0x2e330
movq %rax, 0x40(%rsp)
jmp 0x2c608
movq 0x40(%rsp), %rax
movq %rax, 0x118(%rsp)
movq 0x318(%rsp), %rdi
callq 0x2d140
movq %rax, 0x100(%rsp)
leaq 0x118(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x2d170
testb $0x1, %al
jne 0x2c648
jmp 0x2c86e
cmpq $0x0, 0x58e58(%rip)     # 0x854a8
jne 0x2c719
movq 0x5896b(%rip), %rdi     # 0x84fc8
leaq 0x3c650(%rip), %rsi     # 0x68cb4
callq 0x5460
movq %rax, 0x38(%rsp)
jmp 0x2c670
leaq 0x188(%rsp), %rdi
callq 0x2d1b0
movq 0x38(%rsp), %rdi
movq %rax, %rsi
callq 0x53e0
movq %rax, 0x30(%rsp)
jmp 0x2c691
movq 0x30(%rsp), %rdi
leaq 0x3c8f0(%rip), %rsi     # 0x68f8d
callq 0x5460
movq %rax, 0x28(%rsp)
jmp 0x2c6a9
movq 0x78(%rsp), %rsi
movq 0x28(%rsp), %rdi
callq 0x53e0
movq %rax, 0x20(%rsp)
jmp 0x2c6bf
movq 0x20(%rsp), %rdi
leaq 0x3c5fb(%rip), %rsi     # 0x68cc6
callq 0x5460
movq %rax, 0x18(%rsp)
jmp 0x2c6d7
movq 0x18(%rsp), %rdi
movq 0x588cd(%rip), %rsi     # 0x84fb0
callq 0x54b0
jmp 0x2c6ea
movq 0x588d7(%rip), %rdi     # 0x84fc8
leaq 0x3c5f7(%rip), %rsi     # 0x68cef
callq 0x5460
movq %rax, 0x10(%rsp)
jmp 0x2c704
movq 0x10(%rsp), %rdi
movq 0x588a0(%rip), %rsi     # 0x84fb0
callq 0x54b0
jmp 0x2c717
jmp 0x2c71b
jmp 0x2c71b
movq 0x68(%rsp), %rdi
movq 0x58d81(%rip), %rax     # 0x854a8
incq %rax
movq %rax, 0x58d77(%rip)     # 0x854a8
callq 0x51d0
movq %rax, %rdi
xorl %edx, %edx
movl %edx, %esi
callq 0x5160
movq 0x70(%rsp), %rsi
movq %rax, 0xf8(%rsp)
movq 0x340(%rsp), %rax
movq %rax, 0x8(%rsp)
leaq 0x3e8ff(%rip), %rdx     # 0x6b062
leaq 0x90(%rsp), %rdi
callq 0xfae0
jmp 0x2c772
leaq 0x188(%rsp), %rdi
callq 0x2d1b0
movq %rax, %rdx
leaq 0xb0(%rsp), %rdi
leaq 0x90(%rsp), %rsi
callq 0xfbf0
jmp 0x2c799
leaq 0xd0(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
leaq 0xf8(%rsp), %rdx
callq 0x2e3c0
jmp 0x2c7b8
movq 0x8(%rsp), %rdi
leaq 0xd0(%rsp), %rsi
callq 0x2e390
movq %rax, (%rsp)
jmp 0x2c7d0
movq (%rsp), %rax
movq %rax, 0x88(%rsp)
leaq 0xd0(%rsp), %rdi
callq 0x10220
leaq 0xb0(%rsp), %rdi
callq 0x58b8
leaq 0x90(%rsp), %rdi
callq 0x58b8
jmp 0x2c86e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2d0(%rsp)
movl %eax, 0x2cc(%rsp)
jmp 0x2c85f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2d0(%rsp)
movl %eax, 0x2cc(%rsp)
jmp 0x2c852
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2d0(%rsp)
movl %eax, 0x2cc(%rsp)
leaq 0xd0(%rsp), %rdi
callq 0x10220
leaq 0xb0(%rsp), %rdi
callq 0x58b8
leaq 0x90(%rsp), %rdi
callq 0x58b8
jmp 0x2c897
leaq 0x188(%rsp), %rdi
xorl %esi, %esi
callq 0x2d340
movq %rax, 0x80(%rsp)
leaq 0x148(%rsp), %rdi
callq 0x58b8
jmp 0x2c492
leaq 0x148(%rsp), %rdi
callq 0x58b8
jmp 0x2c8f1
jmp 0x2c8b5
movq 0x310(%rsp), %rdi
callq 0x2e310
movb $0x1, 0x337(%rsp)
movl $0x1, 0x2c8(%rsp)
leaq 0x1b0(%rsp), %rdi
callq 0x58b8
leaq 0x260(%rsp), %rdi
callq 0x58b8
leaq 0x288(%rsp), %rdi
callq 0x58b8
jmp 0x2c91a
leaq 0x1b0(%rsp), %rdi
callq 0x58b8
leaq 0x260(%rsp), %rdi
callq 0x58b8
leaq 0x288(%rsp), %rdi
callq 0x58b8
jmp 0x2c929
leaq 0x2b0(%rsp), %rdi
callq 0x8910
jmp 0x2c938
leaq 0x2b0(%rsp), %rdi
callq 0x8910
jmp 0x2c956
leaq 0x2e8(%rsp), %rdi
callq 0x8910
movb 0x337(%rsp), %al
andb $0x1, %al
addq $0x338, %rsp            # imm = 0x338
retq
leaq 0x2e8(%rsp), %rdi
callq 0x8910
movq 0x2d0(%rsp), %rdi
callq 0x57b0