// File: /workspace/github_c_makefile_star2_O2/nh13[P]ksw/src/parasail/apps/parasail_aligner.cpp
// Function: output_graph(_IO_FILE*, int, unsigned char*, int, int, int, parasail_matrix const*, std::vector<long, std::allocator<long>> const&, std::vector<long, std::allocator<long>> const&, std::vector<std::pair<int, int>, std::allocator<std::pair<int, int>>> const&, std::vector<parasail_result*, std::allocator<parasail_result*>> const&, std::vector<std::vector<std::pair<int, float>, std::allocator<std::pair<int, float>>>, std::allocator<std::vector<std::pair<int, float>, std::allocator<std::pair<int, float>>>>>&, unsigned long&, long long, long long)
inline static void output_graph(
        FILE *fop,
        int which,
        unsigned char *T,
        int AOL,
        int SIM,
        int OS,
        const parasail_matrix_t *matrix,
        const vector<long> &BEG,
        const vector<long> &END,
        const PairVec &vpairs,
        const vector<parasail_result_t*> &results,
        vector<vector<pair<int,float> > > &graph,
        unsigned long &edge_count,
        long long start,
        long long stop)
{
    if (NULL == fop) {
        for (long long index=start; index<stop; ++index) {
            parasail_result_t *result = results[index];
            int i = vpairs[index].first;
            int j = vpairs[index].second;
            long i_beg = BEG[i];
            long i_end = END[i];
            long i_len = i_end-i_beg;
            long j_beg = BEG[j];
            long j_end = END[j];
            long j_len = j_end-j_beg;

            if (parasail_result_is_saturated(result)) {
                fprintf(stderr, "seq %d and seq %d saturated\n", i, j);
                continue;
            }

            int score = parasail_result_get_score(result);
            int matches = parasail_result_get_matches(result);
            int length = parasail_result_get_length(result);
            int self_score_ = 0;
            int max_len = 0;
            int i_self_score = self_score(
                    (const char*)&T[i_beg], i_len, matrix);
            int j_self_score = self_score(
                    (const char*)&T[j_beg], j_len, matrix);

            if (i_len > j_len) {
                max_len = i_len;
                self_score_ = i_self_score;
            }
            else {
                max_len = j_len;
                self_score_ = j_self_score;
            }

            if ((length * 100 >= AOL * int(max_len))
                    && (matches * 100 >= SIM * length)
                    && (score * 100 >= OS * self_score_)) {
                float value;
                ++edge_count;
                switch (which) {
                    case 0:
                        value = 1.0*length/max_len;
                        break;
                    case 1:
                        value = 1.0*matches/length;
                        break;
                    case 2:
                        value = 1.0*score/self_score_;
                        break;
                }
                graph[i].push_back(make_pair(j,value));
                graph[j].push_back(make_pair(i,value));
            }
        }
    }
    else {
        fprintf(fop, "%lu %lu 1\n", (unsigned long)graph.size(), edge_count);
        for (size_t i=0; i<graph.size(); ++i) {
            if (graph[i].size() > 0) {
                fprintf(fop, "%d %f", graph[i][0].first+1, graph[i][0].second);
                for (size_t j=1; j<graph[i].size(); ++j) {
                    fprintf(fop, "  %d %f", graph[i][j].first+1, graph[i][j].second);
                }
                fprintf(fop, "\n");
            } else {
                fprintf(fop, "\n");
            }
        }
        fprintf(stdout, "%20s: %lu\n", "edges count", edge_count);
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movq %rdi, %r13
movq 0xe8(%rsp), %rdi
movq 0xe0(%rsp), %rbp
testq %r13, %r13
movq %rdi, 0x28(%rsp)
je 0x2a4392
movq 0x8(%rbp), %rax
subq (%rbp), %rax
pushq $0x18
popq %rcx
cqto
idivq %rcx
movq (%rdi), %rcx
leaq 0x3d151f(%rip), %rsi    # 0x6757d5
xorl %r14d, %r14d
movq %r13, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x2a0380
leaq 0x3d1513(%rip), %r15    # 0x6757e0
movq (%rbp), %rcx
movq 0x8(%rbp), %rax
subq %rcx, %rax
cqto
pushq $0x18
popq %rsi
idivq %rsi
cmpq %rax, %r14
jae 0x2a435a
imulq $0x18, %r14, %r12
movq (%rcx,%r12), %rax
cmpq %rax, 0x8(%rcx,%r12)
je 0x2a4347
movl (%rax), %edx
incl %edx
cvtss2sd 0x4(%rax), %xmm0
movq %r13, %rdi
leaq 0x3d14db(%rip), %rsi    # 0x6757e2
movb $0x1, %al
callq 0x2a0380
pushq $0x1
popq %rbx
movq (%rbp), %rcx
movq (%rcx,%r12), %rax
movq 0x8(%rcx,%r12), %rcx
subq %rax, %rcx
sarq $0x3, %rcx
cmpq %rcx, %rbx
jae 0x2a4347
movl (%rax,%rbx,8), %edx
incl %edx
cvtss2sd 0x4(%rax,%rbx,8), %xmm0
movq %r13, %rdi
movq %r15, %rsi
movb $0x1, %al
callq 0x2a0380
incq %rbx
jmp 0x2a4311
pushq $0xa
popq %rdi
movq %r13, %rsi
callq 0x2a0310
incq %r14
jmp 0x2a42cd
movq 0x5d0c47(%rip), %rax    # 0x874fa8
movq (%rax), %rdi
movq 0x28(%rsp), %rax
movq (%rax), %rcx
leaq 0x3d0723(%rip), %rsi    # 0x674a96
leaq 0x3d146e(%rip), %rdx    # 0x6757e8
xorl %eax, %eax
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x2a0380
movq 0xf8(%rsp), %rax
movq %rax, 0x78(%rsp)
movq 0xf0(%rsp), %rdi
movq 0xd8(%rsp), %rax
movq %rax, 0x70(%rsp)
movq 0xd0(%rsp), %rax
movq %rax, 0x68(%rsp)
movq 0xc8(%rsp), %rax
movq %rax, 0x60(%rsp)
movq 0xc0(%rsp), %rax
movq %rax, 0x58(%rsp)
movl %r8d, 0x18(%rsp)
movl %ecx, 0x14(%rsp)
movl %edx, 0x10(%rsp)
movq %rsi, 0x50(%rsp)
movq %r9, 0x48(%rsp)
cmpq 0x78(%rsp), %rdi
jge 0x2a45aa
movq 0x70(%rsp), %rax
movq (%rax), %rax
movq (%rax,%rdi,8), %r15
movq 0x68(%rsp), %rax
movq (%rax), %rax
movslq (%rax,%rdi,8), %rsi
movq %rdi, 0x80(%rsp)
movslq 0x4(%rax,%rdi,8), %rdx
movq 0x58(%rsp), %rax
movq (%rax), %rax
movq (%rax,%rsi,8), %r12
movq 0x60(%rsp), %rcx
movq (%rcx), %rcx
movq %rsi, 0x30(%rsp)
movq (%rcx,%rsi,8), %rbx
movq (%rax,%rdx,8), %r14
movq %rdx, 0x38(%rsp)
movq (%rcx,%rdx,8), %r13
movq %r15, %rdi
callq 0x2b2446
testl %eax, %eax
jne 0x2a4578
subq %r14, %r13
subq %r12, %rbx
movq %r15, %rdi
callq 0x2b2724
movl %eax, 0x1c(%rsp)
movq %r15, %rdi
callq 0x2b27c8
movl %eax, 0x20(%rsp)
movq %r15, %rdi
callq 0x2b288b
movl %eax, 0x8(%rsp)
movq 0x50(%rsp), %r15
addq %r15, %r12
movq %r12, %rdi
movl %ebx, %esi
movq 0x48(%rsp), %r12
movq %r12, %rdx
callq 0x2a58ac
movl %eax, 0x24(%rsp)
addq %r15, %r14
movq %r14, %rdi
movl %r13d, %esi
movq %r12, %rdx
callq 0x2a58ac
movl 0x8(%rsp), %r9d
cmpq %r13, %rbx
cmovgl 0x24(%rsp), %eax
cmovleq %r13, %rbx
imull $0x64, %r9d, %ecx
movl %ebx, %esi
movl 0x10(%rsp), %edx
imull %edx, %esi
cmpl %esi, %ecx
movq 0x28(%rsp), %rsi
movl 0x18(%rsp), %r13d
movl 0x14(%rsp), %ecx
jl 0x2a459a
imull $0x64, 0x20(%rsp), %edi
movl %r9d, %r8d
imull %ecx, %r8d
cmpl %r8d, %edi
jl 0x2a459a
imull $0x64, 0x1c(%rsp), %edi
imull %r13d, %eax
cmpl %eax, %edi
jl 0x2a459a
incq (%rsi)
cvtsi2sd %r9d, %xmm0
cvtsi2sd %ebx, %xmm1
movq 0x30(%rsp), %rcx
movl %ecx, %eax
movq %rax, 0x8(%rsp)
divsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movq 0x38(%rsp), %rbx
movl %ebx, %eax
imulq $0x18, %rcx, %rdi
addq (%rbp), %rdi
movd %xmm0, %r14d
shlq $0x20, %r14
orq %r14, %rax
movq %rax, 0x40(%rsp)
leaq 0x40(%rsp), %r15
movq %r15, %rsi
callq 0x2a6e82
imulq $0x18, %rbx, %rdi
addq (%rbp), %rdi
addq 0x8(%rsp), %r14
movq %r14, 0x40(%rsp)
movq %r15, %rsi
callq 0x2a6e82
jmp 0x2a459a
movq 0x5d0a59(%rip), %rax    # 0x874fd8
movq (%rax), %rdi
leaq 0x3d122f(%rip), %rsi    # 0x6757b8
movq 0x30(%rsp), %rdx
movq 0x38(%rsp), %rcx
xorl %eax, %eax
callq 0x2a0380
movq 0x80(%rsp), %rdi
incq %rdi
jmp 0x2a43f2
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq