// File: /workspace/github_c_makefile_star2_O2/sTeeLM[P]dwipe/gui.c
// Function: dwipe_gui_select
void dwipe_gui_select( int count, dwipe_context_t* c )
{
/**
 * The primary user interface.  Allows the user to
 * change options and specify the devices to be wiped.
 *
 * @parameter  count       The number of contexts in the array.
 * @parameter  c           An array of device contexts.
 *
 * @modifies   c[].select  Sets the select flag according to user input.
 * @modifies   options     Sets program options according to to user input.
 *
 */

	/* Widget labels. */
	const char* select_title = " Disks and Partitions ";

	/* The number of lines available in the window. */
	int wlines;

	/* The number of columns available in the window. */
	int wcols;

	/* The number of selection elements that we can show in the window. */
	int slots;

	/* The index of the element that is visible in the first slot. */
	int offset = 0;

	/* The selection focus. */
	int focus = 0;

	/* A generic loop variable. */
	int i;

	/* User input buffer. */
	int keystroke;

	/* The current working line. */
	int yy;

	/* The number of currently selected elements. */
	int selected = 0;

	/* There is one slot per line. */
	getmaxyx( main_window, wlines, wcols );

	/* Less two lines for the box and two lines for padding. */
	slots = wlines - 4;



	do
	{
		/* Clear the main window. */
		werase( main_window );

		/* Update the footer window. */
		werase( footer_window );
		dwipe_gui_title( footer_window, dwipe_buttons1 );
		wrefresh( footer_window );

		/* Update the options window. */
		dwipe_gui_options();

		/* Initialize the line offset. */
		yy = 2;

		for( i = 0; i < slots && i < count ; i++ )
		{
			/* Move to the next line. */
			mvwprintw( main_window, yy++, 1, " " );

			if( i + offset == focus )
			{
				if( c[focus].select == DWIPE_SELECT_TRUE || c[focus].select == DWIPE_SELECT_FALSE )
				{
					/* Print the 'enabled' cursor. */
					waddch( main_window, ACS_RARROW );
				}

				else
				{
					/* Print the 'disabled' cursor. */
					waddch( main_window, ACS_DIAMOND );
				}
			}

			else
			{
				/* Print whitespace. */
				waddch( main_window, ' '  );
			}


			switch( c[i+offset].select )
			{
				case DWIPE_SELECT_TRUE:

					/* Print a selected element. */
					wprintw( main_window, " [   WIPE  ] %s", c[i+offset].label );
					break;

				case DWIPE_SELECT_FALSE:

					/* Print an element that is not selected. */
					wprintw( main_window, " [         ] %s", c[i+offset].label );
					break;

				case DWIPE_SELECT_TRUE_PARENT:

					/* This element will be wiped when its parent is wiped. */
					wprintw( main_window, " [*********] %s", c[i+offset].label );
					break;

				case DWIPE_SELECT_FALSE_CHILD:

					/* We can't wipe this element because it has a child that is being wiped. */
					wprintw( main_window, " [---------] %s", c[i+offset].label );
					break;

				case DWIPE_SELECT_DISABLED:

					/* We don't know how to wipe this device. (Iomega Zip drives.) */
					wprintw( main_window, " [ DISABLE ] %s", c[i+offset].label == NULL ? "Unrecognized Device" : c[i+offset].label);
					break;
				case DWIPE_SELECT_SKIPPED:
                                        wprintw( main_window, " [ SKIPPED ] %s", c[i+offset].label == NULL ? "Unrecognized Device" : c[i+offset].label);
                                        break;
				default:
					
					/* TODO: Handle the sanity error. */
					break;


			} /* switch select */

		} /* for */

		if( offset > 0 )
		{
			mvwprintw( main_window, 1, wcols -8, " More " );
			waddch( main_window, ACS_UARROW );
		}

		if( count - offset > slots )
		{
			mvwprintw( main_window, wlines -2, wcols -8, " More " );
			waddch( main_window, ACS_DARROW );
		}

		/* Draw a border around the menu window. */
		box( main_window, 0, 0 );

		/* Print a title. */
		dwipe_gui_title( main_window, select_title );

		/* Refresh the window. */
		wrefresh( main_window );

		/* Get user input. */
		keystroke = getch();

		switch( keystroke )
		{
			case KEY_DOWN:
			case 'j':
			case 'J':

				/* Increment the focus. */
				focus += 1;

				if( focus >= count )
				{
					/* The focus is already at the last element. */
					focus = count -1;
					break;
				}

				if( focus - offset >= slots )
				{
					/* The next element is offscreen. Scroll down. */
					offset += 1;
					break;
				}

				break;

			case KEY_UP:
			case 'k':
			case 'K':

				/* Decrement the focus. */
				focus -= 1;

				if( focus < 0 )
				{
					/* The focus is already at the last element. */
					focus = 0;
					break;
				}

				if( focus < offset )
				{
					/* The next element is offscreen. Scroll up. */
					offset -= 1;
					break;
				}

				break;

			case KEY_ENTER:
			case 10:
			case ' ':

				/* TODO: This block should be made into a function. */

				if( c[focus].select == DWIPE_SELECT_TRUE )
				{
					/* Reverse the selection of this element. */
					c[focus].select = DWIPE_SELECT_FALSE;

					if( c[focus].device_part == 0 )
					{
						/* Sub-deselect all partitions and slices within this disk. */
						for( i = 0 ; i < count ; i++ )
						{
							if
							(
								   c[i].device_type   == c[focus].device_type
								&& c[i].device_host   == c[focus].device_host
								&& c[i].device_bus    == c[focus].device_bus
								&& c[i].device_target == c[focus].device_target
								&& c[i].device_lun    == c[focus].device_lun
								&& c[i].device_part   > 0
							)
							{
                                if(c[i].select != DWIPE_SELECT_SKIPPED)
								    c[i].select = DWIPE_SELECT_FALSE;
							}

						} /* for all contexts */

					} /* if sub-deselect */

					else
					{
						/* The number of selected partitions or slices within this disk. */
						int j = 0;

						for( i = 0 ; i < count ; i++ )
						{
							if
							(
								   c[i].device_type   == c[focus].device_type
								&& c[i].device_host   == c[focus].device_host
								&& c[i].device_bus    == c[focus].device_bus
								&& c[i].device_target == c[focus].device_target
								&& c[i].device_lun    == c[focus].device_lun
								&& c[i].device_part   > 0
								&& c[i].select        == DWIPE_SELECT_TRUE
							)
							{
								/* Increment the counter. */
								j += 1;
							}

						} /* for all contexts */

						if( j == 0 )
						{
							/* Find the parent disk of this partition or slice. */
							for( i = 0 ; i < count ; i++ )
							{
								if
								(
									   c[i].device_type   == c[focus].device_type
									&& c[i].device_host   == c[focus].device_host
									&& c[i].device_bus    == c[focus].device_bus
									&& c[i].device_target == c[focus].device_target
									&& c[i].device_lun    == c[focus].device_lun
									&& c[i].device_part   == 0
								)
								{
									/* Enable the disk element. */
                                    if(c[i].select != DWIPE_SELECT_SKIPPED)
									    c[i].select = DWIPE_SELECT_FALSE;
								}

							} /* for all contexts */

						} /* if */

					} /* else super-enable */

					break;

				} /* if DWIPE_SELECT_TRUE */

				if( c[focus].select == DWIPE_SELECT_FALSE )
				{
					/* Reverse the selection. */
					c[focus].select = DWIPE_SELECT_TRUE;

					if( c[focus].device_part == 0 )
					{
						/* Sub-select all partitions and slices within this disk. */
						for( i = 0 ; i < count ; i++ )
						{
							if
							(
								   c[i].device_type   == c[focus].device_type
								&& c[i].device_host   == c[focus].device_host
								&& c[i].device_bus    == c[focus].device_bus
								&& c[i].device_target == c[focus].device_target
								&& c[i].device_lun    == c[focus].device_lun
								&& c[i].device_part   > 0
							)
							{
                                if(c[i].select != DWIPE_SELECT_SKIPPED)
								    c[i].select = DWIPE_SELECT_TRUE_PARENT;
							}

						} /* for */

					} /* if sub-select */

					else
					{
						/* ASSERT: ( c[focus].device_part > 0 ) */

						/* Super-deselect the disk that contains this device. */
						for( i = 0 ; i < count ; i++ )
						{
							if
							(
								   c[i].device_type   == c[focus].device_type
								&& c[i].device_host   == c[focus].device_host
								&& c[i].device_bus    == c[focus].device_bus
								&& c[i].device_target == c[focus].device_target
								&& c[i].device_lun    == c[focus].device_lun
								&& c[i].device_part   == 0
							)
							{
                                if(c[i].select != DWIPE_SELECT_SKIPPED)
								    c[i].select = DWIPE_SELECT_FALSE_CHILD;
							}
						}

					} /* else super-deselect */

					break;

				} /* if DWIPE_SELECT_FALSE */

				/* TODO: Explain to the user why they can't change this. */
				break;

			case 'm':
			case 'M':
			
				/*  Run the method dialog. */
				dwipe_gui_method();
				break;

			case 'p':
			case 'P':

				/* Run the PRNG dialog. */
				dwipe_gui_prng();
				break;

			case 'r':
			case 'R':

				/* Run the rounds dialog. */
				dwipe_gui_rounds();
				break;

			case 'v':
			case 'V':

				/* Run the option dialog. */
				dwipe_gui_verify();
				break;

		} /* keystroke switch */

		selected = 0;
		for( i = 0 ; i < count ; i++ )
		{
			if( c[i].select == DWIPE_SELECT_TRUE )
			{
				selected += 1;
			};
		}

	} while( keystroke != KEY_F(10) || selected == 0 );

	/* Clear the main window. */
	werase( main_window );

	/* Refresh the main window. */
	wrefresh( main_window );

	/* Clear the footer. */
	werase( footer_window );

	/* Refresh the footer window. */
	wrefresh( footer_window );

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rsi, %rbx
movq %rdi, 0x8(%rsp)
movq 0xba3b(%rip), %rax      # 0x10828
testq %rax, %rax
je 0x4e04
movswl 0x4(%rax), %ecx
incl %ecx
movswl 0x6(%rax), %eax
addl $-0x7, %eax
movl %eax, (%rsp)
jmp 0x4e0d
pushq $-0x9
popq %rax
movl %eax, (%rsp)
pushq $-0x1
popq %rcx
leal -0x4(%rcx), %esi
movq 0x8(%rsp), %rdx
cmpl %edx, %esi
movl %edx, %eax
movl %esi, 0x4(%rsp)
cmovll %esi, %eax
addl $-0x2, %ecx
movq %rcx, 0x18(%rsp)
xorl %ecx, %ecx
testl %eax, %eax
cmovlel %ecx, %eax
testl %edx, %edx
movl $0x0, %ecx
cmovgl %edx, %ecx
decl %edx
movl %edx, 0x10(%rsp)
imulq $0x590, %rax, %rax      # imm = 0x590
movq %rax, 0x40(%rsp)
leaq 0x2e0(%rbx), %rax
movq %rax, 0x28(%rsp)
imulq $0x590, %rcx, %r14      # imm = 0x590
xorl %r12d, %r12d
xorl %r15d, %r15d
movq %r14, 0x20(%rsp)
movq 0xb9b8(%rip), %rdi      # 0x10828
callq 0x3050
movq 0xb994(%rip), %rdi      # 0x10810
callq 0x3050
movq 0xb988(%rip), %rdi      # 0x10810
movq 0xb7d1(%rip), %rsi      # 0x10660
callq 0x4974
movq 0xb975(%rip), %rdi      # 0x10810
callq 0x31b0
callq 0x54db
movq %r12, 0x38(%rsp)
movslq %r12d, %rax
imulq $0x590, %rax, %rcx      # imm = 0x590
movq %rcx, 0x30(%rsp)
leaq (%rbx,%rcx), %r13
addq $0x368, %r13            # imm = 0x368
movl %r15d, 0x14(%rsp)
movslq %r15d, %r12
imulq $0x590, %r12, %r14      # imm = 0x590
addq 0x28(%rsp), %r14
subl %eax, %r12d
xorl %r15d, %r15d
pushq $0x2
popq %rax
movl %eax, %ebp
cmpq %r15, 0x40(%rsp)
je 0x5022
movq 0xb933(%rip), %rdi      # 0x10828
movl %ebp, %esi
pushq $0x1
popq %rdx
leaq 0x6aec(%rip), %rcx      # 0xb9ed
xorl %eax, %eax
callq 0x31c0
leal (%r12,%rbp), %eax
cmpl $0x2, %eax
jne 0x4f33
movl (%r13), %eax
orl $0x2, %eax
cmpl $0x3, %eax
jne 0x4f3f
movq 0xb904(%rip), %rdi      # 0x10828
movq 0xb06d(%rip), %rax      # 0xff98
movl 0xac(%rax), %esi
jmp 0x4f53
movq 0xb8ee(%rip), %rdi      # 0x10828
pushq $0x20
popq %rsi
jmp 0x4f53
movq 0xb8e2(%rip), %rdi      # 0x10828
movq 0xb04b(%rip), %rax      # 0xff98
movl 0x180(%rax), %esi
callq 0x33f0
movl 0x88(%r14,%r15), %eax
decl %eax
cmpl $0x5, %eax
ja 0x5014
leaq 0x6026(%rip), %rcx      # 0xaf98
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0xb8a6(%rip), %rdi      # 0x10828
movq (%r14,%r15), %rdx
leaq 0x621c(%rip), %rsi      # 0xb1a9
jmp 0x500d
movq 0xb892(%rip), %rdi      # 0x10828
movq (%r14,%r15), %rdx
testq %rdx, %rdx
leaq 0x6255(%rip), %rax      # 0xb1f9
cmoveq %rax, %rdx
leaq 0x623a(%rip), %rsi      # 0xb1e9
jmp 0x500d
movq 0xb870(%rip), %rdi      # 0x10828
movq (%r14,%r15), %rdx
leaq 0x61f6(%rip), %rsi      # 0xb1b9
jmp 0x500d
movq 0xb85c(%rip), %rdi      # 0x10828
movq (%r14,%r15), %rdx
leaq 0x6202(%rip), %rsi      # 0xb1d9
jmp 0x500d
movq 0xb848(%rip), %rdi      # 0x10828
movq (%r14,%r15), %rdx
leaq 0x61de(%rip), %rsi      # 0xb1c9
jmp 0x500d
movq 0xb834(%rip), %rdi      # 0x10828
movq (%r14,%r15), %rdx
testq %rdx, %rdx
leaq 0x61f7(%rip), %rax      # 0xb1f9
cmoveq %rax, %rdx
leaq 0x6200(%rip), %rsi      # 0xb20d
xorl %eax, %eax
callq 0x3440
addq $0x590, %r15            # imm = 0x590
incl %ebp
jmp 0x4ee3
movl 0x14(%rsp), %r15d
testl %r15d, %r15d
jle 0x5060
movq 0xb7f5(%rip), %rdi      # 0x10828
pushq $0x1
popq %rsi
movl (%rsp), %edx
leaq 0x61dd(%rip), %rcx      # 0xb21d
xorl %eax, %eax
callq 0x31c0
movq 0xb7da(%rip), %rdi      # 0x10828
movq 0xaf43(%rip), %rax      # 0xff98
movl 0xb4(%rax), %esi
callq 0x33f0
movq 0x8(%rsp), %rax
subl %r15d, %eax
cmpl 0x4(%rsp), %eax
movq 0x20(%rsp), %r14
movq 0x38(%rsp), %r12
jle 0x50ae
movq 0xb7a9(%rip), %rdi      # 0x10828
movq 0x18(%rsp), %rsi
movl (%rsp), %edx
leaq 0x618f(%rip), %rcx      # 0xb21d
xorl %eax, %eax
callq 0x31c0
movq 0xb78c(%rip), %rdi      # 0x10828
movq 0xaef5(%rip), %rax      # 0xff98
movl 0xb8(%rax), %esi
callq 0x33f0
movq 0xb773(%rip), %rdi      # 0x10828
subq $0x8, %rsp
xorl %esi, %esi
xorl %edx, %edx
xorl %ecx, %ecx
xorl %r8d, %r8d
xorl %r9d, %r9d
pushq $0x0
pushq $0x0
pushq $0x0
callq 0x3100
addq $0x20, %rsp
movq 0xb74d(%rip), %rdi      # 0x10828
leaq 0x60b0(%rip), %rsi      # 0xb192
callq 0x4974
movq 0xb73a(%rip), %rdi      # 0x10828
callq 0x31b0
movq 0xaea6(%rip), %rax      # 0xffa0
movq (%rax), %rdi
callq 0x3120
movl %eax, %ebp
leal -0x4a(%rbp), %eax
cmpl $0xc, %eax
jbe 0x5124
leal -0x6a(%rbp), %eax
cmpl $0xc, %eax
ja 0x513e
leaq 0x5ec9(%rip), %rcx      # 0xafe4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq 0x5e85(%rip), %rcx      # 0xafb0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
callq 0x563a
jmp 0x5311
cmpl $0xa, %ebp
je 0x516c
cmpl $0x20, %ebp
je 0x516c
cmpl $0x102, %ebp            # imm = 0x102
je 0x5217
cmpl $0x103, %ebp            # imm = 0x103
je 0x5238
cmpl $0x157, %ebp            # imm = 0x157
jne 0x5311
movq 0x30(%rsp), %rcx
leaq (%rbx,%rcx), %rax
movl 0x368(%rbx,%rcx), %ecx
cmpl $0x1, %ecx
je 0x5287
cmpl $0x3, %ecx
jne 0x5311
movl $0x1, 0x368(%rax)
cmpl $0x0, 0x220(%rax)
je 0x534b
xorl %ecx, %ecx
cmpq %rcx, %r14
je 0x5311
movl 0x2c8(%rbx,%rcx), %edx
cmpl 0x2c8(%rax), %edx
jne 0x520e
movl 0xc(%rbx,%rcx), %edx
cmpl 0xc(%rax), %edx
jne 0x520e
movl 0x4(%rbx,%rcx), %edx
cmpl 0x4(%rax), %edx
jne 0x520e
movl 0x210(%rbx,%rcx), %edx
cmpl 0x210(%rax), %edx
jne 0x520e
movl 0x214(%rbx,%rcx), %edx
cmpl 0x214(%rax), %edx
jne 0x520e
cmpl $0x0, 0x220(%rbx,%rcx)
jne 0x520e
cmpl $0x6, 0x368(%rbx,%rcx)
je 0x520e
movl $0x4, 0x368(%rbx,%rcx)
addq $0x590, %rcx            # imm = 0x590
jmp 0x51a7
incl %r12d
cmpl 0x8(%rsp), %r12d
jge 0x5273
movl %r12d, %eax
subl %r15d, %eax
xorl %ecx, %ecx
cmpl 0x4(%rsp), %eax
setge %cl
addl %ecx, %r15d
jmp 0x5311
testl %r12d, %r12d
jle 0x527f
xorl %eax, %eax
cmpl %r12d, %r15d
leal -0x1(%r12), %ecx
setge %al
subl %eax, %r15d
movl %ecx, %r12d
jmp 0x5311
callq 0x6127
jmp 0x5311
callq 0x5c4c
jmp 0x5311
callq 0x5f77
jmp 0x5311
movl 0x10(%rsp), %eax
movl %eax, %r12d
jmp 0x5311
xorl %r12d, %r12d
jmp 0x5311
movl $0x3, 0x368(%rax)
cmpl $0x0, 0x220(%rax)
je 0x53b9
xorl %ecx, %ecx
xorl %edx, %edx
cmpq %rcx, %r14
je 0x5309
movl 0x2c8(%rbx,%rcx), %esi
cmpl 0x2c8(%rax), %esi
jne 0x5300
movl 0xc(%rbx,%rcx), %esi
cmpl 0xc(%rax), %esi
jne 0x5300
movl 0x4(%rbx,%rcx), %esi
cmpl 0x4(%rax), %esi
jne 0x5300
movl 0x210(%rbx,%rcx), %esi
cmpl 0x210(%rax), %esi
jne 0x5300
movl 0x214(%rbx,%rcx), %esi
cmpl 0x214(%rax), %esi
jne 0x5300
cmpl $0x0, 0x220(%rbx,%rcx)
jle 0x5300
xorl %esi, %esi
cmpl $0x1, 0x368(%rbx,%rcx)
sete %sil
addl %esi, %edx
addq $0x590, %rcx            # imm = 0x590
jmp 0x52a2
testl %edx, %edx
je 0x542b
xorl %ecx, %ecx
xorl %eax, %eax
cmpq %rcx, %r14
je 0x5332
xorl %edx, %edx
cmpl $0x1, 0x368(%rbx,%rcx)
sete %dl
addl %edx, %eax
addq $0x590, %rcx            # imm = 0x590
jmp 0x5315
cmpl $0x112, %ebp            # imm = 0x112
jne 0x4e69
testl %eax, %eax
je 0x4e69
jmp 0x549d
xorl %ecx, %ecx
cmpq %rcx, %r14
je 0x5311
movl 0x2c8(%rbx,%rcx), %edx
cmpl 0x2c8(%rax), %edx
jne 0x53b0
movl 0xc(%rbx,%rcx), %edx
cmpl 0xc(%rax), %edx
jne 0x53b0
movl 0x4(%rbx,%rcx), %edx
cmpl 0x4(%rax), %edx
jne 0x53b0
movl 0x210(%rbx,%rcx), %edx
cmpl 0x210(%rax), %edx
jne 0x53b0
movl 0x214(%rbx,%rcx), %edx
cmpl 0x214(%rax), %edx
jne 0x53b0
cmpl $0x0, 0x220(%rbx,%rcx)
jle 0x53b0
cmpl $0x6, 0x368(%rbx,%rcx)
je 0x53b0
movl $0x2, 0x368(%rbx,%rcx)
addq $0x590, %rcx            # imm = 0x590
jmp 0x534d
xorl %ecx, %ecx
cmpq %rcx, %r14
je 0x5311
movl 0x2c8(%rbx,%rcx), %edx
cmpl 0x2c8(%rax), %edx
jne 0x5422
movl 0xc(%rbx,%rcx), %edx
cmpl 0xc(%rax), %edx
jne 0x5422
movl 0x4(%rbx,%rcx), %edx
cmpl 0x4(%rax), %edx
jne 0x5422
movl 0x210(%rbx,%rcx), %edx
cmpl 0x210(%rax), %edx
jne 0x5422
movl 0x214(%rbx,%rcx), %edx
cmpl 0x214(%rax), %edx
jne 0x5422
cmpl $0x0, 0x220(%rbx,%rcx)
jle 0x5422
cmpl $0x6, 0x368(%rbx,%rcx)
je 0x5422
movl $0x3, 0x368(%rbx,%rcx)
addq $0x590, %rcx            # imm = 0x590
jmp 0x53bb
xorl %ecx, %ecx
cmpq %rcx, %r14
je 0x5311
movl 0x2c8(%rbx,%rcx), %edx
cmpl 0x2c8(%rax), %edx
jne 0x5494
movl 0xc(%rbx,%rcx), %edx
cmpl 0xc(%rax), %edx
jne 0x5494
movl 0x4(%rbx,%rcx), %edx
cmpl 0x4(%rax), %edx
jne 0x5494
movl 0x210(%rbx,%rcx), %edx
cmpl 0x210(%rax), %edx
jne 0x5494
movl 0x214(%rbx,%rcx), %edx
cmpl 0x214(%rax), %edx
jne 0x5494
cmpl $0x0, 0x220(%rbx,%rcx)
jne 0x5494
cmpl $0x6, 0x368(%rbx,%rcx)
je 0x5494
movl $0x3, 0x368(%rbx,%rcx)
addq $0x590, %rcx            # imm = 0x590
jmp 0x542d
movq 0xb384(%rip), %rdi      # 0x10828
callq 0x3050
movq 0xb378(%rip), %rdi      # 0x10828
callq 0x31b0
movq 0xb354(%rip), %rdi      # 0x10810
callq 0x3050
movq 0xb348(%rip), %rdi      # 0x10810
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x31b0