// File: tomfunkhouser[P]gaps/apps/confview/confview.cpp
// Function: GLUTKeyboard(unsigned char, int, int)
void GLUTKeyboard(unsigned char key, int x, int y)
{
  // Invert y coordinate
  y = GLUTwindow_height - y;

  // Process keyboard button event
  switch (key) {
  case '~': {
    // Dump screen shot to file iX.jpg
    static char buffer[64];
    static int image_count = 1;
    sprintf(buffer, "i%d.jpg", image_count++);
    screenshot_image_name = buffer;
    break; }

  case 1: // ctrl-A
    for (int i = 0; i < configuration.NImages(); i++) {
      RGBDImage *image = configuration.Image(i);
      if (!image->DepthChannel()) image->ReadChannels();
    }
    break;

  case 26: // ctrl-Z
    for (int i = 0; i < configuration.NImages(); i++) {
      RGBDImage *image = configuration.Image(i);
      if (image->DepthChannel()) image->ReleaseChannels();
    }
    break;

  case 4: // ctrl-D
    DeleteSelectedSurface();
    break;

  case 18: // ctrl-R
    ResetViewer();
    break;

  case 'A':
  case 'a':
    show_axes = !show_axes;
    break;

  case 'B':
  case 'b':
    show_bboxes = !show_bboxes;
    break;

  case 'C':
  case 'c':
    show_cameras = !show_cameras;
    break;

  case 'D':
  case 'd':
    if (color_scheme == RGBD_PHOTO_COLOR_SCHEME) color_scheme = RGBD_RENDER_COLOR_SCHEME;
    else if (color_scheme == RGBD_RENDER_COLOR_SCHEME) color_scheme = RGBD_INDEX_COLOR_SCHEME;
    else color_scheme = RGBD_PHOTO_COLOR_SCHEME;
    break;

  case 'E':
  case 'e':
    show_edges = !show_edges;
    break;

  case 'F':
  case 'f':
    show_faces = !show_faces;
    break;

  case 'I':
  case 'i':
    show_images = !show_images;
    break;

  case 'O':
  case 'o':
    show_overlaps = !show_overlaps;
    break;

  case 'P':
  case 'p':
    show_points = !show_points;
    break;

  case 'q':
  case 'Q':
    show_quads = !show_quads;
    break;

  case 's':
  case 'S':
    show_surfels = !show_surfels;
    break;

  case 'T':
  case 't':
    show_textures = !show_textures;
    break;

  case 'V':
  case 'v':
    show_vertices = !show_vertices;
    break;
      
  case 'W':
  case 'w':
    if (snap_image_index >= 0) {
      RGBDImage *snap_image = configuration.Image(snap_image_index);
      viewer.RepositionCamera(snap_image->WorldViewpoint());
      viewer.ReorientCamera(snap_image->WorldTowards(), snap_image->WorldUp());
      center = snap_image->WorldViewpoint() + 3 * snap_image->WorldTowards();
    }
    break;
      
  case 'Y':
  case 'y':
    show_selected_position = !show_selected_position;
    break;

  case 'Z':
  case 'z':
    show_patches = !show_patches;
    break;

  case ' ': {
    RGBDImage *selected_image = NULL;
    if (Pick(x, y, NULL, &selected_image)) {
      printf("Picked %s\n", selected_image->Name());
      if (!selected_image->DepthChannel()) selected_image->ReadChannels();
      else selected_image->ReleaseChannels();
      selected_image_index = selected_image->ConfigurationIndex();
      snap_image_index = selected_image_index;
    }
    break; }

  case '!': {
    // Print camera
    const R3Camera& camera = viewer.Camera();
    printf("%g %g %g  %g %g %g  %g %g %g  %g %g  1\n",
           camera.Origin().X(), camera.Origin().Y(), camera.Origin().Z(),
           camera.Towards().X(), camera.Towards().Y(), camera.Towards().Z(),
           camera.Up().X(), camera.Up().Y(), camera.Up().Z(),
           camera.XFOV(), camera.YFOV());
    break; }

  case 27: // ESCAPE
    GLUTStop();
    break;
  }

  // Remember mouse position 
  GLUTmouse[0] = x;
  GLUTmouse[1] = GLUTwindow_height - y;

  // Remember modifiers 
  GLUTmodifiers = glutGetModifiers();

  // Redraw
  glutPostRedisplay();  
}

