// File: /workspace/github_cpp_makefile_star2_O3/tomfunkhouser[P]gaps/pkgs/R3Graphics/R3Scene.cpp
// Function: gaps::R3Scene::ReadSUNCGModelFile(char const*)
int R3Scene::
ReadSUNCGModelFile(const char *filename)
{
  // Open file
  FILE *fp = fopen(filename, "r");
  if (!fp) {
    RNFail("Unable to open lights file %s\n", filename);
    return 0;
  }

  // Read keys from first line
  int line_number = 1;
  char key_buffer[4096];
  RNArray<char *> keys;
  if (fgets(key_buffer, 4096, fp)) {
    char *token = strtok(key_buffer, ",\r\n");
    while (token) {
      keys.Insert(RNStrdup(token));
      token = strtok(NULL, ",\r\n");
    }
  }

  // Extract index of model_id
  int model_id_k = -1;
  for (int i = 0; i < keys.NEntries(); i++) {
    if (!strcmp(keys[i], "model_id")) {
      model_id_k = i;
      break;
    }
  }

  // Check if found model_id
  if (model_id_k < 0) {
    RNFail("Did not find \"model_id\" in header on line %d of %s\n", line_number, filename);
    return 0;
  }

  // Read subsequent lines of file
  char value_buffer[4096];
  while (fgets(value_buffer, 4096, fp)) {
    line_number++;

    // Read values
    RNArray<char *> values;
    char *token = strtok(value_buffer, ",\r\n");
    while (token) {
      values.Insert(RNStrdup(token));
      token = strtok(NULL, ",\r\n");
    }

    // Check number of values
    if (values.NEntries() == 0) continue;
    if (values.NEntries() != keys.NEntries()) {
      RNFail("Invalid number of entries at line %d in %s\n", line_number, filename);
      return 0;
    }

    // Get model id
    const char *model_id = values[model_id_k];
    if (!model_id) continue;
    int model_id_length = strlen(model_id);
    if (model_id_length == 0) continue;

    // Assign key-value info to nodes matching model_id
    for (int i = 0; i < NNodes(); i++) {
      R3SceneNode *node = Node(i);

      // Determine if node name matches model_id
      if (node->Name()) {
        char node_name[1024];
        strncpy(node_name, node->Name(), 1023);
        char *model_name = strchr(node_name, '#');
        if (model_name) { *model_name = '\0'; model_name++; }
        else model_name = node_name;
        if (!strcmp(node_name, model_id) || !strcmp(model_name, model_id)) {
          for (int j = 0; j < keys.NEntries(); j++) node->InsertInfo(keys[j], values[j]);
        }
      }

      // Determine if referenced scene name matches model_id
      for (int j = 0; j < node->NReferences(); j++) {
        R3SceneReference *reference = node->Reference(j);
        R3Scene *referenced_scene = reference->ReferencedScene();
        R3SceneNode *root = referenced_scene->Root();
        if (!root->Name()) continue;
        char node_name[1024];
        strncpy(node_name, root->Name(), 1023);
        char *model_name = strchr(node_name, '#');
        if (model_name) { *model_name = '\0'; model_name++; }
        else model_name = node_name;
        if (!strcmp(node_name, model_id) || !strcmp(model_name, model_id)) {
          for (int j = 0; j < keys.NEntries(); j++) node->InsertInfo(keys[j], values[j]);
          break;
        }
      }
    }

    // Assign key-value info to root node of referenced scene matching model_id
    R3Scene *model = ReferencedScene(model_id);
    if (model) {
      for (int i = 0; i < keys.NEntries(); i++) {
        model->Root()->InsertInfo(keys[i], values[i]);
      }
    }
  }

  // Close file
  fclose(fp);

  // Delete inactive nodes
  RNArray<R3SceneNode *> tmp;
  for (int i = 0; i < NNodes(); i++)
    tmp.Insert(Node(i));
  for (int i = 0; i < tmp.NEntries(); i++) {
    R3SceneNode *node = tmp.Kth(i);
    const char *active = node->Info("active");
    if (!active) continue;
    if (strcmp(active, "0")) continue;
    delete node;
  }

  
#if 0
  // Print result
  for (int i = 0; i < NNodes(); i++) {
    R3SceneNode *node = Node(i);
    const char *model_index = node->Info("index");
    if (model_index) printf("%s %s\n", node->Name(), model_index);
  }
#endif
  
  // Return success
  return 1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x2458, %rsp           # imm = 0x2458
movq %rsi, %r14
movq %rdi, %r13
leaq 0xaaccb(%rip), %rsi     # 0xe1083
movq %r14, %rdi
callq 0x21ab0
testq %rax, %rax
je 0x36490
movq %rax, %rbp
movq %r14, 0x30(%rsp)
leaq 0x18(%rsp), %rdi
callq 0x8758c
leaq 0x1450(%rsp), %rdi
movl $0x1000, %esi           # imm = 0x1000
movq %rbp, %rdx
callq 0x21f30
testq %rax, %rax
je 0x36440
leaq 0xa5138(%rip), %rsi     # 0xdb534
leaq 0x1450(%rsp), %rdi
callq 0x21ef0
testq %rax, %rax
je 0x36440
leaq 0x18(%rsp), %r14
leaq 0xa511a(%rip), %r15     # 0xdb534
movq %rax, %rdi
callq 0x89f5f
movl 0x24(%rsp), %edx
movq %r14, %rdi
movq %rax, %rsi
callq 0x87622
xorl %edi, %edi
movq %r15, %rsi
callq 0x21ef0
testq %rax, %rax
jne 0x3641a
movslq 0x24(%rsp), %rbx
testq %rbx, %rbx
jle 0x36471
movq 0x18(%rsp), %r15
xorl %r12d, %r12d
leaq 0xa50df(%rip), %r14     # 0xdb538
movq (%r15,%r12,8), %rdi
movq %r14, %rsi
callq 0x21d00
testl %eax, %eax
je 0x364a8
incq %r12
cmpq %r12, %rbx
jne 0x36459
xorl %ebx, %ebx
leaq 0xa50c7(%rip), %rdi     # 0xdb541
movl $0x1, %esi
movq 0x30(%rsp), %rdx
xorl %eax, %eax
callq 0x8a0fe
jmp 0x3686e
leaq 0xa4ebe(%rip), %rdi     # 0xdb355
xorl %ebx, %ebx
movq %r14, %rsi
xorl %eax, %eax
callq 0x8a0fe
jmp 0x36878
movq %r12, 0x38(%rsp)
leaq 0x450(%rsp), %rdi
movl $0x1000, %esi           # imm = 0x1000
movq %rbp, %rdx
callq 0x21f30
testq %rax, %rax
je 0x3674d
movl $0x1, %r12d
leaq 0x8(%rsp), %r14
leaq 0xa5057(%rip), %r15     # 0xdb534
leaq 0x50(%rsp), %rbx
movq %r13, 0x48(%rsp)
movq %rbp, 0x40(%rsp)
movq %r14, %rdi
callq 0x8758c
leaq 0x450(%rsp), %rdi
movq %r15, %rsi
callq 0x21ef0
testq %rax, %rax
je 0x36524
movq %rax, %rdi
callq 0x89f5f
movl 0x14(%rsp), %edx
movq %r14, %rdi
movq %rax, %rsi
callq 0x87622
xorl %edi, %edi
jmp 0x364fc
incl %r12d
movl 0x14(%rsp), %ebp
testl %ebp, %ebp
je 0x36716
cmpl 0x24(%rsp), %ebp
jne 0x3684c
movq 0x8(%rsp), %rax
movq 0x38(%rsp), %rcx
movq (%rax,%rcx,8), %r15
testq %r15, %r15
je 0x36716
movq %r15, %rdi
callq 0x21380
testl %eax, %eax
je 0x36716
cmpl $0x0, 0x14(%r13)
jle 0x366d5
movl %r12d, 0x2c(%rsp)
xorl %r12d, %r12d
movq 0x8(%r13), %rax
movq (%rax,%r12,8), %rbp
movq 0x1a0(%rbp), %rsi
testq %rsi, %rsi
je 0x36605
movl $0x3ff, %edx            # imm = 0x3FF
movq %rbx, %rdi
callq 0x21430
movq %rbx, %rdi
movl $0x23, %esi
callq 0x21330
movq %rbx, %r14
testq %rax, %rax
je 0x365b6
movb $0x0, (%rax)
incq %rax
movq %rax, %r14
movq %rbx, %rdi
movq %r15, %rsi
callq 0x21d00
testl %eax, %eax
je 0x365d4
movq %r14, %rdi
movq %r15, %rsi
callq 0x21d00
testl %eax, %eax
jne 0x36605
cmpl $0x0, 0x24(%rsp)
jle 0x36605
xorl %r14d, %r14d
movq 0x18(%rsp), %rax
movq (%rax,%r14,8), %rsi
movq 0x8(%rsp), %rax
movq (%rax,%r14,8), %rdx
movq %rbp, %rdi
callq 0x3ca2a
incq %r14
movslq 0x24(%rsp), %rax
cmpq %rax, %r14
jl 0x365de
movl 0x4c(%rbp), %eax
testl %eax, %eax
jle 0x366b7
xorl %r13d, %r13d
movq 0x40(%rbp), %rcx
movq (%rcx,%r13,8), %rcx
movq (%rcx), %rcx
movq (%rcx), %rcx
movq 0x1a0(%rcx), %rsi
testq %rsi, %rsi
je 0x36679
movl $0x3ff, %edx            # imm = 0x3FF
movq %rbx, %rdi
callq 0x21430
movq %rbx, %rdi
movl $0x23, %esi
callq 0x21330
movq %rbx, %r14
testq %rax, %rax
je 0x36658
movb $0x0, (%rax)
incq %rax
movq %rax, %r14
movq %rbx, %rdi
movq %r15, %rsi
callq 0x21d00
testl %eax, %eax
je 0x36686
movq %r14, %rdi
movq %r15, %rsi
callq 0x21d00
testl %eax, %eax
je 0x36686
movl 0x4c(%rbp), %eax
incq %r13
movslq %eax, %rcx
cmpq %rcx, %r13
jl 0x36613
jmp 0x366b7
cmpl $0x0, 0x24(%rsp)
jle 0x366b7
xorl %r14d, %r14d
movq 0x18(%rsp), %rax
movq (%rax,%r14,8), %rsi
movq 0x8(%rsp), %rax
movq (%rax,%r14,8), %rdx
movq %rbp, %rdi
callq 0x3ca2a
incq %r14
movslq 0x24(%rsp), %rax
cmpq %rax, %r14
jl 0x36690
incq %r12
movq 0x48(%rsp), %r13
movslq 0x14(%r13), %rax
cmpq %rax, %r12
jl 0x36577
movl 0x24(%rsp), %ebp
movl 0x2c(%rsp), %r12d
movq %r13, %rdi
movq %r15, %rsi
callq 0x28638
testq %rax, %rax
je 0x36716
testl %ebp, %ebp
jle 0x36716
movq %rax, %r15
xorl %r14d, %r14d
movq (%r15), %rdi
movq 0x18(%rsp), %rax
movq (%rax,%r14,8), %rsi
movq 0x8(%rsp), %rax
movq (%rax,%r14,8), %rdx
callq 0x3ca2a
incq %r14
movslq 0x24(%rsp), %rax
cmpq %rax, %r14
jl 0x366ef
leaq 0x8(%rsp), %r14
movq %r14, %rdi
callq 0x875f6
leaq 0x450(%rsp), %rdi
movl $0x1000, %esi           # imm = 0x1000
movq 0x40(%rsp), %rbp
movq %rbp, %rdx
callq 0x21f30
testq %rax, %rax
leaq 0xa4ded(%rip), %r15     # 0xdb534
jne 0x364ec
movq %rbp, %rdi
callq 0x218b0
leaq 0x8(%rsp), %rdi
callq 0x8758c
cmpl $0x0, 0x14(%r13)
jle 0x3678d
xorl %ebx, %ebx
leaq 0x8(%rsp), %r14
movq 0x8(%r13), %rax
movq (%rax,%rbx,8), %rsi
movl 0x14(%rsp), %edx
movq %r14, %rdi
callq 0x87622
incq %rbx
movslq 0x14(%r13), %rax
cmpq %rax, %rbx
jl 0x3676d
cmpl $0x0, 0x14(%rsp)
jle 0x3683b
leaq 0x60(%rsp), %r13
xorl %ebp, %ebp
leaq 0xa4e01(%rip), %r14     # 0xdb5a7
leaq 0x50(%rsp), %r15
movq 0x8(%rsp), %rax
movq (%rax,%rbp,8), %r12
movq %r13, 0x50(%rsp)
movq %r15, %rdi
leaq 0xa4dde(%rip), %rsi     # 0xdb5a1
movq %r14, %rdx
callq 0x39150
movq 0x50(%r12), %rdi
movq %r15, %rsi
callq 0x38e94
movq 0x50(%r12), %rcx
addq $0x8, %rcx
cmpq %rcx, %rax
je 0x367ec
movq 0x40(%rax), %rbx
jmp 0x367ee
xorl %ebx, %ebx
movq 0x50(%rsp), %rdi
cmpq %r13, %rdi
je 0x36805
movq 0x60(%rsp), %rsi
incq %rsi
callq 0x218e0
testq %rbx, %rbx
je 0x3682a
cmpb $0x30, (%rbx)
jne 0x3682a
cmpb $0x0, 0x1(%rbx)
jne 0x3682a
movq %r12, %rdi
callq 0x3b862
movl $0x1b0, %esi            # imm = 0x1B0
movq %r12, %rdi
callq 0x218e0
incq %rbp
movslq 0x14(%rsp), %rax
cmpq %rax, %rbp
jl 0x367ab
leaq 0x8(%rsp), %rdi
callq 0x875f6
movl $0x1, %ebx
jmp 0x3686e
leaq 0xa4d22(%rip), %rdi     # 0xdb575
xorl %ebx, %ebx
movl %r12d, %esi
movq 0x30(%rsp), %rdx
xorl %eax, %eax
callq 0x8a0fe
leaq 0x8(%rsp), %rdi
callq 0x875f6
leaq 0x18(%rsp), %rdi
callq 0x875f6
movl %ebx, %eax
addq $0x2458, %rsp           # imm = 0x2458
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x368bf
jmp 0x368b6
jmp 0x368b6
jmp 0x368b6
jmp 0x368bf
movq %rax, %rbx
movq 0x50(%rsp), %rdi
cmpq %r13, %rdi
je 0x368c2
movq 0x60(%rsp), %rsi
incq %rsi
callq 0x218e0
jmp 0x368c2
jmp 0x368bf
jmp 0x368bf
movq %rax, %rbx
jmp 0x368cc
jmp 0x368bf
jmp 0x368bf
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
callq 0x875f6
leaq 0x18(%rsp), %rdi
callq 0x875f6
movq %rbx, %rdi
callq 0x220c0