// File: /workspace/github_cpp_makefile_star2_O1/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, %rbx
movq %rdi, %rbp
leaq 0xac8c1(%rip), %rsi     # 0xe3043
movq %rbx, %rdi
callq 0x21ac0
testq %rax, %rax
je 0x36848
movq %rax, %r14
leaq 0x10(%rsp), %rdi
callq 0x886bc
leaq 0x1450(%rsp), %rdi
movl $0x1000, %esi           # imm = 0x1000
movq %r14, 0x20(%rsp)
movq %r14, %rdx
callq 0x21f40
testq %rax, %rax
je 0x3680a
leaq 0xa6d5e(%rip), %rsi     # 0xdd524
leaq 0x1450(%rsp), %rdi
callq 0x21f00
testq %rax, %rax
je 0x3680a
leaq 0x10(%rsp), %r14
leaq 0xa6d40(%rip), %r15     # 0xdd524
movq %rax, %rdi
callq 0x8b397
movl 0x1c(%rsp), %edx
movq %r14, %rdi
movq %rax, %rsi
callq 0x88752
xorl %edi, %edi
movq %r15, %rsi
callq 0x21f00
testq %rax, %rax
jne 0x367e4
movq %rbx, 0x30(%rsp)
movslq 0x1c(%rsp), %r15
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
testq %r15, %r15
jle 0x36863
movq 0x10(%rsp), %r13
xorl %r12d, %r12d
leaq 0xa6cfb(%rip), %r14     # 0xdd528
movq (%r13,%r12,8), %rdi
movq %r14, %rsi
callq 0x21d10
testl %eax, %eax
je 0x36860
incq %r12
cmpq %r12, %r15
jne 0x3682d
jmp 0x36863
leaq 0xa6af6(%rip), %rdi     # 0xdd345
movq %rbx, %rsi
xorl %ebx, %ebx
xorl %eax, %eax
callq 0x8b53a
jmp 0x36c8d
movl %r12d, %ebx
testl %ebx, %ebx
js 0x36c65
leaq 0x450(%rsp), %rdi
movl $0x1000, %esi           # imm = 0x1000
movq 0x20(%rsp), %rdx
callq 0x21f40
testq %rax, %rax
je 0x36b66
movl %ebx, %eax
movq %rax, 0x38(%rsp)
movl $0x1, %r15d
movq %rsp, %rbx
leaq 0xa6c82(%rip), %r12     # 0xdd524
leaq 0x50(%rsp), %r14
movq %rbp, 0x40(%rsp)
movq %rbx, %rdi
callq 0x886bc
leaq 0x450(%rsp), %rdi
movq %r12, %rsi
callq 0x21f00
testq %rax, %rax
je 0x368e4
movq %rax, %rdi
callq 0x8b397
movl 0xc(%rsp), %edx
movq %rbx, %rdi
movq %rax, %rsi
callq 0x88752
xorl %edi, %edi
jmp 0x368bc
incl %r15d
movl 0xc(%rsp), %eax
movl $0x7, %ebx
testl %eax, %eax
movl %r15d, 0x2c(%rsp)
je 0x36b29
cmpl 0x1c(%rsp), %eax
jne 0x36b0e
movq (%rsp), %rax
movq 0x38(%rsp), %rcx
movq (%rax,%rcx,8), %r15
testq %r15, %r15
je 0x36b29
movq %r15, %rdi
callq 0x21380
testl %eax, %eax
je 0x36b29
cmpl $0x0, 0x14(%rbp)
jle 0x36ac0
xorl %ecx, %ecx
movq 0x8(%rbp), %rax
movq %rcx, 0x48(%rsp)
movq (%rax,%rcx,8), %rbp
cmpq $0x0, 0x1a0(%rbp)
je 0x369cf
movq 0x1a0(%rbp), %rsi
movl $0x3ff, %edx            # imm = 0x3FF
movq %r14, %rdi
callq 0x21430
movq %r14, %rdi
movl $0x23, %esi
callq 0x21330
movq %r14, %rbx
testq %rax, %rax
je 0x36982
movb $0x0, (%rax)
incq %rax
movq %rax, %rbx
movq %r14, %rdi
movq %r15, %rsi
callq 0x21d10
testl %eax, %eax
je 0x369a0
movq %rbx, %rdi
movq %r15, %rsi
callq 0x21d10
testl %eax, %eax
jne 0x369cf
cmpl $0x0, 0x1c(%rsp)
jle 0x369cf
xorl %ebx, %ebx
movq 0x10(%rsp), %rax
movq (%rax,%rbx,8), %rsi
movq (%rsp), %rax
movq (%rax,%rbx,8), %rdx
movq %rbp, %rdi
callq 0x3cf00
incq %rbx
movslq 0x1c(%rsp), %rax
cmpq %rax, %rbx
jl 0x369a9
cmpl $0x0, 0x4c(%rbp)
jle 0x36a9f
xorl %r12d, %r12d
movq 0x40(%rbp), %rax
movq (%rax,%r12,8), %rax
movq (%rax), %rax
movq (%rax), %rax
cmpq $0x0, 0x1a0(%rax)
je 0x36a81
movq 0x1a0(%rax), %rsi
movl $0x3ff, %edx            # imm = 0x3FF
movq %r14, %rdi
callq 0x21430
movq %r14, %rdi
movl $0x23, %esi
callq 0x21330
movq %r14, %rbx
testq %rax, %rax
je 0x36a2a
movb $0x0, (%rax)
incq %rax
movq %rax, %rbx
movq %r14, %rdi
movq %r15, %rsi
callq 0x21d10
testl %eax, %eax
je 0x36a4a
movq %rbx, %rdi
movq %r15, %rsi
callq 0x21d10
xorl %ebx, %ebx
testl %eax, %eax
jne 0x36a86
movl $0x11, %ebx
cmpl $0x0, 0x1c(%rsp)
jle 0x36a86
xorl %r13d, %r13d
movq 0x10(%rsp), %rax
movq (%rax,%r13,8), %rsi
movq (%rsp), %rax
movq (%rax,%r13,8), %rdx
movq %rbp, %rdi
callq 0x3cf00
incq %r13
movslq 0x1c(%rsp), %rax
cmpq %rax, %r13
jl 0x36a59
jmp 0x36a86
movl $0x13, %ebx
cmpl $0x13, %ebx
je 0x36a8f
testl %ebx, %ebx
jne 0x36a9f
incq %r12
movslq 0x4c(%rbp), %rax
cmpq %rax, %r12
jl 0x369dc
movq 0x48(%rsp), %rcx
incq %rcx
movq 0x40(%rsp), %rbp
movslq 0x14(%rbp), %rax
cmpq %rax, %rcx
leaq 0xa6a6a(%rip), %r12     # 0xdd524
jl 0x36939
movq %rbp, %rdi
movq %r15, %rsi
callq 0x286f0
xorl %ebx, %ebx
testq %rax, %rax
je 0x36b29
cmpl $0x0, 0x1c(%rsp)
jle 0x36b29
movq %rax, %r15
xorl %r12d, %r12d
movq (%r15), %rdi
movq 0x10(%rsp), %rax
movq (%rax,%r12,8), %rsi
movq (%rsp), %rax
movq (%rax,%r12,8), %rdx
callq 0x3cf00
incq %r12
movslq 0x1c(%rsp), %rax
cmpq %rax, %r12
jl 0x36adf
leaq 0xa6a18(%rip), %r12     # 0xdd524
jmp 0x36b29
movl $0x1, %ebx
leaq 0xa6a4b(%rip), %rdi     # 0xdd565
movl %r15d, %esi
movq 0x30(%rsp), %rdx
xorl %eax, %eax
callq 0x8b53a
movq %rsp, %rdi
callq 0x88726
cmpl $0x7, %ebx
je 0x36b3e
testl %ebx, %ebx
jne 0x36c81
leaq 0x450(%rsp), %rdi
movl $0x1000, %esi           # imm = 0x1000
movq 0x20(%rsp), %rdx
callq 0x21f40
testq %rax, %rax
movl 0x2c(%rsp), %r15d
movq %rsp, %rbx
jne 0x368ac
movq 0x20(%rsp), %rdi
callq 0x218b0
movq %rsp, %rdi
callq 0x886bc
cmpl $0x0, 0x14(%rbp)
jle 0x36ba3
xorl %ebx, %ebx
movq %rsp, %r14
movq 0x8(%rbp), %rax
movq (%rax,%rbx,8), %rsi
movl 0xc(%rsp), %edx
movq %r14, %rdi
callq 0x88752
incq %rbx
movslq 0x14(%rbp), %rax
cmpq %rax, %rbx
jl 0x36b83
cmpl $0x0, 0xc(%rsp)
jle 0x36c56
leaq 0x60(%rsp), %r12
xorl %ebx, %ebx
leaq 0xa69db(%rip), %r14     # 0xdd597
leaq 0x50(%rsp), %r15
movq (%rsp), %rax
movq (%rax,%rbx,8), %r13
movq %r12, 0x50(%rsp)
movq %r15, %rdi
leaq 0xa69b9(%rip), %rsi     # 0xdd591
movq %r14, %rdx
callq 0x395ec
movq 0x50(%r13), %rdi
movq %r15, %rsi
callq 0x39326
movq 0x50(%r13), %rcx
addq $0x8, %rcx
cmpq %rcx, %rax
je 0x36bff
movq 0x40(%rax), %rbp
jmp 0x36c01
xorl %ebp, %ebp
movq 0x50(%rsp), %rdi
cmpq %r12, %rdi
je 0x36c18
movq 0x60(%rsp), %rsi
incq %rsi
callq 0x218e0
testq %rbp, %rbp
je 0x36c45
movq %rbp, %rdi
leaq 0xad250(%rip), %rsi     # 0xe3e77
callq 0x21d10
testl %eax, %eax
jne 0x36c45
movq %r13, %rdi
callq 0x3bdc0
movl $0x1b0, %esi            # imm = 0x1B0
movq %r13, %rdi
callq 0x218e0
incq %rbx
movslq 0xc(%rsp), %rax
cmpq %rax, %rbx
jl 0x36bc1
movq %rsp, %rdi
callq 0x88726
movl $0x1, %ebx
jmp 0x36c83
xorl %ebx, %ebx
leaq 0xa68c3(%rip), %rdi     # 0xdd531
movl $0x1, %esi
movq 0x30(%rsp), %rdx
xorl %eax, %eax
callq 0x8b53a
jmp 0x36c83
xorl %ebx, %ebx
leaq 0x10(%rsp), %rdi
callq 0x88726
movl %ebx, %eax
addq $0x2458, %rsp           # imm = 0x2458
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x36ccb
jmp 0x36ccb
jmp 0x36cd4
jmp 0x36ccb
jmp 0x36cd4
movq %rax, %rbx
movq 0x50(%rsp), %rdi
cmpq %r12, %rdi
je 0x36cd7
movq 0x60(%rsp), %rsi
incq %rsi
callq 0x218e0
jmp 0x36cd7
jmp 0x36cd4
jmp 0x36cd4
movq %rax, %rbx
jmp 0x36cdf
jmp 0x36cd4
jmp 0x36cd4
movq %rax, %rbx
movq %rsp, %rdi
callq 0x88726
leaq 0x10(%rsp), %rdi
callq 0x88726
movq %rbx, %rdi
callq 0x220d0