// Assembly:
subq $0x1a8, %rsp            # imm = 0x1A8
movb %dil, %al
movb %al, 0x1a7(%rsp)
movl %esi, 0x1a0(%rsp)
movl %edx, 0x19c(%rsp)
movl 0x2097db(%rip), %eax    # 0x235ae0
movl 0x19c(%rsp), %ecx
subl %ecx, %eax
movl %eax, 0x19c(%rsp)
movzbl 0x1a7(%rsp), %eax
decl %eax
movl %eax, %ecx
movq %rcx, 0x70(%rsp)
subl $0x7d, %eax
ja 0x2c9d7
movq 0x70(%rsp), %rax
leaq 0x19ad85(%rip), %rcx    # 0x1c70c0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl 0x2097a6(%rip), %edx    # 0x235af0
movl %edx, %eax
addl $0x1, %eax
movl %eax, 0x20979b(%rip)    # 0x235af0
leaq 0x20fab4(%rip), %rdi    # 0x23be10
leaq 0x19afac(%rip), %rsi    # 0x1c730f
movb $0x0, %al
callq 0x24160
leaq 0x20fa9f(%rip), %rax    # 0x23be10
movq %rax, 0x20fa50(%rip)    # 0x23bdc8
jmp 0x2c9d7
movl $0x0, 0x198(%rsp)
movl 0x198(%rsp), %eax
movl %eax, 0x6c(%rsp)
leaq 0x20f846(%rip), %rdi    # 0x23bbe0
callq 0x2ea00
movl %eax, %ecx
movl 0x6c(%rsp), %eax
cmpl %ecx, %eax
jge 0x2c3fd
movl 0x198(%rsp), %esi
leaq 0x20f829(%rip), %rdi    # 0x23bbe0
callq 0x2ea20
movq %rax, 0x190(%rsp)
movq 0x190(%rsp), %rdi
callq 0x2ea50
cmpq $0x0, %rax
jne 0x2c3e8
movq 0x190(%rsp), %rdi
movq (%rdi), %rax
callq *0xf8(%rax)
jmp 0x2c3ea
movl 0x198(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x198(%rsp)
jmp 0x2c388
jmp 0x2c9d7
movl $0x0, 0x18c(%rsp)
movl 0x18c(%rsp), %eax
movl %eax, 0x68(%rsp)
leaq 0x20f7c1(%rip), %rdi    # 0x23bbe0
callq 0x2ea00
movl %eax, %ecx
movl 0x68(%rsp), %eax
cmpl %ecx, %eax
jge 0x2c482
movl 0x18c(%rsp), %esi
leaq 0x20f7a4(%rip), %rdi    # 0x23bbe0
callq 0x2ea20
movq %rax, 0x180(%rsp)
movq 0x180(%rsp), %rdi
callq 0x2ea50
cmpq $0x0, %rax
je 0x2c46d
movq 0x180(%rsp), %rdi
movq (%rdi), %rax
callq *0x148(%rax)
jmp 0x2c46f
movl 0x18c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x18c(%rsp)
jmp 0x2c40d
jmp 0x2c9d7
callq 0x2ca10
jmp 0x2c9d7
callq 0x2c010
jmp 0x2c9d7
cmpl $0x0, 0x20f91e(%rip)    # 0x23bdc0
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x20f90e(%rip)    # 0x23bdc0
jmp 0x2c9d7
cmpl $0x0, 0x20f8d6(%rip)    # 0x23bd94
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x20f8c6(%rip)    # 0x23bd94
jmp 0x2c9d7
cmpl $0x0, 0x2095f6(%rip)    # 0x235ad0
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x2095e6(%rip)    # 0x235ad0
jmp 0x2c9d7
cmpl $0x1, 0x2095de(%rip)    # 0x235ad4
jne 0x2c504
movl $0x2, 0x2095d2(%rip)    # 0x235ad4
jmp 0x2c525
cmpl $0x2, 0x2095c9(%rip)    # 0x235ad4
jne 0x2c519
movl $0x3, 0x2095bd(%rip)    # 0x235ad4
jmp 0x2c523
movl $0x1, 0x2095b1(%rip)    # 0x235ad4
jmp 0x2c525
jmp 0x2c9d7
cmpl $0x0, 0x20f873(%rip)    # 0x23bda4
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x20f863(%rip)    # 0x23bda4
jmp 0x2c9d7
cmpl $0x0, 0x20f853(%rip)    # 0x23bda0
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x20f843(%rip)    # 0x23bda0
jmp 0x2c9d7
cmpl $0x0, 0x20f82f(%rip)    # 0x23bd98
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x20f81f(%rip)    # 0x23bd98
jmp 0x2c9d7
cmpl $0x0, 0x20f837(%rip)    # 0x23bdbc
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x20f827(%rip)    # 0x23bdbc
jmp 0x2c9d7
cmpl $0x0, 0x20f80b(%rip)    # 0x23bdac
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x20f7fb(%rip)    # 0x23bdac
jmp 0x2c9d7
cmpl $0x0, 0x20f7f7(%rip)    # 0x23bdb4
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x20f7e7(%rip)    # 0x23bdb4
jmp 0x2c9d7
cmpl $0x0, 0x20f7d7(%rip)    # 0x23bdb0
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x20f7c7(%rip)    # 0x23bdb0
jmp 0x2c9d7
cmpl $0x0, 0x20f7c3(%rip)    # 0x23bdb8
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x20f7b3(%rip)    # 0x23bdb8
jmp 0x2c9d7
cmpl $0x0, 0x20f797(%rip)    # 0x23bda8
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x20f787(%rip)    # 0x23bda8
jmp 0x2c9d7
cmpl $0x0, 0x2094bf(%rip)    # 0x235aec
jl 0x2c734
movl 0x2094b3(%rip), %esi    # 0x235aec
leaq 0x20f5a0(%rip), %rdi    # 0x23bbe0
callq 0x2ea20
movq %rax, 0x178(%rsp)
movq 0x178(%rsp), %rsi
leaq 0x160(%rsp), %rdi
callq 0x2eaa0
leaq 0x20f677(%rip), %rdi    # 0x23bce0
leaq 0x160(%rsp), %rsi
callq 0x2ea70
movq 0x178(%rsp), %rsi
leaq 0x148(%rsp), %rdi
callq 0x2eb20
movq 0x178(%rsp), %rsi
leaq 0x130(%rsp), %rdi
callq 0x2eb70
leaq 0x20f639(%rip), %rdi    # 0x23bce0
leaq 0x148(%rsp), %rsi
leaq 0x130(%rsp), %rdx
callq 0x2eaf0
movq 0x178(%rsp), %rsi
leaq 0x100(%rsp), %rdi
callq 0x2eaa0
movq 0x178(%rsp), %rsi
leaq 0xd0(%rsp), %rdi
callq 0x2eb20
leaq 0xe8(%rsp), %rdi
movsd 0x19a98a(%rip), %xmm0   # 0x1c7080
leaq 0xd0(%rsp), %rsi
callq 0x2ebc0
leaq 0x118(%rsp), %rdi
leaq 0x100(%rsp), %rsi
leaq 0xe8(%rsp), %rdx
callq 0xed770
leaq 0x20f5a1(%rip), %rdi    # 0x23bcc8
leaq 0x118(%rsp), %rsi
callq 0xed840
jmp 0x2c9d7
cmpl $0x0, 0x209398(%rip)    # 0x235ad8
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x209388(%rip)    # 0x235ad8
jmp 0x2c9d7
cmpl $0x0, 0x20f640(%rip)    # 0x23bd9c
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x20f630(%rip)    # 0x23bd9c
jmp 0x2c9d7
movq $0x0, 0xc8(%rsp)
movl 0x1a0(%rsp), %edi
movl 0x19c(%rsp), %esi
xorl %eax, %eax
movl %eax, %r8d
leaq 0xc8(%rsp), %rcx
movl $0xa, %r9d
movq %r8, %rdx
callq 0x2abb0
cmpl $0x0, %eax
je 0x2c81f
movq 0xc8(%rsp), %rdi
callq 0x2e9e0
movq %rax, %rsi
leaq 0x19ab55(%rip), %rdi    # 0x1c7317
movb $0x0, %al
callq 0x24090
movq 0xc8(%rsp), %rdi
callq 0x2ea50
cmpq $0x0, %rax
jne 0x2c7ef
movq 0xc8(%rsp), %rdi
movq (%rdi), %rax
callq *0xf8(%rax)
jmp 0x2c800
movq 0xc8(%rsp), %rdi
movq (%rdi), %rax
callq *0x148(%rax)
movq 0xc8(%rsp), %rdi
callq 0x2e9a0
movl %eax, 0x2092d5(%rip)    # 0x235ae8
movl 0x2092cf(%rip), %eax    # 0x235ae8
movl %eax, 0x2092cd(%rip)    # 0x235aec
jmp 0x2c9d7
leaq 0x20f4b5(%rip), %rdi    # 0x23bce0
callq 0x2e900
movq %rax, 0xc0(%rsp)
movq 0xc0(%rsp), %rdi
callq 0x2ec00
movq %rax, %rdi
callq 0x2e9b0
movsd %xmm0, 0x60(%rsp)
movq 0xc0(%rsp), %rdi
callq 0x2ec00
movq %rax, %rdi
callq 0x2e9c0
movsd %xmm0, 0x18(%rsp)
movq 0xc0(%rsp), %rdi
callq 0x2ec00
movq %rax, %rdi
callq 0x2e9d0
movsd %xmm0, 0x20(%rsp)
movq 0xc0(%rsp), %rsi
leaq 0xa8(%rsp), %rdi
callq 0x2ec10
leaq 0xa8(%rsp), %rdi
callq 0x2ec60
movsd %xmm0, 0x28(%rsp)
movq 0xc0(%rsp), %rsi
leaq 0x90(%rsp), %rdi
callq 0x2ec10
leaq 0x90(%rsp), %rdi
callq 0x2ec70
movsd %xmm0, 0x30(%rsp)
movq 0xc0(%rsp), %rsi
leaq 0x78(%rsp), %rdi
callq 0x2ec10
leaq 0x78(%rsp), %rdi
callq 0x2ec80
movsd %xmm0, 0x38(%rsp)
movq 0xc0(%rsp), %rdi
callq 0x2ec90
movq %rax, %rdi
callq 0x2ec60
movsd %xmm0, 0x40(%rsp)
movq 0xc0(%rsp), %rdi
callq 0x2ec90
movq %rax, %rdi
callq 0x2ec70
movsd %xmm0, 0x48(%rsp)
movq 0xc0(%rsp), %rdi
callq 0x2ec90
movq %rax, %rdi
callq 0x2ec80
movsd %xmm0, 0x50(%rsp)
movq 0xc0(%rsp), %rdi
callq 0x2ecb0
movsd %xmm0, 0x58(%rsp)
movq 0xc0(%rsp), %rdi
callq 0x2ecc0
movsd 0x18(%rsp), %xmm1
movsd 0x20(%rsp), %xmm2
movsd 0x28(%rsp), %xmm3
movsd 0x30(%rsp), %xmm4
movsd 0x38(%rsp), %xmm5
movsd 0x40(%rsp), %xmm6
movsd 0x48(%rsp), %xmm7
movsd 0x50(%rsp), %xmm10
movsd 0x58(%rsp), %xmm9
movaps %xmm0, %xmm8
movsd 0x60(%rsp), %xmm0
leaq 0x19a96d(%rip), %rdi    # 0x1c7322
movsd %xmm10, (%rsp)
movsd %xmm9, 0x8(%rsp)
movsd %xmm8, 0x10(%rsp)
movb $0x8, %al
callq 0x24090
jmp 0x2c9d7
callq 0x29130
movl 0x1a0(%rsp), %eax
movl %eax, 0x20f3f0(%rip)    # 0x23bdd4
movl 0x2090f6(%rip), %eax    # 0x235ae0
subl 0x19c(%rsp), %eax
movl %eax, 0x20f3e1(%rip)    # 0x23bdd8
callq 0x1bad10
movl %eax, 0x20f3de(%rip)    # 0x23bde0
callq 0x1b2ae0
addq $0x1a8, %rsp            # imm = 0x1A8
retq
nop