// File: /workspace/github_cpp_makefile_star2_O1/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, %r13d
movl %r8d, %ebx
movl %ecx, %r15d
movl %edx, %ebp
movl %esi, %r12d
movq %rdi, %r14
cmpl $0x1, %r8d
jne 0x30769
movl $0x0, 0x4b8(%r14)
movl %r12d, 0x4b0(%r14)
movl %ebp, 0x4b4(%r14)
leal -0x3(%r15), %ecx
xorl %eax, %eax
cmpl $0x1, %ecx
ja 0x3094f
movl %r12d, 0x1c(%rsp)
movl %ebp, 0x18(%rsp)
movl %ebx, 0x14(%rsp)
movl %r13d, 0x20(%rsp)
leaq 0x2b0(%r14), %rsi
leaq 0x30(%rsp), %rdi
callq 0xc532e
leaq 0x80(%r14), %r13
leaq 0xc8(%r14), %rbx
leaq 0x80(%rsp), %r12
movq %r12, %rdi
movq %rbx, %rsi
callq 0xc6a4c
leaq 0x48(%rsp), %rbp
movq %rbp, %rdi
movq %r13, %rsi
movq %r12, %rdx
callq 0xc3e9e
movq %rbp, %rdi
leaq 0x30(%rsp), %rsi
callq 0x8cc8b
xorpd %xmm1, %xmm1
ucomisd %xmm0, %xmm1
jbe 0x30736
addsd 0x10a93e(%rip), %xmm0   # 0x13b038
movsd %xmm0, 0x28(%rsp)
leaq 0x68(%rsp), %r12
movq %r12, %rdi
movq %rbx, %rsi
callq 0xc6a4c
leaq 0x80(%rsp), %rbx
movq %rbx, %rdi
movq %r12, %rsi
movsd 0x28(%rsp), %xmm0
callq 0xc6786
leaq 0x30(%rsp), %rdi
movq %rbx, %rsi
callq 0xc5c8c
cmpl $0x3, %r15d
movl 0x20(%rsp), %r13d
movl 0x18(%rsp), %ebp
movl 0x1c(%rsp), %r12d
je 0x30930
cmpl $0x4, %r15d
movl 0x14(%rsp), %ebx
jne 0x3094a
movsd 0x10abf4(%rip), %xmm0   # 0x13b358
jmp 0x3093c
movl %r12d, 0x1c(%rsp)
movl %ebp, 0x18(%rsp)
movl %ebx, 0x14(%rsp)
movl 0x4b8(%r14), %ebx
movb 0x194265(%rip), %al     # 0x1c49e8
testb %al, %al
je 0x309b5
movl 0xe0(%rsp), %ebp
xorl %r12d, %r12d
movl $0x0, %eax
cmpl $0x64, %ebx
jg 0x307c5
cmpl $0x0, 0x19422a(%rip)    # 0x1c49d0
jne 0x307c5
leaq 0x194229(%rip), %rdi    # 0x1c49d8
callq 0xe698e
movsd 0x10a864(%rip), %xmm1   # 0x13b020
xorl %eax, %eax
ucomisd %xmm0, %xmm1
seta %al
cmpl $0x65, %ebx
setge %bl
movl %eax, 0x1941ff(%rip)    # 0x1c49d0
leaq 0x194200(%rip), %rdi    # 0x1c49d8
xorl %esi, %esi
callq 0x28030
testl %ebp, %ebp
sete %al
orb %bl, %al
movl 0x18(%rsp), %ebp
jne 0x30914
leaq 0x48(%rsp), %rbx
movq %rbx, %rdi
callq 0xc531c
movq (%r14), %rax
movq %r14, %rdi
movl 0x1c(%rsp), %r12d
movl %r12d, %esi
movl %ebp, %edx
movq %rbx, %rcx
callq *0x1e8(%rax)
testq %rax, %rax
je 0x3083d
testl %r15d, %r15d
jne 0x308fd
movq (%r14), %r8
movq %r14, %rdi
movq %rax, %rsi
xorl %edx, %edx
xorl %ecx, %ecx
callq *0x1c0(%r8)
jmp 0x308fd
leaq 0x24(%rsp), %r9
movl $0xffffffff, (%r9)      # imm = 0xFFFFFFFF
leaq 0x68(%rsp), %r8
movq $0x0, (%r8)
movq (%r14), %rax
movl $0x0, (%rsp)
leaq 0x48(%rsp), %rcx
movq %r14, %rdi
movl %r12d, %esi
movl %ebp, %edx
callq *0x1f8(%rax)
testq %rax, %rax
je 0x3099d
testl %r15d, %r15d
sete %al
movl 0x24(%rsp), %edx
testl %edx, %edx
setns %cl
andb %al, %cl
cmpb $0x1, %cl
jne 0x308fd
movq 0x68(%rsp), %rsi
movq (%r14), %rax
movq %r14, %rdi
callq *0x1b8(%rax)
movq 0x2c8(%r14), %rsi
testq %rsi, %rsi
je 0x308fd
cmpl $0x0, 0x328(%r14)
jne 0x308fd
movq 0x8(%r14), %rbx
leaq 0x30(%rsp), %r12
movq %r12, %rdi
callq 0x3455c
movq 0x2c8(%r14), %rsi
movl %r13d, %ebp
leaq 0x80(%rsp), %r13
movq %r13, %rdi
callq 0x3458e
movq %rbx, %rdi
movq %r12, %rsi
movq %r13, %rdx
movl %ebp, %r13d
movl 0x18(%rsp), %ebp
callq 0x48d6c
jmp 0x30824
movq (%r14), %rax
leaq 0x48(%rsp), %rsi
movq %r14, %rdi
callq *0x80(%rax)
movl $0x1, %r12d
cmpl $0x2, 0x490(%r14)
movl $0x1, %eax
cmovll %r12d, %eax
movl 0x14(%rsp), %ebx
movl 0x1c(%rsp), %r12d
jmp 0x3094f
movsd 0x10aa90(%rip), %xmm0   # 0x13b3c8
movl 0x14(%rsp), %ebx
leaq 0x78(%r14), %rdi
leaq 0x30(%rsp), %rsi
callq 0x78f9c
movl $0x1, %eax
movl 0xd8(%rsp), %ecx
movl 0xd0(%rsp), %edx
movl %r12d, 0x4a8(%r14)
movl %ebp, 0x4ac(%r14)
movslq %r15d, %rsi
movl %ebx, 0x49c(%r14,%rsi,4)
movl %r13d, 0x4bc(%r14)
movl %edx, 0x4c0(%r14)
movl %ecx, 0x4c4(%r14)
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq (%r14), %rax
movq %r14, %rdi
xorl %esi, %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq *0x1b8(%rax)
jmp 0x3090e
leaq 0x19402c(%rip), %rdi    # 0x1c49e8
callq 0x281a0
testl %eax, %eax
je 0x3078b
leaq 0x194008(%rip), %rdi    # 0x1c49d8
callq 0xe692c
leaq 0x19400c(%rip), %rdi    # 0x1c49e8
callq 0x275f0
jmp 0x3078b
movq %rax, %rbx
leaq 0x193ff8(%rip), %rdi    # 0x1c49e8
callq 0x275d0
movq %rbx, %rdi
callq 0x28130
nop