// File: tomfunkhouser[P]gaps/apps/scnview/scnview.cpp
// Function: GLUTMouse(int, int, int, int)
void GLUTMouse(int button, int state, int x, int y)
{
  // Invert y coordinate
  y = GLUTwindow_height - y;

  // Mouse is going down
  if (state == GLUT_DOWN) {
    // Reset mouse drag
    GLUTmouse_drag = 0;

    // Process thumbwheel
    if (button == 3) viewer->ScaleWorld(center, 0.9);
    else if (button == 4) viewer->ScaleWorld(center, 1.1);
  }
  else if (button == 0) {
    // Check for double click  
    static RNBoolean double_click = FALSE;
    static RNTime last_mouse_up_time;
    double_click = (!double_click) && (last_mouse_up_time.Elapsed() < 0.4);
    last_mouse_up_time.Read();

    // Check for click (rather than drag)
    if (GLUTmouse_drag < 100) {
      // Check for double click
      if (double_click) {
        // Set viewing center point 
        R3Point intersection_point;
        if (Pick(scene, x, y, NULL, &intersection_point)) {
          center = intersection_point;
        }
      }
      else {
        // Select node 
        R3Point position;
        R3Vector normal;
        selected_node = NULL;;
#if 1
        if (Pick(scene, x, y, &selected_node, &position)) {
          printf("Selected %s    %g %g %g\n", (selected_node->Name()) ? selected_node->Name() : "NoName",
            position.X(), position.Y(), position.Z());
        }
#else
        R3Ray ray = viewer->WorldRay(x, y);
        R3Material *material = NULL;
        if (scene->Intersects(ray, &selected_node, &material, NULL, &position, &normal)) {
          printf("Selected %s    %g %g %g    %g %g %g\n", (selected_node->Name()) ? selected_node->Name() : "NoName",
            position.X(), position.Y(), position.Z(), normal.X(), normal.Y(), normal.Z());
          const char *material_name = (material) ? material->Name() : "-";
          const R3Brdf *brdf = (material) ? material->Brdf() : NULL;
          const char *brdf_name = (brdf) ? brdf->Name() : "-";
          RNRgb diffuse = (brdf) ? brdf->Diffuse() : RNblack_rgb;
          RNRgb specular = (brdf) ? brdf->Specular() : RNblack_rgb;
          RNRgb transmission = (brdf) ? brdf->Transmission() : RNblack_rgb;
          RNRgb emission = (brdf) ? brdf->Emission() : RNblack_rgb;
          RNScalar shininess = (brdf) ? brdf->Shininess() : 0;
          const R2Texture *texture = (material) ? material->Texture() : NULL;
          const char *texture_name = (texture) ? texture->Name() : "-";
          printf("  Material %s : brdf %s  kd=(%g %g %g) ks=(%g %g %g) kt=(%g %g %g) ke=(%g %g %g) ns=%g : texture %s\n", material_name,
            brdf_name, diffuse.R(), diffuse.G(), diffuse.B(), specular.R(), specular.G(), specular.B(),
            transmission.R(), transmission.G(), transmission.B(), emission.R(), emission.G(), emission.B(),
            shininess, texture_name);
        }
#endif
      }
    }
  }

  // Remember button state 
  int b = (button == GLUT_LEFT_BUTTON) ? 0 : ((button == GLUT_MIDDLE_BUTTON) ? 1 : 2);
  GLUTbutton[b] = (state == GLUT_DOWN) ? 1 : 0;

  // Remember modifiers 
  GLUTmodifiers = glutGetModifiers();

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

  // Redraw
  glutPostRedisplay();
}

