// File: /workspace/github_cpp_makefile_star2_O2/tomfunkhouser[P]gaps/pkgs/R3Utils/R3SurfelViewer.cpp
// Function: gaps::R3SurfelViewer::MouseButton(int, int, int, int, int, int, int, int)
int R3SurfelViewer::
MouseButton(int x, int y, int button, int state, int shift, int ctrl, int alt, int update_center_point)
{
  // Initialize
  int redraw = 0;

  // Process mouse button event
  if (state == 1) {
    // Button is going down
    mouse_drag_distance_squared = 0;

    // Remember mouse down position 
    mouse_down_position[0] = x;
    mouse_down_position[1] = y;

    // Process thumbwheel
    if ((button == 3) || (button == 4)) {
      R3Point viewing_center_point = center_point;
      const R3Camera& camera = viewer.Camera();
      R3Plane camera_plane(camera.Origin(), camera.Towards());
      RNScalar signed_distance = R3SignedDistance(camera_plane, viewing_center_point);
      if (signed_distance < 0) viewing_center_point -= (signed_distance - 1) * camera.Towards();
      if (button == 3) viewer.ScaleWorld(viewing_center_point, 1.1);
      else if (button == 4) viewer.ScaleWorld(viewing_center_point, 0.9);
      redraw = TRUE;
    }
  }
  else {
    // Check for drag
    RNBoolean drag = (mouse_drag_distance_squared > 10 * 10);

    // Check for double click
    static RNBoolean double_click = FALSE;
    static RNTime last_mouse_down_time;
    double_click = !drag && !double_click && (last_mouse_down_time.Elapsed() < 0.4);
    last_mouse_down_time.Read();

    // Select stuff on left click 
    if (!drag && update_center_point) {
      // Select image
      R3Point pick_position;
      R3SurfelImage *picked_image = PickImage(x, y, &pick_position);
      if (picked_image) {
        if (button == 0) SelectImage(picked_image, FALSE, FALSE);
        SetCenterPoint(pick_position);
        redraw = TRUE;
      }
      else {
        // Select point
        int picked_surfel_index = -1;
        R3SurfelBlock *picked_block = NULL;
        if (PickNode(x, y, &pick_position, &picked_block, &picked_surfel_index)) {
          // Hit
          if ((button == 0) && (picked_surfel_index >= 0)) {
            SelectPoint(picked_block, picked_surfel_index);
            if (selected_point && !image_plane_visibility) {
              R3SurfelImage *image = scene->FindImageByBestView(selected_point->Position(), selected_point->Normal());
              SelectImage(image, FALSE, FALSE);
            }
          }
          SetCenterPoint(pick_position);
          redraw = TRUE;
        }
        else {
          // Miss
          SelectPoint(NULL, -1);
          redraw = TRUE;
        }
      }
    }

    // Redraw if was subsampling
    if (subsampling_multiplier_when_mouse_down > 1) redraw = TRUE;
  }

  // Remember mouse position 
  mouse_position[0] = x;
  mouse_position[1] = y;

  // Remember button state 
  mouse_button[button] = state;
  
  // Remember modifiers 
  shift_down = shift;
  ctrl_down = ctrl;
  alt_down = alt;

  // Return whether need redraw
  return redraw;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
movl %r9d, %r12d
movl %r8d, %ebp
movl %ecx, %r15d
movq %rdi, %r14
cmpl $0x1, %r8d
jne 0x2f32f
andl $0x0, 0x4b8(%r14)
movl %esi, 0x4b0(%r14)
movl %edx, 0x4b4(%r14)
leal -0x3(%r15), %eax
xorl %ebx, %ebx
cmpl $0x1, %eax
ja 0x2f4f1
movl %esi, 0x8(%rsp)
movl %edx, 0x18(%rsp)
movq %r15, 0x10(%rsp)
movl %r12d, 0xc(%rsp)
leaq 0x2b0(%r14), %rsi
leaq 0x30(%rsp), %rdi
callq 0xb2330
leaq 0x78(%r14), %rax
movq %rax, 0x28(%rsp)
leaq 0x80(%r14), %r12
leaq 0xc8(%r14), %rbx
leaq 0x80(%rsp), %r13
movq %r13, %rdi
movq %rbx, %rsi
callq 0xb3446
leaq 0x48(%rsp), %r15
movq %r15, %rdi
movq %r12, %rsi
movq %r13, %rdx
callq 0xb0f80
movq %r15, %rdi
leaq 0x30(%rsp), %rsi
callq 0x7fda0
xorpd %xmm1, %xmm1
ucomisd %xmm0, %xmm1
jbe 0x2f2f5
addsd 0xead7f(%rip), %xmm0    # 0x11a038
movsd %xmm0, 0x20(%rsp)
leaq 0x68(%rsp), %r15
movq %r15, %rdi
movq %rbx, %rsi
callq 0xb3446
leaq 0x80(%rsp), %rbx
movq %rbx, %rdi
movq %r15, %rsi
movsd 0x20(%rsp), %xmm0
callq 0xb31d6
leaq 0x30(%rsp), %rdi
movq %rbx, %rsi
callq 0xb29b8
xorl %eax, %eax
movq 0x10(%rsp), %r15
cmpl $0x3, %r15d
sete %al
leaq 0xeb196(%rip), %rcx     # 0x11a4a0
movsd (%rcx,%rax,8), %xmm0
leaq 0x30(%rsp), %rsi
movq 0x28(%rsp), %rdi
callq 0x6ea76
pushq $0x1
popq %rbx
movl 0xc(%rsp), %r12d
movl 0x18(%rsp), %edx
jmp 0x2f4ed
movl %esi, 0x8(%rsp)
movl %edx, %r13d
movq %r15, 0x10(%rsp)
movl 0x4b8(%r14), %r15d
movb 0x17d6c0(%rip), %al     # 0x1aca08
testb %al, %al
je 0x2f557
movl %r12d, 0xc(%rsp)
movl 0xe0(%rsp), %r12d
xorl %ebx, %ebx
movl $0x0, %eax
cmpl $0x64, %r15d
jg 0x2f390
cmpl $0x0, 0x17d67f(%rip)    # 0x1ac9f0
jne 0x2f390
leaq 0x17d67e(%rip), %rdi    # 0x1ac9f8
callq 0xd0554
movsd 0xeac99(%rip), %xmm1    # 0x11a020
xorl %eax, %eax
ucomisd %xmm0, %xmm1
seta %al
cmpl $0x65, %r15d
setge %r15b
movl %eax, 0x17d652(%rip)    # 0x1ac9f0
leaq 0x17d653(%rip), %rdi    # 0x1ac9f8
callq 0x2baa4
testl %r12d, %r12d
sete %al
orb %r15b, %al
pushq $0x1
popq %rax
jne 0x2f4d5
leaq 0x48(%rsp), %rbx
movq %rbx, %rdi
callq 0xb231e
movq (%r14), %rax
movq %r14, %rdi
movl 0x8(%rsp), %r15d
movl %r15d, %esi
movl %r13d, %r12d
movl %r13d, %edx
movq %rbx, %rcx
callq *0x1e8(%rax)
testq %rax, %rax
je 0x2f40f
cmpl $0x0, 0x10(%rsp)
jne 0x2f4bf
movq (%r14), %r8
movq %r14, %rdi
movq %rax, %rsi
xorl %edx, %edx
xorl %ecx, %ecx
callq *0x1c0(%r8)
jmp 0x2f4bf
leaq 0x1c(%rsp), %r9
orl $-0x1, (%r9)
leaq 0x68(%rsp), %r8
andq $0x0, (%r8)
movq (%r14), %rax
andl $0x0, (%rsp)
leaq 0x48(%rsp), %rcx
movq %r14, %rdi
movl %r15d, %esi
movl %r12d, %edx
callq *0x1f8(%rax)
testq %rax, %rax
je 0x2f541
cmpl $0x0, 0x10(%rsp)
sete %al
movl 0x1c(%rsp), %edx
testl %edx, %edx
setns %cl
andb %al, %cl
cmpb $0x1, %cl
jne 0x2f4bf
movq 0x68(%rsp), %rsi
movq (%r14), %rax
movq %r14, %rdi
callq *0x1b8(%rax)
movq 0x2c8(%r14), %rsi
testq %rsi, %rsi
je 0x2f4bf
cmpl $0x0, 0x328(%r14)
jne 0x2f4bf
movq 0x8(%r14), %rbx
leaq 0x30(%rsp), %r15
movq %r15, %rdi
callq 0x32b2a
movq 0x2c8(%r14), %rsi
leaq 0x80(%rsp), %r12
movq %r12, %rdi
callq 0x32bbc
movq %rbx, %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0x44cee
jmp 0x2f3f6
movq (%r14), %rax
leaq 0x48(%rsp), %rsi
movq %r14, %rdi
callq *0x80(%rax)
pushq $0x1
popq %rax
movl %eax, %ebx
cmpl $0x2, 0x490(%r14)
cmovgel %eax, %ebx
movl 0xc(%rsp), %r12d
movq 0x10(%rsp), %r15
movl %r13d, %edx
movl 0x8(%rsp), %esi
movl 0xd8(%rsp), %eax
movl 0xd0(%rsp), %ecx
movl %esi, 0x4a8(%r14)
movl %edx, 0x4ac(%r14)
movslq %r15d, %rdx
movl %ebp, 0x49c(%r14,%rdx,4)
movl %r12d, 0x4bc(%r14)
movl %ecx, 0x4c0(%r14)
movl %eax, 0x4c4(%r14)
movl %ebx, %eax
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq (%r14), %rax
pushq $-0x1
popq %rdx
movq %r14, %rdi
xorl %esi, %esi
callq *0x1b8(%rax)
jmp 0x2f4d0
leaq 0x17d4aa(%rip), %rdi    # 0x1aca08
callq 0x281b0
testl %eax, %eax
je 0x2f350
leaq 0x17d486(%rip), %rdi    # 0x1ac9f8
callq 0xd051a
leaq 0x17d48a(%rip), %rdi    # 0x1aca08
callq 0x275f0
jmp 0x2f350
movq %rax, %rbx
leaq 0x17d476(%rip), %rdi    # 0x1aca08
callq 0x275d0
movq %rbx, %rdi
callq 0x28140
nop