// File: chhylp123[P]hifiasm/hic.cpp
// Function: get_available_com(H_partition*, bubble_type*, ma_ug_t*, unsigned int, unsigned int, unsigned char*, unsigned int*)
uint32_t get_available_com(H_partition* hap, bubble_type* bub, ma_ug_t *ug, uint32_t check_self, uint32_t check_others, 
uint8_t* hap_label_flag, uint32_t* max_hap_label)
{
    hc_links* link = hap->link;
    uint32_t beg, sink, n, *a, i, j, k, uID, max_bub_i, max_non_bub_i, max_i, is_ava;
    uint32_t hap_label, max_bub_label = (uint32_t)-1, max_non_bub_label = (uint32_t)-1;
    double w, max_bub_w, max_non_bub_w;
    max_i = (uint32_t)-1;

    for (i = 0, max_bub_w = -1, max_bub_i = (uint32_t)-1; i < bub->f_bub/**bub->s_bub**/; i++)
    {
        get_bubbles(bub, i, &beg, &sink, &a, &n, NULL);
        for (j = 0, w = 0; j < n; j++)
        {
            uID = a[j]>>1;
            if(check_self && is_hap_set(uID, *hap)) break;
        }
        if(j != n) continue;

        is_ava = 0;
        hap_label = (uint32_t)-1;
        if(check_others)
        {
            if(get_weightest_hap_label_from_bubble(i, hap, bub, 
                                                    hap_label_flag, &hap_label, &w)>0)
            {
                is_ava = 1;
            }
        }
        else
        {
            for (j = 0, w = 0, is_ava = 0; j < n; j++)
            {
                uID = a[j]>>1;
                for (k = 0; k < link->a.a[uID].e.n; k++)
                {
                    if(link->a.a[uID].e.a[k].del) continue;
                    w += link->a.a[uID].e.a[k].weight;
                    is_ava = 1;
                }
            }
        }
        
        if(is_ava == 0) continue;

        if(w > max_bub_w)
        {
            max_bub_w = w;
            max_bub_i = i;
            max_bub_label = hap_label;
        }
    }

    for (i = 0, max_non_bub_w = -1, max_non_bub_i = (uint32_t)-1; i < ug->u.n; i++)
    {
        if(IF_HET(i, *bub)/** || (bub->index[i] >= bub->s_bub && bub->index[i] < bub->f_bub)**/)
        {
            uID = i;
            is_ava = 0;
            if(check_self && is_hap_set(uID, *hap)) continue;
            hap_label = (uint32_t)-1;
            if(check_others)
            {
                if(get_weightest_hap_label_from_uid(uID, hap, hap_label_flag, &hap_label, &w)>0)
                {
                    is_ava = 1;
                }
            }
            else
            {
                for (k = 0, w = 0, is_ava = 0; k < link->a.a[uID].e.n; k++)
                {
                    if(link->a.a[uID].e.a[k].del) continue;
                    w += link->a.a[uID].e.a[k].weight;
                    is_ava = 1;
                }
            }
            
            if(is_ava == 0) continue;

            if(w > max_non_bub_w)
            {
                max_non_bub_w = w;
                max_non_bub_i = i;
                max_non_bub_label = hap_label;
            }
        }
    }

    if(max_bub_i != (uint32_t)-1 && max_non_bub_i != (uint32_t)-1)
    {
        if(max_non_bub_w > max_bub_w)
        {
            max_i = (max_non_bub_i << 1) + 1;
            w = max_non_bub_w;
            (*max_hap_label) = max_non_bub_label;
        }
        else
        {
            max_i = (max_bub_i << 1);
            w = max_bub_w;
            (*max_hap_label) = max_bub_label;
        }
    }
    else if(max_bub_i != (uint32_t)-1)
    {
        max_i = (max_bub_i << 1);
        w = max_bub_w;
        (*max_hap_label) = max_bub_label;
    }
    else if(max_non_bub_i != (uint32_t)-1)
    {
        max_i = (max_non_bub_i << 1) + 1;
        w = max_non_bub_w;
        (*max_hap_label) = max_non_bub_label;
    }

    if(max_i == (uint32_t)-1)
    {
        for (i = 0, max_non_bub_w = -1, max_non_bub_i = (uint32_t)-1; i < ug->u.n; i++)
        {
            ///if(bub->index[i] < bub->s_bub)
            if(IF_BUB(i, *bub))
            {

                uID = i;
                is_ava = 0;
                if(check_self && is_hap_set(uID, *hap)) continue;
                hap_label = (uint32_t)-1;
                if(check_others)
                {
                    if(get_weightest_hap_label_from_uid(uID, hap, hap_label_flag, &hap_label, &w)>0)
                    {
                        is_ava = 1;
                    }
                }
                else
                {
                    for (k = 0, w = 0, is_ava = 0; k < link->a.a[uID].e.n; k++)
                    {
                        if(link->a.a[uID].e.a[k].del) continue;
                        w += link->a.a[uID].e.a[k].weight;
                        is_ava = 1;
                    }
                }
                
                if(is_ava == 0) continue;

                if(w > max_non_bub_w)
                {
                    max_non_bub_w = w;
                    max_non_bub_i = i;
                    max_non_bub_label = hap_label;
                }

            }
        }

        if(max_non_bub_i != (uint32_t)-1)
        {
            max_i = (max_non_bub_i << 1) + 1;
            w = max_non_bub_w;
            (*max_hap_label) = max_non_bub_label;
        }
    }

    // if(max_i == (uint32_t)-1)
    // {
    //     fprintf(stderr, "-Cannot find!\n");
    // }
    // else if(max_i & 1)
    // {
    //     fprintf(stderr, "-utg-%uth, phasing ID: %u, w: %f, max_bub_i: %u, max_bub_w: %f, max_non_bub_i: %u, max_non_bub_w: %f\n", 
    //     max_i>>1, hap->label>>3, w, max_bub_i, max_bub_w, max_non_bub_i, max_non_bub_w);
    // }
    // else
    // {
    //     fprintf(stderr, "-bubble-%uth, phasing ID: %u, w: %f, max_bub_i: %u, max_bub_w: %f, max_non_bub_i: %u, max_non_bub_w: %f\n", 
    //     max_i>>1, hap->label>>3, w, max_bub_i, max_bub_w, max_non_bub_i, max_non_bub_w);
    // }

    return max_i;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq 0x10(%rbp), %rax
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
movl %r8d, -0x20(%rbp)
movq %r9, -0x28(%rbp)
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rax
movq %rax, -0x30(%rbp)
movl $0xffffffff, -0x70(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, -0x74(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, -0x64(%rbp) # imm = 0xFFFFFFFF
movl $0x0, -0x4c(%rbp)
movsd 0x194ba2(%rip), %xmm0   # 0x382278
movsd %xmm0, -0x88(%rbp)
movl $0xffffffff, -0x5c(%rbp) # imm = 0xFFFFFFFF
movl -0x4c(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpq 0x80(%rcx), %rax
jae 0x1ed8e9
movq -0x10(%rbp), %rdi
movl -0x4c(%rbp), %eax
movl %eax, %esi
leaq -0x34(%rbp), %rdx
leaq -0x38(%rbp), %rcx
leaq -0x48(%rbp), %r8
leaq -0x3c(%rbp), %r9
xorl %eax, %eax
movq $0x0, (%rsp)
callq 0x1c4b20
movl $0x0, -0x50(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x80(%rbp)
movl -0x50(%rbp), %eax
cmpl -0x3c(%rbp), %eax
jae 0x1ed786
movq -0x48(%rbp), %rax
movl -0x50(%rbp), %ecx
movl (%rax,%rcx,4), %eax
shrl %eax
movl %eax, -0x58(%rbp)
cmpl $0x0, -0x1c(%rbp)
je 0x1ed779
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x58(%rbp), %ecx
movl (%rax,%rcx,4), %eax
movq -0x8(%rbp), %rcx
movl 0x18(%rcx), %ecx
movq -0x8(%rbp), %rdx
orl 0x1c(%rdx), %ecx
movq -0x8(%rbp), %rdx
orl 0x20(%rdx), %ecx
andl %ecx, %eax
cmpl $0x0, %eax
je 0x1ed779
jmp 0x1ed786
jmp 0x1ed77b
movl -0x50(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x50(%rbp)
jmp 0x1ed730
movl -0x50(%rbp), %eax
cmpl -0x3c(%rbp), %eax
je 0x1ed793
jmp 0x1ed8db
movl $0x0, -0x68(%rbp)
movl $0xffffffff, -0x6c(%rbp) # imm = 0xFFFFFFFF
cmpl $0x0, -0x20(%rbp)
je 0x1ed7d6
movl -0x4c(%rbp), %eax
movl %eax, %edi
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rdx
movq -0x28(%rbp), %rcx
leaq -0x6c(%rbp), %r8
leaq -0x80(%rbp), %r9
callq 0x1ed1f0
cmpl $0x0, %eax
jbe 0x1ed7d1
movl $0x1, -0x68(%rbp)
jmp 0x1ed8a9
movl $0x0, -0x50(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x80(%rbp)
movl $0x0, -0x68(%rbp)
movl -0x50(%rbp), %eax
cmpl -0x3c(%rbp), %eax
jae 0x1ed8a7
movq -0x48(%rbp), %rax
movl -0x50(%rbp), %ecx
movl (%rax,%rcx,4), %eax
shrl %eax
movl %eax, -0x58(%rbp)
movl $0x0, -0x54(%rbp)
movl -0x54(%rbp), %eax
movq -0x30(%rbp), %rcx
movq 0x10(%rcx), %rcx
movl -0x58(%rbp), %edx
imulq $0x30, %rdx, %rdx
addq %rdx, %rcx
cmpq (%rcx), %rax
jae 0x1ed897
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x58(%rbp), %ecx
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
movq 0x10(%rax), %rax
movl -0x54(%rbp), %ecx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movb 0x18(%rax), %al
shrb $0x7, %al
cmpb $0x0, %al
je 0x1ed854
jmp 0x1ed889
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x58(%rbp), %ecx
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
movq 0x10(%rax), %rax
movl -0x54(%rbp), %ecx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movsd (%rax), %xmm0
addsd -0x80(%rbp), %xmm0
movsd %xmm0, -0x80(%rbp)
movl $0x1, -0x68(%rbp)
movl -0x54(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x54(%rbp)
jmp 0x1ed80e
jmp 0x1ed899
movl -0x50(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x50(%rbp)
jmp 0x1ed7ec
jmp 0x1ed8a9
cmpl $0x0, -0x68(%rbp)
jne 0x1ed8b1
jmp 0x1ed8db
movsd -0x80(%rbp), %xmm0
ucomisd -0x88(%rbp), %xmm0
jbe 0x1ed8d9
movsd -0x80(%rbp), %xmm0
movsd %xmm0, -0x88(%rbp)
movl -0x4c(%rbp), %eax
movl %eax, -0x5c(%rbp)
movl -0x6c(%rbp), %eax
movl %eax, -0x70(%rbp)
jmp 0x1ed8db
movl -0x4c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rbp)
jmp 0x1ed6e5
movl $0x0, -0x4c(%rbp)
movsd 0x194980(%rip), %xmm0   # 0x382278
movsd %xmm0, -0x90(%rbp)
movl $0xffffffff, -0x60(%rbp) # imm = 0xFFFFFFFF
movl -0x4c(%rbp), %eax
movq -0x18(%rbp), %rcx
cmpq (%rcx), %rax
jae 0x1eda99
movq -0x10(%rbp), %rax
movq (%rax), %rax
movl -0x4c(%rbp), %ecx
movl (%rax,%rcx,4), %eax
movq -0x10(%rbp), %rcx
movq 0x80(%rcx), %rcx
addq $0x1, %rcx
cmpq %rcx, %rax
jne 0x1eda89
movl -0x4c(%rbp), %eax
movl %eax, -0x58(%rbp)
movl $0x0, -0x68(%rbp)
cmpl $0x0, -0x1c(%rbp)
je 0x1ed97e
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x58(%rbp), %ecx
movl (%rax,%rcx,4), %eax
movq -0x8(%rbp), %rcx
movl 0x18(%rcx), %ecx
movq -0x8(%rbp), %rdx
orl 0x1c(%rdx), %ecx
movq -0x8(%rbp), %rdx
orl 0x20(%rdx), %ecx
andl %ecx, %eax
cmpl $0x0, %eax
je 0x1ed97e
jmp 0x1eda8b
movl $0xffffffff, -0x6c(%rbp) # imm = 0xFFFFFFFF
cmpl $0x0, -0x20(%rbp)
je 0x1ed9b6
movl -0x58(%rbp), %eax
movl %eax, %edi
movq -0x8(%rbp), %rsi
movq -0x28(%rbp), %rdx
leaq -0x6c(%rbp), %rcx
leaq -0x80(%rbp), %r8
callq 0x1ecdc0
cmpl $0x0, %eax
jbe 0x1ed9b1
movl $0x1, -0x68(%rbp)
jmp 0x1eda57
movl $0x0, -0x54(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x80(%rbp)
movl $0x0, -0x68(%rbp)
movl -0x54(%rbp), %eax
movq -0x30(%rbp), %rcx
movq 0x10(%rcx), %rcx
movl -0x58(%rbp), %edx
imulq $0x30, %rdx, %rdx
addq %rdx, %rcx
cmpq (%rcx), %rax
jae 0x1eda55
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x58(%rbp), %ecx
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
movq 0x10(%rax), %rax
movl -0x54(%rbp), %ecx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movb 0x18(%rax), %al
shrb $0x7, %al
cmpb $0x0, %al
je 0x1eda12
jmp 0x1eda47
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x58(%rbp), %ecx
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
movq 0x10(%rax), %rax
movl -0x54(%rbp), %ecx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movsd (%rax), %xmm0
addsd -0x80(%rbp), %xmm0
movsd %xmm0, -0x80(%rbp)
movl $0x1, -0x68(%rbp)
movl -0x54(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x54(%rbp)
jmp 0x1ed9cc
jmp 0x1eda57
cmpl $0x0, -0x68(%rbp)
jne 0x1eda5f
jmp 0x1eda8b
movsd -0x80(%rbp), %xmm0
ucomisd -0x90(%rbp), %xmm0
jbe 0x1eda87
movsd -0x80(%rbp), %xmm0
movsd %xmm0, -0x90(%rbp)
movl -0x4c(%rbp), %eax
movl %eax, -0x60(%rbp)
movl -0x6c(%rbp), %eax
movl %eax, -0x74(%rbp)
jmp 0x1eda89
jmp 0x1eda8b
movl -0x4c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rbp)
jmp 0x1ed907
cmpl $-0x1, -0x5c(%rbp)
je 0x1edafa
cmpl $-0x1, -0x60(%rbp)
je 0x1edafa
movsd -0x90(%rbp), %xmm0
ucomisd -0x88(%rbp), %xmm0
jbe 0x1edada
movl -0x60(%rbp), %eax
shll %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
movsd -0x90(%rbp), %xmm0
movsd %xmm0, -0x80(%rbp)
movl -0x74(%rbp), %ecx
movq 0x10(%rbp), %rax
movl %ecx, (%rax)
jmp 0x1edaf8
movl -0x5c(%rbp), %eax
shll %eax
movl %eax, -0x64(%rbp)
movsd -0x88(%rbp), %xmm0
movsd %xmm0, -0x80(%rbp)
movl -0x70(%rbp), %ecx
movq 0x10(%rbp), %rax
movl %ecx, (%rax)
jmp 0x1edb4b
cmpl $-0x1, -0x5c(%rbp)
je 0x1edb20
movl -0x5c(%rbp), %eax
shll %eax
movl %eax, -0x64(%rbp)
movsd -0x88(%rbp), %xmm0
movsd %xmm0, -0x80(%rbp)
movl -0x70(%rbp), %ecx
movq 0x10(%rbp), %rax
movl %ecx, (%rax)
jmp 0x1edb49
cmpl $-0x1, -0x60(%rbp)
je 0x1edb47
movl -0x60(%rbp), %eax
shll %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
movsd -0x90(%rbp), %xmm0
movsd %xmm0, -0x80(%rbp)
movl -0x74(%rbp), %ecx
movq 0x10(%rbp), %rax
movl %ecx, (%rax)
jmp 0x1edb49
jmp 0x1edb4b
cmpl $-0x1, -0x64(%rbp)
jne 0x1edd2e
movl $0x0, -0x4c(%rbp)
movsd 0x194714(%rip), %xmm0   # 0x382278
movsd %xmm0, -0x90(%rbp)
movl $0xffffffff, -0x60(%rbp) # imm = 0xFFFFFFFF
movl -0x4c(%rbp), %eax
movq -0x18(%rbp), %rcx
cmpq (%rcx), %rax
jae 0x1edd05
movq -0x10(%rbp), %rax
movq (%rax), %rax
movl -0x4c(%rbp), %ecx
movl (%rax,%rcx,4), %eax
movq -0x10(%rbp), %rcx
movq 0x80(%rcx), %rcx
addq $0x1, %rcx
cmpq %rcx, %rax
jae 0x1edcf5
movl -0x4c(%rbp), %eax
movl %eax, -0x58(%rbp)
movl $0x0, -0x68(%rbp)
cmpl $0x0, -0x1c(%rbp)
je 0x1edbea
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x58(%rbp), %ecx
movl (%rax,%rcx,4), %eax
movq -0x8(%rbp), %rcx
movl 0x18(%rcx), %ecx
movq -0x8(%rbp), %rdx
orl 0x1c(%rdx), %ecx
movq -0x8(%rbp), %rdx
orl 0x20(%rdx), %ecx
andl %ecx, %eax
cmpl $0x0, %eax
je 0x1edbea
jmp 0x1edcf7
movl $0xffffffff, -0x6c(%rbp) # imm = 0xFFFFFFFF
cmpl $0x0, -0x20(%rbp)
je 0x1edc22
movl -0x58(%rbp), %eax
movl %eax, %edi
movq -0x8(%rbp), %rsi
movq -0x28(%rbp), %rdx
leaq -0x6c(%rbp), %rcx
leaq -0x80(%rbp), %r8
callq 0x1ecdc0
cmpl $0x0, %eax
jbe 0x1edc1d
movl $0x1, -0x68(%rbp)
jmp 0x1edcc3
movl $0x0, -0x54(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x80(%rbp)
movl $0x0, -0x68(%rbp)
movl -0x54(%rbp), %eax
movq -0x30(%rbp), %rcx
movq 0x10(%rcx), %rcx
movl -0x58(%rbp), %edx
imulq $0x30, %rdx, %rdx
addq %rdx, %rcx
cmpq (%rcx), %rax
jae 0x1edcc1
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x58(%rbp), %ecx
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
movq 0x10(%rax), %rax
movl -0x54(%rbp), %ecx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movb 0x18(%rax), %al
shrb $0x7, %al
cmpb $0x0, %al
je 0x1edc7e
jmp 0x1edcb3
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x58(%rbp), %ecx
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
movq 0x10(%rax), %rax
movl -0x54(%rbp), %ecx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movsd (%rax), %xmm0
addsd -0x80(%rbp), %xmm0
movsd %xmm0, -0x80(%rbp)
movl $0x1, -0x68(%rbp)
movl -0x54(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x54(%rbp)
jmp 0x1edc38
jmp 0x1edcc3
cmpl $0x0, -0x68(%rbp)
jne 0x1edccb
jmp 0x1edcf7
movsd -0x80(%rbp), %xmm0
ucomisd -0x90(%rbp), %xmm0
jbe 0x1edcf3
movsd -0x80(%rbp), %xmm0
movsd %xmm0, -0x90(%rbp)
movl -0x4c(%rbp), %eax
movl %eax, -0x60(%rbp)
movl -0x6c(%rbp), %eax
movl %eax, -0x74(%rbp)
jmp 0x1edcf5
jmp 0x1edcf7
movl -0x4c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rbp)
jmp 0x1edb73
cmpl $-0x1, -0x60(%rbp)
je 0x1edd2c
movl -0x60(%rbp), %eax
shll %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
movsd -0x90(%rbp), %xmm0
movsd %xmm0, -0x80(%rbp)
movl -0x74(%rbp), %ecx
movq 0x10(%rbp), %rax
movl %ecx, (%rax)
jmp 0x1edd2e
movl -0x64(%rbp), %eax
addq $0xa0, %rsp
popq %rbp
retq
nopw (%rax,%rax)