// File: Ciaxur[P]yagb-emu/include/imgui/imgui.cpp
// Function: ImGui::NavScoreItem(ImGuiNavMoveResult*, ImRect)
static bool ImGui::NavScoreItem(ImGuiNavMoveResult* result, ImRect cand)
{
    ImGuiContext& g = *GImGui;
    ImGuiWindow* window = g.CurrentWindow;
    if (g.NavLayer != window->DC.NavLayerCurrent)
        return false;

    const ImRect& curr = g.NavScoringRect; // Current modified source rect (NB: we've applied Max.x = Min.x in NavUpdate() to inhibit the effect of having varied item width)
    g.NavScoringCount++;

    // When entering through a NavFlattened border, we consider child window items as fully clipped for scoring
    if (window->ParentWindow == g.NavWindow)
    {
        IM_ASSERT((window->Flags | g.NavWindow->Flags) & ImGuiWindowFlags_NavFlattened);
        if (!window->ClipRect.Overlaps(cand))
            return false;
        cand.ClipWithFull(window->ClipRect); // This allows the scored item to not overlap other candidates in the parent window
    }

    // We perform scoring on items bounding box clipped by the current clipping rectangle on the other axis (clipping on our movement axis would give us equal scores for all clipped items)
    // For example, this ensure that items in one column are not reached when moving vertically from items in another column.
    NavClampRectToVisibleAreaForMoveDir(g.NavMoveClipDir, cand, window->ClipRect);

    // Compute distance between boxes
    // FIXME-NAV: Introducing biases for vertical navigation, needs to be removed.
    float dbx = NavScoreItemDistInterval(cand.Min.x, cand.Max.x, curr.Min.x, curr.Max.x);
    float dby = NavScoreItemDistInterval(ImLerp(cand.Min.y, cand.Max.y, 0.2f), ImLerp(cand.Min.y, cand.Max.y, 0.8f), ImLerp(curr.Min.y, curr.Max.y, 0.2f), ImLerp(curr.Min.y, curr.Max.y, 0.8f)); // Scale down on Y to keep using box-distance for vertically touching items
    if (dby != 0.0f && dbx != 0.0f)
        dbx = (dbx / 1000.0f) + ((dbx > 0.0f) ? +1.0f : -1.0f);
    float dist_box = ImFabs(dbx) + ImFabs(dby);

    // Compute distance between centers (this is off by a factor of 2, but we only compare center distances with each other so it doesn't matter)
    float dcx = (cand.Min.x + cand.Max.x) - (curr.Min.x + curr.Max.x);
    float dcy = (cand.Min.y + cand.Max.y) - (curr.Min.y + curr.Max.y);
    float dist_center = ImFabs(dcx) + ImFabs(dcy); // L1 metric (need this for our connectedness guarantee)

    // Determine which quadrant of 'curr' our candidate item 'cand' lies in based on distance
    ImGuiDir quadrant;
    float dax = 0.0f, day = 0.0f, dist_axial = 0.0f;
    if (dbx != 0.0f || dby != 0.0f)
    {
        // For non-overlapping boxes, use distance between boxes
        dax = dbx;
        day = dby;
        dist_axial = dist_box;
        quadrant = ImGetDirQuadrantFromDelta(dbx, dby);
    }
    else if (dcx != 0.0f || dcy != 0.0f)
    {
        // For overlapping boxes with different centers, use distance between centers
        dax = dcx;
        day = dcy;
        dist_axial = dist_center;
        quadrant = ImGetDirQuadrantFromDelta(dcx, dcy);
    }
    else
    {
        // Degenerate case: two overlapping buttons with same center, break ties arbitrarily (note that LastItemId here is really the _previous_ item order, but it doesn't matter)
        quadrant = (window->DC.LastItemId < g.NavId) ? ImGuiDir_Left : ImGuiDir_Right;
    }

#if IMGUI_DEBUG_NAV_SCORING
    char buf[128];
    if (IsMouseHoveringRect(cand.Min, cand.Max))
    {
        ImFormatString(buf, IM_ARRAYSIZE(buf), "dbox (%.2f,%.2f->%.4f)\ndcen (%.2f,%.2f->%.4f)\nd (%.2f,%.2f->%.4f)\nnav %c, quadrant %c", dbx, dby, dist_box, dcx, dcy, dist_center, dax, day, dist_axial, "WENS"[g.NavMoveDir], "WENS"[quadrant]);
        ImDrawList* draw_list = GetForegroundDrawList(window);
        draw_list->AddRect(curr.Min, curr.Max, IM_COL32(255,200,0,100));
        draw_list->AddRect(cand.Min, cand.Max, IM_COL32(255,255,0,200));
        draw_list->AddRectFilled(cand.Max - ImVec2(4, 4), cand.Max + CalcTextSize(buf) + ImVec2(4, 4), IM_COL32(40,0,0,150));
        draw_list->AddText(g.IO.FontDefault, 13.0f, cand.Max, ~0U, buf);
    }
    else if (g.IO.KeyCtrl) // Hold to preview score in matching quadrant. Press C to rotate.
    {
        if (IsKeyPressedMap(ImGuiKey_C)) { g.NavMoveDirLast = (ImGuiDir)((g.NavMoveDirLast + 1) & 3); g.IO.KeysDownDuration[g.IO.KeyMap[ImGuiKey_C]] = 0.01f; }
        if (quadrant == g.NavMoveDir)
        {
            ImFormatString(buf, IM_ARRAYSIZE(buf), "%.0f/%.0f", dist_box, dist_center);
            ImDrawList* draw_list = GetForegroundDrawList(window);
            draw_list->AddRectFilled(cand.Min, cand.Max, IM_COL32(255, 0, 0, 200));
            draw_list->AddText(g.IO.FontDefault, 13.0f, cand.Min, IM_COL32(255, 255, 255, 255), buf);
        }
    }
#endif

    // Is it in the quadrant we're interesting in moving to?
    bool new_best = false;
    if (quadrant == g.NavMoveDir)
    {
        // Does it beat the current best candidate?
        if (dist_box < result->DistBox)
        {
            result->DistBox = dist_box;
            result->DistCenter = dist_center;
            return true;
        }
        if (dist_box == result->DistBox)
        {
            // Try using distance between center points to break ties
            if (dist_center < result->DistCenter)
            {
                result->DistCenter = dist_center;
                new_best = true;
            }
            else if (dist_center == result->DistCenter)
            {
                // Still tied! we need to be extra-careful to make sure everything gets linked properly. We consistently break ties by symbolically moving "later" items
                // (with higher index) to the right/downwards by an infinitesimal amount since we the current "best" button already (so it must have a lower index),
                // this is fairly easy. This rule ensures that all buttons with dx==dy==0 will end up being linked in order of appearance along the x axis.
                if (((g.NavMoveDir == ImGuiDir_Up || g.NavMoveDir == ImGuiDir_Down) ? dby : dbx) < 0.0f) // moving bj to the right/down decreases distance
                    new_best = true;
            }
        }
    }

    // Axial check: if 'curr' has no link at all in some direction and 'cand' lies roughly in that direction, add a tentative link. This will only be kept if no "real" matches
    // are found, so it only augments the graph produced by the above method using extra links. (important, since it doesn't guarantee strong connectedness)
    // This is just to avoid buttons having no links in a particular direction when there's a suitable neighbor. you get good graphs without this too.
    // 2017/09/29: FIXME: This now currently only enabled inside menu bars, ideally we'd disable it everywhere. Menus in particular need to catch failure. For general navigation it feels awkward.
    // Disabling it may lead to disconnected graphs when nodes are very spaced out on different axis. Perhaps consider offering this as an option?
    if (result->DistBox == FLT_MAX && dist_axial < result->DistAxial)  // Check axial match
        if (g.NavLayer == ImGuiNavLayer_Menu && !(g.NavWindow->Flags & ImGuiWindowFlags_ChildMenu))
            if ((g.NavMoveDir == ImGuiDir_Left && dax < 0.0f) || (g.NavMoveDir == ImGuiDir_Right && dax > 0.0f) || (g.NavMoveDir == ImGuiDir_Up && day < 0.0f) || (g.NavMoveDir == ImGuiDir_Down && day > 0.0f))
            {
                result->DistAxial = dist_axial;
                new_best = true;
            }

    return new_best;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movlpd %xmm0, -0x14(%rbp)
movlpd %xmm1, -0xc(%rbp)
movq %rdi, -0x20(%rbp)
movq 0x12d070(%rip), %rax    # 0x212f40
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movq 0x1ae0(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x28(%rbp), %rax
movl 0x1cdc(%rax), %eax
movq -0x30(%rbp), %rcx
cmpl 0x14c(%rcx), %eax
je 0xe5f02
movb $0x0, -0x1(%rbp)
jmp 0xe642e
movq -0x28(%rbp), %rax
addq $0x1cc8, %rax           # imm = 0x1CC8
movq %rax, -0x38(%rbp)
movq -0x28(%rbp), %rax
movl 0x1cd8(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x1cd8(%rax)
movq -0x30(%rbp), %rax
movq 0x388(%rax), %rax
movq -0x28(%rbp), %rcx
cmpq 0x1c90(%rcx), %rax
jne 0xe5fb0
movq -0x30(%rbp), %rax
movl 0xc(%rax), %eax
movq -0x28(%rbp), %rcx
movq 0x1c90(%rcx), %rcx
orl 0xc(%rcx), %eax
andl $0x800000, %eax         # imm = 0x800000
cmpl $0x0, %eax
je 0xe5f5c
jmp 0xe5f7b
leaq 0x915e4(%rip), %rdi     # 0x177547
leaq 0x8cf9f(%rip), %rsi     # 0x172f09
movl $0x20fb, %edx           # imm = 0x20FB
leaq 0x91616(%rip), %rcx     # 0x17758c
callq 0xd180
movq -0x30(%rbp), %rdi
addq $0x258, %rdi            # imm = 0x258
leaq -0x14(%rbp), %rsi
callq 0xe9420
testb $0x1, %al
jne 0xe5f9c
movb $0x0, -0x1(%rbp)
jmp 0xe642e
movq -0x30(%rbp), %rsi
addq $0x258, %rsi            # imm = 0x258
leaq -0x14(%rbp), %rdi
callq 0xeb8d0
movq -0x28(%rbp), %rax
movl 0x1d18(%rax), %edi
movq -0x30(%rbp), %rdx
addq $0x258, %rdx            # imm = 0x258
leaq -0x14(%rbp), %rsi
callq 0xe64a0
movss -0x14(%rbp), %xmm0
movss -0xc(%rbp), %xmm1
movq -0x38(%rbp), %rax
movss (%rax), %xmm2
movq -0x38(%rbp), %rax
movss 0x8(%rax), %xmm3
callq 0xe6570
movss %xmm0, -0x3c(%rbp)
movss -0x10(%rbp), %xmm0
movss -0x8(%rbp), %xmm1
movss 0x8bfcb(%rip), %xmm2    # 0x171fd0
callq 0xddb10
movss %xmm0, -0x68(%rbp)
movss -0x10(%rbp), %xmm0
movss -0x8(%rbp), %xmm1
movss 0x8c7a7(%rip), %xmm2    # 0x1727c8
callq 0xddb10
movss %xmm0, -0x70(%rbp)
movq -0x38(%rbp), %rax
movss 0x4(%rax), %xmm0
movq -0x38(%rbp), %rax
movss 0xc(%rax), %xmm1
movss 0x8bf8b(%rip), %xmm2    # 0x171fd0
callq 0xddb10
movss %xmm0, -0x6c(%rbp)
movq -0x38(%rbp), %rax
movss 0x4(%rax), %xmm0
movq -0x38(%rbp), %rax
movss 0xc(%rax), %xmm1
movss 0x8c75f(%rip), %xmm2    # 0x1727c8
callq 0xddb10
movss -0x70(%rbp), %xmm1
movss -0x6c(%rbp), %xmm2
movaps %xmm0, %xmm3
movss -0x68(%rbp), %xmm0
callq 0xe6570
movss %xmm0, -0x40(%rbp)
movss -0x40(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomiss %xmm1, %xmm0
jne 0xe609b
jp 0xe609b
jmp 0xe60ef
movss -0x3c(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomiss %xmm1, %xmm0
jne 0xe60ac
jp 0xe60ac
jmp 0xe60ef
movss -0x3c(%rbp), %xmm0
movss 0x8becb(%rip), %xmm1    # 0x171f84
divss %xmm1, %xmm0
movss -0x3c(%rbp), %xmm2
movss 0x8ab72(%rip), %xmm4    # 0x170c3c
movss 0x8beae(%rip), %xmm3    # 0x171f80
xorps %xmm1, %xmm1
cmpltss %xmm2, %xmm1
movaps %xmm1, %xmm2
andps %xmm4, %xmm2
andnps %xmm3, %xmm1
orps %xmm2, %xmm1
addss %xmm1, %xmm0
movss %xmm0, -0x3c(%rbp)
movss -0x3c(%rbp), %xmm0
movaps 0x8c705(%rip), %xmm1    # 0x172800
pand %xmm1, %xmm0
movss -0x40(%rbp), %xmm1
movaps 0x8c6f5(%rip), %xmm2    # 0x172800
pand %xmm2, %xmm1
addss %xmm1, %xmm0
movss %xmm0, -0x44(%rbp)
movss -0x14(%rbp), %xmm0
addss -0xc(%rbp), %xmm0
movq -0x38(%rbp), %rax
movss (%rax), %xmm1
movq -0x38(%rbp), %rax
addss 0x8(%rax), %xmm1
subss %xmm1, %xmm0
movss %xmm0, -0x48(%rbp)
movss -0x10(%rbp), %xmm0
addss -0x8(%rbp), %xmm0
movq -0x38(%rbp), %rax
movss 0x4(%rax), %xmm1
movq -0x38(%rbp), %rax
addss 0xc(%rax), %xmm1
subss %xmm1, %xmm0
movss %xmm0, -0x4c(%rbp)
movss -0x48(%rbp), %xmm0
movaps 0x8c693(%rip), %xmm1    # 0x172800
pand %xmm1, %xmm0
movss -0x4c(%rbp), %xmm1
movaps 0x8c683(%rip), %xmm2    # 0x172800
pand %xmm2, %xmm1
addss %xmm1, %xmm0
movss %xmm0, -0x50(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0x58(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0x5c(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0x60(%rbp)
movss -0x3c(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomiss %xmm1, %xmm0
jne 0xe61c2
jp 0xe61c2
movss -0x40(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomiss %xmm1, %xmm0
jne 0xe61c2
jp 0xe61c2
jmp 0xe61f4
movss -0x3c(%rbp), %xmm0
movss %xmm0, -0x58(%rbp)
movss -0x40(%rbp), %xmm0
movss %xmm0, -0x5c(%rbp)
movss -0x44(%rbp), %xmm0
movss %xmm0, -0x60(%rbp)
movss -0x3c(%rbp), %xmm0
movss -0x40(%rbp), %xmm1
callq 0xdf5c0
movl %eax, -0x54(%rbp)
jmp 0xe626b
movss -0x48(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomiss %xmm1, %xmm0
jne 0xe6214
jp 0xe6214
movss -0x4c(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomiss %xmm1, %xmm0
jne 0xe6214
jp 0xe6214
jmp 0xe6246
movss -0x48(%rbp), %xmm0
movss %xmm0, -0x58(%rbp)
movss -0x4c(%rbp), %xmm0
movss %xmm0, -0x5c(%rbp)
movss -0x50(%rbp), %xmm0
movss %xmm0, -0x60(%rbp)
movss -0x48(%rbp), %xmm0
movss -0x4c(%rbp), %xmm1
callq 0xdf5c0
movl %eax, -0x54(%rbp)
jmp 0xe6269
movq -0x30(%rbp), %rax
movl 0x124(%rax), %edx
movq -0x28(%rbp), %rax
movl 0x1c98(%rax), %esi
movl $0x1, %eax
xorl %ecx, %ecx
cmpl %esi, %edx
cmovbl %ecx, %eax
movl %eax, -0x54(%rbp)
jmp 0xe626b
movb $0x0, -0x61(%rbp)
movl -0x54(%rbp), %eax
movq -0x28(%rbp), %rcx
cmpl 0x1d10(%rcx), %eax
jne 0xe6350
movss -0x44(%rbp), %xmm1
movq -0x20(%rbp), %rax
movss 0x10(%rax), %xmm0
ucomiss %xmm1, %xmm0
jbe 0xe62ba
movss -0x44(%rbp), %xmm0
movq -0x20(%rbp), %rax
movss %xmm0, 0x10(%rax)
movss -0x50(%rbp), %xmm0
movq -0x20(%rbp), %rax
movss %xmm0, 0x14(%rax)
movb $0x1, -0x1(%rbp)
jmp 0xe642e
movss -0x44(%rbp), %xmm0
movq -0x20(%rbp), %rax
ucomiss 0x10(%rax), %xmm0
jne 0xe634e
jp 0xe634e
movss -0x50(%rbp), %xmm1
movq -0x20(%rbp), %rax
movss 0x14(%rax), %xmm0
ucomiss %xmm1, %xmm0
jbe 0xe62f6
movss -0x50(%rbp), %xmm0
movq -0x20(%rbp), %rax
movss %xmm0, 0x14(%rax)
movb $0x1, -0x61(%rbp)
jmp 0xe634c
movss -0x50(%rbp), %xmm0
movq -0x20(%rbp), %rax
ucomiss 0x14(%rax), %xmm0
jne 0xe634a
jp 0xe634a
movq -0x28(%rbp), %rax
cmpl $0x2, 0x1d10(%rax)
je 0xe6321
movq -0x28(%rbp), %rax
cmpl $0x3, 0x1d10(%rax)
jne 0xe632d
movss -0x40(%rbp), %xmm0
movss %xmm0, -0x74(%rbp)
jmp 0xe6337
movss -0x3c(%rbp), %xmm0
movss %xmm0, -0x74(%rbp)
movss -0x74(%rbp), %xmm1
xorps %xmm0, %xmm0
ucomiss %xmm1, %xmm0
jbe 0xe6348
movb $0x1, -0x61(%rbp)
jmp 0xe634a
jmp 0xe634c
jmp 0xe634e
jmp 0xe6350
movq -0x20(%rbp), %rax
movss 0x10(%rax), %xmm0
movss 0x8bc53(%rip), %xmm1    # 0x171fb4
ucomiss %xmm1, %xmm0
jne 0xe6426
jp 0xe6426
movss -0x60(%rbp), %xmm1
movq -0x20(%rbp), %rax
movss 0x18(%rax), %xmm0
ucomiss %xmm1, %xmm0
jbe 0xe6426
movq -0x28(%rbp), %rax
cmpl $0x1, 0x1cdc(%rax)
jne 0xe6424
movq -0x28(%rbp), %rax
movq 0x1c90(%rax), %rax
movl 0xc(%rax), %eax
andl $0x10000000, %eax       # imm = 0x10000000
cmpl $0x0, %eax
jne 0xe6424
movq -0x28(%rbp), %rax
cmpl $0x0, 0x1d10(%rax)
jne 0xe63c6
xorps %xmm0, %xmm0
ucomiss -0x58(%rbp), %xmm0
ja 0xe6410
movq -0x28(%rbp), %rax
cmpl $0x1, 0x1d10(%rax)
jne 0xe63e0
movss -0x58(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomiss %xmm1, %xmm0
ja 0xe6410
movq -0x28(%rbp), %rax
cmpl $0x2, 0x1d10(%rax)
jne 0xe63f6
xorps %xmm0, %xmm0
ucomiss -0x5c(%rbp), %xmm0
ja 0xe6410
movq -0x28(%rbp), %rax
cmpl $0x3, 0x1d10(%rax)
jne 0xe6422
movss -0x5c(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomiss %xmm1, %xmm0
jbe 0xe6422
movss -0x60(%rbp), %xmm0
movq -0x20(%rbp), %rax
movss %xmm0, 0x18(%rax)
movb $0x1, -0x61(%rbp)
jmp 0xe6424
jmp 0xe6426
movb -0x61(%rbp), %al
andb $0x1, %al
movb %al, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x80, %rsp
popq %rbp
retq
nopl (%rax)