// Assembly:
subq $0x98, %rsp
movl %edi, 0x94(%rsp)
movl %esi, 0x90(%rsp)
movl %edx, 0x8c(%rsp)
movl %ecx, 0x88(%rsp)
movl 0x1cd15f(%rip), %eax    # 0x1f5ac8
subl 0x88(%rsp), %eax
movl %eax, 0x88(%rsp)
cmpl $0x0, 0x90(%rsp)
jne 0x289de
movl $0x0, 0x1d3345(%rip)    # 0x1fbcd0
cmpl $0x3, 0x94(%rsp)
jne 0x289b2
movq 0x1d328c(%rip), %rdi    # 0x1fbc28
leaq 0x1d3255(%rip), %rsi    # 0x1fbbf8
movsd 0x1656cd(%rip), %xmm0   # 0x18e078
callq 0x5a730
jmp 0x289d9
cmpl $0x4, 0x94(%rsp)
jne 0x289d7
movq 0x1d3265(%rip), %rdi    # 0x1fbc28
leaq 0x1d322e(%rip), %rsi    # 0x1fbbf8
movsd 0x16569e(%rip), %xmm0   # 0x18e070
callq 0x5a730
jmp 0x289d9
jmp 0x28bcd
cmpl $0x0, 0x94(%rsp)
jne 0x28bcb
cmpb $0x0, 0x1d3305(%rip)    # 0x1fbcf8
jne 0x28a20
leaq 0x1d32fc(%rip), %rdi    # 0x1fbcf8
callq 0x23310
cmpl $0x0, %eax
je 0x28a20
leaq 0x1d32db(%rip), %rdi    # 0x1fbce8
callq 0xeeb80
jmp 0x28a14
leaq 0x1d32dd(%rip), %rdi    # 0x1fbcf8
callq 0x22680
xorl %eax, %eax
cmpl $0x0, 0x1d32bb(%rip)    # 0x1fbce4
movb %al, 0x2b(%rsp)
jne 0x28a51
leaq 0x1d32b2(%rip), %rdi    # 0x1fbce8
callq 0xeec40
movaps %xmm0, %xmm1
movsd 0x165622(%rip), %xmm0   # 0x18e068
ucomisd %xmm1, %xmm0
seta %al
movb %al, 0x2b(%rsp)
movb 0x2b(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x1d3284(%rip)    # 0x1fbce4
leaq 0x1d3281(%rip), %rdi    # 0x1fbce8
callq 0x2b680
cmpl $0x64, 0x1d325d(%rip)   # 0x1fbcd0
jge 0x28bc9
cmpl $0x0, 0x1d3264(%rip)    # 0x1fbce4
je 0x28aee
leaq 0x60(%rsp), %rdi
callq 0xcc860
movq 0x1d3185(%rip), %rdi    # 0x1fbc18
movl 0x8c(%rsp), %esi
movl 0x88(%rsp), %edx
xorl %eax, %eax
movl %eax, %ecx
leaq 0x60(%rsp), %r8
callq 0x28c70
cmpl $0x0, %eax
je 0x28ae9
leaq 0x1d313d(%rip), %rdi    # 0x1fbbf8
leaq 0x60(%rsp), %rsi
callq 0xccf00
jmp 0x28ae9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x80(%rsp)
movl %eax, 0x7c(%rsp)
leaq 0x1d3219(%rip), %rdi    # 0x1fbcf8
callq 0x22660
jmp 0x28c57
jmp 0x28bc7
leaq 0x48(%rsp), %rdi
callq 0xcc860
leaq 0x30(%rsp), %rdi
callq 0xcd9c0
movq $0x0, 0x1d3143(%rip) # 0x1fbc50
movq 0x1d3104(%rip), %rdi    # 0x1fbc18
movl 0x8c(%rsp), %esi
movl 0x88(%rsp), %edx
leaq 0x1d3127(%rip), %rcx    # 0x1fbc50
leaq 0x48(%rsp), %r8
callq 0x28c70
cmpl $0x0, %eax
je 0x28bc5
movq 0x1d310d(%rip), %rdi    # 0x1fbc50
callq 0x2b800
cmpq $0x0, %rax
je 0x28b61
movq 0x1d30fb(%rip), %rdi    # 0x1fbc50
callq 0x2b800
movq %rax, 0x20(%rsp)
jmp 0x28b6f
leaq 0x1656d8(%rip), %rax    # 0x18e240
movq %rax, 0x20(%rsp)
jmp 0x28b6f
movq 0x20(%rsp), %rax
movq %rax, 0x8(%rsp)
leaq 0x48(%rsp), %rdi
callq 0x2b820
movsd %xmm0, 0x18(%rsp)
leaq 0x48(%rsp), %rdi
callq 0x2b830
movsd %xmm0, 0x10(%rsp)
leaq 0x48(%rsp), %rdi
callq 0x2b840
movq 0x8(%rsp), %rsi
movsd 0x10(%rsp), %xmm1
movaps %xmm0, %xmm2
movsd 0x18(%rsp), %xmm0
leaq 0x165669(%rip), %rdi    # 0x18e227
movb $0x3, %al
callq 0x22090
jmp 0x28bc7
jmp 0x28bc9
jmp 0x28bcb
jmp 0x28bcd
cmpl $0x0, 0x94(%rsp)
jne 0x28bdf
xorl %eax, %eax
movl %eax, 0x4(%rsp)
jmp 0x28bfa
movl 0x94(%rsp), %edx
movl $0x2, %eax
movl $0x1, %ecx
cmpl $0x1, %edx
cmovel %ecx, %eax
movl %eax, 0x4(%rsp)
movl 0x4(%rsp), %eax
movl %eax, 0x2c(%rsp)
movl 0x90(%rsp), %ecx
xorl %edx, %edx
movl $0x1, %eax
cmpl $0x0, %ecx
cmovel %eax, %edx
movslq 0x2c(%rsp), %rcx
leaq 0x1d30b6(%rip), %rax    # 0x1fbcd8
movl %edx, (%rax,%rcx,4)
callq 0x1821b0
movl %eax, 0x1d30a4(%rip)    # 0x1fbcd4
movl 0x8c(%rsp), %eax
movl %eax, 0x1d308b(%rip)    # 0x1fbcc8
movl 0x88(%rsp), %eax
movl %eax, 0x1d3082(%rip)    # 0x1fbccc
callq 0x179f80
addq $0x98, %rsp
retq
movq 0x80(%rsp), %rdi
callq 0x23290
nopw %cs:(%rax,%rax)