// File: /workspace/github_c_makefile_star2_O2/enzo1982[P]smooth/classes/gui/widgets/multi/menu/menubar.cpp
// Function: smooth::GUI::Menubar::Paint(int)
S::Int S::GUI::Menubar::Paint(Int message)
{
	if (!IsRegistered()) return Error();
	if (!IsVisible())    return Success();

#ifdef __APPLE__
	if (orientation == OR_FREE)
	{
		if (menubarCocoa != NIL) menubarCocoa->Paint(message);

		return Success();
	}
#endif

	Window		*window	   = GetContainerWindow();
	Surface		*surface   = GetDrawSurface();
	Rect		 menubar   = Rect(GetRealPosition(), GetRealSize() - Size(1, 1));

#ifdef __WIN32__
	static Bool	 flatStyle = Backends::BackendWin32::IsWindowsVersionAtLeast(VER_PLATFORM_WIN32_NT, 6, 2);
#else
	static Bool	 flatStyle = True;
#endif

	if (orientation == OR_TOP || orientation == OR_BOTTOM)
	{
#ifdef __APPLE__
		Int	 leftWidth	= 0;
		Int	 rightWidth	= 0;

		for (Int i = 0; i < Length(); i++)
		{
			MenuEntry	*entry = GetNthEntry(i);

			if	(entry->GetOrientation() == OR_TOP    || entry->GetOrientation() == OR_LEFT)  leftWidth	 += entry->GetWidth() + 2;
			else if (entry->GetOrientation() == OR_BOTTOM || entry->GetOrientation() == OR_RIGHT) rightWidth += entry->GetWidth() + 2;
		}

		Int	 nextXPosLeft	= (GetSize().cx - leftWidth - rightWidth + 2) / 2;
		Int	 nextXPosRight	= nextXPosLeft + leftWidth + rightWidth - 2;
#else
		Int	 nextXPosLeft	= 7 + (window->GetIcon() != NIL ? 17 : 0);
		Int	 nextXPosRight	= GetSize().cx - 1;

		if (flatStyle) nextXPosLeft = 1;
#endif
		Int	 highestEntry	= 0;

		for (Int i = 0; i < Length(); i++)
		{
			MenuEntry	*entry = GetNthEntry(i);

			if (entry->GetOrientation() == OR_TOP) entry->SetOrientation(OR_LEFT);

			if (entry->GetOrientation() == OR_LEFT)
			{
				entry->SetPosition(Point(nextXPosLeft, 2));

				nextXPosLeft += entry->GetWidth() + 2;

				if (highestEntry < entry->GetHeight()) highestEntry = entry->GetHeight();
			}
		}

		for (Int i = Length() - 1; i >= 0; i--)
		{
			MenuEntry	*entry = GetNthEntry(i);

			if (entry->GetOrientation() == OR_BOTTOM) entry->SetOrientation(OR_RIGHT);

			if (entry->GetOrientation() == OR_RIGHT)
			{
				entry->SetPosition(Point(nextXPosRight - entry->GetWidth(), 2));

				nextXPosRight -= entry->GetWidth() + 2;

				if (highestEntry < entry->GetHeight()) highestEntry = entry->GetHeight();
			}
		}

		SetHeight(highestEntry + 2);

		for (Int i = 0; i < Length(); i++)
		{
			MenuEntry	*entry = GetNthEntry(i);

			if (entry->GetText() == NIL && entry->GetBitmap() == NIL) entry->SetHeight(GetHeight() - 3);
		}
	}
	else if (orientation == OR_LEFT || orientation == OR_RIGHT)
	{
		Int	 nextYPos	= 1;
		Int	 widestEntry	= 0;

		for (Int i = 0; i < Length(); i++)
		{
			MenuEntry	*entry = GetNthEntry(i);

			if (entry->GetOrientation() == OR_LEFT) entry->SetOrientation(OR_TOP);

			if (entry->GetOrientation() == OR_TOP)
			{
				entry->SetPosition(Point(1, nextYPos));

				nextYPos += entry->GetHeight() + 2;

				if (widestEntry < entry->GetWidth()) widestEntry = entry->GetWidth();
			}
		}

		for (Int i = 0; i < Length(); i++)
		{
			MenuEntry	*entry = GetNthEntry(i);

			if (entry->GetOrientation() == OR_RIGHT) entry->SetOrientation(OR_BOTTOM);

			if (entry->GetOrientation() == OR_BOTTOM)
			{
				entry->SetPosition(Point(1, nextYPos));

				nextYPos += entry->GetHeight() + 2;

				if (widestEntry < entry->GetWidth()) widestEntry = entry->GetWidth();
			}
		}

		SetWidth(widestEntry + 3);

		for (Int i = 0; i < Length(); i++)
		{
			MenuEntry	*entry = GetNthEntry(i);

			if (entry->GetText() == NIL && entry->GetBitmap() == NIL) entry->SetWidth(GetWidth() - 3);
		}
	}

	/* Draw handles of non-flat style menubars.
	 */
	switch (message)
	{
		case SP_PAINT:
			if (flatStyle) break;

			if (orientation == OR_TOP || orientation == OR_BOTTOM)
			{
				if (orientation == OR_BOTTOM) { menubar.top--; menubar.bottom--; }

				Point	 p1 = Point(menubar.left + 1, menubar.top + 2);
				Point	 p2 = Point(p1.x, menubar.bottom);

				if (window->GetIcon() != NIL && orientation == OR_TOP)
				{
					p1.x += Math::Round(18 * surface->GetSurfaceDPI() / 96.0) - 1;
					p2.x += Math::Round(18 * surface->GetSurfaceDPI() / 96.0) - 1;
				}

				surface->Bar(p1, p2, OR_VERT);

				p1.x += 2;
				p2.x += 2;

				surface->Bar(p1, p2, OR_VERT);
			}

			break;
	}

	return Widget::Paint(message);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movl %esi, %r15d
movq %rdi, %r14
movq (%rdi), %rax
callq *0x88(%rax)
testb %al, %al
je 0x85ea5
movq (%r14), %rax
movq %r14, %rdi
callq *0x90(%rax)
movl %eax, %ecx
xorl %eax, %eax
testb %cl, %cl
je 0x861e8
movq %r14, %rdi
callq 0x56a50
movq %rax, %rbx
movq (%r14), %rax
movq %r14, %rdi
callq *0x40(%rax)
movq (%r14), %rax
movq %r14, %rdi
callq *0x48(%rax)
movq (%r14), %rax
movq %r14, %rdi
callq *0x50(%rax)
movl 0xd0(%r14), %eax
addl $-0x4, %eax
rolw $0xe, %ax
cmpw $0x2, %ax
jb 0x85fce
movzwl %ax, %eax
cmpl $0x3, %eax
je 0x85df4
cmpl $0x7, %eax
jne 0x861dd
movl %r15d, 0xc(%rsp)
xorl %ebp, %ebp
pushq $0x1
popq %r12
leaq 0x4(%rsp), %r15
xorl %r13d, %r13d
movq (%r14), %rax
movq %r14, %rdi
callq *0x178(%rax)
cmpl %eax, %r13d
jge 0x85ead
movq (%r14), %rax
movq %r14, %rdi
movl %r13d, %esi
callq *0x180(%rax)
movq %rax, %rbx
movq (%rax), %rax
movq %rbx, %rdi
callq *0x128(%rax)
cmpl $0x10, %eax
jne 0x85e4e
movq (%rbx), %rax
movq %rbx, %rdi
pushq $0x4
popq %rsi
callq *0x120(%rax)
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x128(%rax)
cmpl $0x4, %eax
jne 0x85e9d
movl $0x1, 0x4(%rsp)
movl %r12d, 0x8(%rsp)
movq %rbx, %rdx
addq $0xb0, %rdx
movq (%rbx), %rax
movq %rbx, %rdi
movq %r15, %rsi
callq *0x150(%rax)
movl 0xb0(%rbx), %eax
movl 0xb4(%rbx), %ecx
addl %ecx, %r12d
addl $0x2, %r12d
cmpl %eax, %ebp
cmovlel %eax, %ebp
incl %r13d
jmp 0x85e07
pushq $-0x1
popq %rax
jmp 0x861e8
xorl %r15d, %r15d
leaq 0x4(%rsp), %r13
movq (%r14), %rax
movq %r14, %rdi
callq *0x178(%rax)
cmpl %eax, %r15d
jge 0x85f53
movq (%r14), %rax
movq %r14, %rdi
movl %r15d, %esi
callq *0x180(%rax)
movq %rax, %rbx
movq (%rax), %rax
movq %rbx, %rdi
callq *0x128(%rax)
cmpl $0x20, %eax
jne 0x85efc
movq (%rbx), %rax
movq %rbx, %rdi
pushq $0x8
popq %rsi
callq *0x120(%rax)
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x128(%rax)
cmpl $0x8, %eax
jne 0x85f4b
movl $0x1, 0x4(%rsp)
movl %r12d, 0x8(%rsp)
movq %rbx, %rdx
addq $0xb0, %rdx
movq (%rbx), %rax
movq %rbx, %rdi
movq %r13, %rsi
callq *0x150(%rax)
movl 0xb0(%rbx), %eax
movl 0xb4(%rbx), %ecx
addl %ecx, %r12d
addl $0x2, %r12d
cmpl %eax, %ebp
cmovlel %eax, %ebp
incl %r15d
jmp 0x85eb5
addl $0x3, %ebp
movq %r14, %rdi
movl %ebp, %esi
callq 0x5a1f0
xorl %ebp, %ebp
movl 0xc(%rsp), %r15d
movq (%r14), %rax
movq %r14, %rdi
callq *0x178(%rax)
cmpl %eax, %ebp
jge 0x861dd
movq (%r14), %rax
movq %r14, %rdi
movl %ebp, %esi
callq *0x180(%rax)
movq %rax, %rbx
movq (%rax), %rax
movq %rbx, %rdi
callq *0xa8(%rax)
movq %rax, %rdi
xorl %esi, %esi
callq 0x56280
testb %al, %al
je 0x85fca
leaq 0x5c0(%rbx), %rdi
xorl %esi, %esi
callq 0x590c0
testb %al, %al
je 0x85fca
movl 0xb0(%r14), %esi
addl $-0x3, %esi
movq %rbx, %rdi
callq 0x5a1f0
incl %ebp
jmp 0x85f67
movl %r15d, 0xc(%rsp)
addq $0x5d0, %rbx            # imm = 0x5D0
xorl %r15d, %r15d
movq %rbx, %rdi
xorl %esi, %esi
callq 0x574f0
movl 0xb0(%r14), %eax
movq %rax, 0x10(%rsp)
pushq $0x1
popq %r12
leaq 0x4(%rsp), %r13
xorl %ebp, %ebp
movq (%r14), %rax
movq %r14, %rdi
callq *0x178(%rax)
cmpl %eax, %r15d
jge 0x8609c
movq (%r14), %rax
movq %r14, %rdi
movl %r15d, %esi
callq *0x180(%rax)
movq %rax, %rbx
movq (%rax), %rax
movq %rbx, %rdi
callq *0x128(%rax)
cmpl $0x4, %eax
jne 0x86045
movq (%rbx), %rax
movq %rbx, %rdi
pushq $0x10
popq %rsi
callq *0x120(%rax)
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x128(%rax)
cmpl $0x10, %eax
jne 0x86094
movl %r12d, 0x4(%rsp)
movl $0x2, 0x8(%rsp)
movq %rbx, %rdx
addq $0xb0, %rdx
movq (%rbx), %rax
movq %rbx, %rdi
movq %r13, %rsi
callq *0x150(%rax)
movl 0xb0(%rbx), %eax
movl 0xb4(%rbx), %ecx
addl %eax, %r12d
addl $0x2, %r12d
cmpl %ecx, %ebp
cmovlel %ecx, %ebp
incl %r15d
jmp 0x85ffe
movq 0x10(%rsp), %rax
decl %eax
movq %rax, 0x10(%rsp)
movq (%r14), %rax
movq %r14, %rdi
callq *0x178(%rax)
movl %eax, %r15d
pushq $0x20
popq %r12
testl %r15d, %r15d
jle 0x86166
decl %r15d
movq (%r14), %rax
movq %r14, %rdi
movl %r15d, %esi
callq *0x180(%rax)
movq %rax, %r13
movq (%rax), %rax
movq %r13, %rdi
callq *0x128(%rax)
cmpl $0x8, %eax
jne 0x860fa
movq (%r13), %rax
movq %r13, %rdi
movl %r12d, %esi
callq *0x120(%rax)
movq (%r13), %rax
movq %r13, %rdi
callq *0x128(%rax)
cmpl $0x20, %eax
jne 0x860bb
movq %r13, %rdx
movq 0x10(%rsp), %rbx
movl %ebx, %eax
subl 0xb0(%r13), %eax
addq $0xb0, %rdx
movl %eax, 0x4(%rsp)
movl $0x2, 0x8(%rsp)
movq (%r13), %rax
movq %r13, %rdi
leaq 0x4(%rsp), %rsi
callq *0x150(%rax)
movl 0xb0(%r13), %eax
movl 0xb4(%r13), %ecx
negl %eax
addl %eax, %ebx
addl $-0x2, %ebx
movq %rbx, 0x10(%rsp)
cmpl %ecx, %ebp
cmovlel %ecx, %ebp
jmp 0x860bb
addl $0x2, %ebp
movq %r14, %rdi
movl %ebp, %esi
callq 0x58980
xorl %ebp, %ebp
movl 0xc(%rsp), %r15d
movq (%r14), %rax
movq %r14, %rdi
callq *0x178(%rax)
cmpl %eax, %ebp
jge 0x861dd
movq (%r14), %rax
movq %r14, %rdi
movl %ebp, %esi
callq *0x180(%rax)
movq %rax, %rbx
movq (%rax), %rax
movq %rbx, %rdi
callq *0xa8(%rax)
movq %rax, %rdi
xorl %esi, %esi
callq 0x56280
testb %al, %al
je 0x861d9
leaq 0x5c0(%rbx), %rdi
xorl %esi, %esi
callq 0x590c0
testb %al, %al
je 0x861d9
movl 0xb4(%r14), %esi
addl $-0x3, %esi
movq %rbx, %rdi
callq 0x58980
incl %ebp
jmp 0x8617a
movq %r14, %rdi
movl %r15d, %esi
callq 0x57910
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop