;;-*-Lisp-*-
(in-package goal)

;; name: mysql-nav-graph.gc
;; name in dgo: mysql-nav-graph
;; dgos: ENGINE, GAME

;; +++mysql-save-flag
(defenum mysql-save-flag
  :type uint32
  :bitfield #t
  (delete 1)
  (update 2)
  (insert 3)
  )
;; ---mysql-save-flag

;; +++nav-node-flag
(defenum nav-node-flag
  "This string value is stored in their SQL database"
  :type uint32
  :bitfield #t
  (visited 0)
  (blocked 1)
  (pedestrian 2)
  (selected 3)
  (hidden 4))
;; ---nav-node-flag

;; +++nav-directionality
(defenum nav-directionality
  :type uint32
  :bitfield #f
  (default 0)
  (directed 1)
  (bi_directional 2))
;; ---nav-directionality

;; +++nav-clock-mask
(defenum nav-clock-mask
  "This string value is stored in their SQL database"
  :type uint32
  :bitfield #t
  (phase-1 0)
  (phase-1a 1)
  (phase-2 2)
  (phase-2a 3)
  (phase-3 4)
  (phase-3a 5)
  (phase-4 6)
  (phase-4a 7))
;; ---nav-clock-mask

;; +++nav-clock-type
(defenum nav-clock-type
  "This string value is stored in their SQL database"
  :type uint32
  :bitfield #f
  (no-clock 0)
  (clock2 1)
  (clock3 2)
  (clock4 3))
;; ---nav-clock-mask

;; +++nav-minimap-edge-flag
(defenum nav-minimap-edge-flag
  "This string value is stored in their SQL database"
  :type int32
  :bitfield #t
  (pass-red 0)
  (pass-green 1)
  (pass-yellow 2)
  (pass-blue 3))
;; ---nav-minimap-edge-flag

(declare-type mysql-nav-edge structure)

;; og:ignore-form:defmethod mysql-nav-graph-method-19 mysql-nav-graph
;; og:ignore-form:defmethod exec-sql! mysql-nav-graph

;; DECOMP BEGINS

;; this file is debug only
(declare-file (debug))

(deftype mysql-nav-node (structure)
  ((mysql-save-flag   mysql-save-flag)
   (runtime-id        uint32)
   (temp-edge-list    (inline-array mysql-nav-edge))
   (level-node-index  int32)
   (cam-dist          float)
   (visible           symbol)
   (nav_node_id       uint32)
   (nav_graph_id      uint32)
   (position          vector  :inline)
   (level_name        symbol)
   (angle             float)
   (radius            float)
   (nav_node_flag     nav-node-flag)
   (nav_mesh_id       uint32)
   )
  :pack-me
  (:methods
    (exec-sql! (_type_) symbol)
    (temp-edge-size (_type_) int)
    )
  )


(deftype mysql-nav-node-array (inline-array-class)
  ((data  mysql-nav-node  :inline :dynamic)
   )
  )


(set! (-> mysql-nav-node-array heap-base) (the-as uint 80))

(deftype mysql-nav-edge (structure)
  ((mysql-save-flag    mysql-save-flag)
   (runtime-id         uint32)
   (runtime-node-id-1  int32)
   (runtime-node-id-2  int32)
   (temp-next-edge     mysql-nav-edge)
   (nav_edge_id        uint32)
   (nav_graph_id       uint32)
   (nav_node_id_1      uint32)
   (nav_node_id_2      uint32)
   (directionality     nav-directionality)
   (speed_limit        float)
   (density            float)
   (traffic_edge_flag  int32)
   (nav_clock_mask     nav-clock-mask)
   (nav_clock_type     nav-clock-type)
   (width              float)
   (minimap_edge_flag  nav-minimap-edge-flag)
   )
  :allow-misaligned
  (:methods
    (exec-sql! (_type_) symbol)
    )
  )


(deftype mysql-nav-edge-array (inline-array-class)
  ((data  mysql-nav-edge  :inline :dynamic)
   )
  )


(set! (-> mysql-nav-edge-array heap-base) (the-as uint 80))

(deftype mysql-nav-visnode (structure)
  ((mysql-save-flag  mysql-save-flag)
   (runtime-node-id  int32)
   (runtime-edge-id  int32)
   (nav_visnode_id   uint32)
   (nav_graph_id     uint32)
   (nav_node_id      uint32)
   (nav_edge_id      uint32)
   )
  (:methods
    (exec-sql! (_type_) symbol)
    )
  )


(deftype mysql-nav-visnode-array (inline-array-class)
  ((data  mysql-nav-visnode  :inline :dynamic)
   )
  )


(set! (-> mysql-nav-visnode-array heap-base) (the-as uint 32))

(deftype mysql-nav-graph-level-info (structure)
  ((level          symbol)
   (level-id       uint32)
   (node-count     int32)
   (branch-count   int32)
   (to-link-count  int32)
   )
  :allow-misaligned
  )


(deftype mysql-nav-graph (basic)
  ((nav_graph_id             uint32)
   (node-array               mysql-nav-node-array)
   (edge-array               mysql-nav-edge-array)
   (visnode-array            mysql-nav-visnode-array)
   (level-info-array-length  int32)
   (level-info-last-lookup   int32)
   (level-info-array         mysql-nav-graph-level-info  32 :inline)
   )
  (:methods
    (new (symbol type string) _type_)
    (init-from-sql! (_type_ string string) symbol)
    (exec-sql! (_type_) symbol)
    (indexof-nav-node (_type_ int) int)
    (indexof-nav-edge (_type_ int) int)
    (alloc-new-node! (_type_) int)
    (alloc-new-edge! (_type_) int)
    (indexof-visnode (_type_ int int) int)
    (alloc-new-visnode! (_type_ int int) int)
    (mysql-nav-graph-method-17 (_type_) none)
    (lookup-level-info2 (_type_ mysql-nav-node symbol) mysql-nav-graph-level-info)
    (mysql-nav-graph-method-19 (_type_) none)
    (mysql-nav-graph-method-20 (_type_) none)
    )
  )


;; WARN: Return type mismatch object vs mysql-nav-graph.
(defmethod new mysql-nav-graph ((allocation symbol) (type-to-make type) (arg0 string))
  (let ((gp-0 (object-new allocation type-to-make (the-as int (-> type-to-make size)))))
    (if (zero? gp-0)
        (return (the-as mysql-nav-graph 0))
        )
    (set! (-> gp-0 node-array) (new 'debug 'mysql-nav-node-array 3000))
    (set! (-> gp-0 node-array length) 0)
    (set! (-> gp-0 edge-array) (new 'debug 'mysql-nav-edge-array 5000))
    (set! (-> gp-0 edge-array length) 0)
    (set! (-> gp-0 visnode-array) (new 'debug 'mysql-nav-visnode-array 3000))
    (set! (-> gp-0 visnode-array length) 0)
    (let ((s4-0 (clear *temp-string*)))
      (format *temp-string* "select nav_graph_id from nav_graph where name='~S'" arg0)
      (let ((a2-6 (sql-query s4-0)))
        (when (!= (-> a2-6 error) 'select)
          (format 0 "ERROR: sql: select error ~A for ~A~%" a2-6 gp-0)
          (return (the-as mysql-nav-graph #f))
          )
        (set! (-> gp-0 nav_graph_id) (the-as uint (string->int (-> a2-6 data 0))))
        )
      )
    gp-0
    )
  )

(defmethod alloc-new-node! ((this mysql-nav-graph))
  "Allocates a new `[[mysql-nav-node]]`, if `node-array`'s `length` exceeds `3000` return `-1`
otherwise, return the new size of the array"
  (cond
    ((>= (-> this node-array length) 3000)
     (format #t "mysql-nav-graph : nodes buffer too small, increase NAV_GRAPH_EDITOR_NODE_COUNT~%")
     -1
     )
    (else
      (let ((gp-0 (-> this node-array data (-> this node-array length)))
            (s5-0 (-> this node-array length))
            )
        (+! (-> this node-array length) 1)
        (set! (-> gp-0 mysql-save-flag) (mysql-save-flag))
        (logior! (-> gp-0 mysql-save-flag) (mysql-save-flag insert))
        (set! (-> gp-0 runtime-id) (the-as uint s5-0))
        (set! (-> gp-0 nav_graph_id) (-> this nav_graph_id))
        (set! (-> gp-0 level_name) (-> (level-get-target-inside *level*) name))
        s5-0
        )
      )
    )
  )

(defmethod alloc-new-edge! ((this mysql-nav-graph))
  "Allocates a new `[[mysql-nav-edge]]`, if `edge-array`'s `length` exceeds `5000` return `-1`
otherwise, return the new size of the array"
  (cond
    ((>= (-> this edge-array length) 5000)
     (format #t "mysql-nav-graph : edges buffer too small, increase NAV_GRAPH_EDITOR_EDGE_COUNT~%")
     -1
     )
    (else
      (let ((v1-5 (-> this edge-array data (-> this edge-array length)))
            (v0-1 (-> this edge-array length))
            )
        (+! (-> this edge-array length) 1)
        (set! (-> v1-5 mysql-save-flag) (mysql-save-flag))
        (logior! (-> v1-5 mysql-save-flag) (mysql-save-flag insert))
        (set! (-> v1-5 runtime-id) (the-as uint v0-1))
        (set! (-> v1-5 nav_graph_id) (-> this nav_graph_id))
        (set! (-> v1-5 directionality) (nav-directionality default))
        v0-1
        )
      )
    )
  )

(defmethod indexof-visnode ((this mysql-nav-graph) (edge-id int) (node-id int))
  "Returns the index in the `visnode-array` whom's [[mysql-nav-visnode]] has the provided `runtime-edge-id` and `runtime-node-id`
if none exist, return `-1`"
  (dotimes (v1-0 (-> this visnode-array length))
    (let ((a3-2 (-> this visnode-array data v1-0)))
      (if (and (= (-> a3-2 runtime-edge-id) edge-id) (= (-> a3-2 runtime-node-id) node-id))
          (return v1-0)
          )
      )
    )
  -1
  )

(defmethod alloc-new-visnode! ((this mysql-nav-graph) (edge-id int) (node-id int))
  "Potentially allocates a new `[[mysql-nav-visnode]]`:
- if `visnode-array`'s `length` exceeds `3000` return `-1`
- otherwise, if the node already exists, TODO
- if the node does not already exist, create it!"
  (cond
    ((>= (-> this visnode-array length) 3000)
     (format #t "mysql-nav-graph : visnodes buffer too small, increase NAV_GRAPH_EDITOR_VISNODE_COUNT~%")
     -1
     )
    (else
      (let ((v1-3 (indexof-visnode this edge-id node-id)))
        (when (>= v1-3 0)
          (logand!
            (-> (the-as mysql-nav-visnode (+ (the-as uint (-> this visnode-array)) (* v1-3 32))) nav_visnode_id)
            -3
            )
          (return v1-3)
          )
        )
      (let ((v1-9 (-> this visnode-array data (-> this visnode-array length)))
            (v0-1 (-> this visnode-array length))
            )
        (+! (-> this visnode-array length) 1)
        (set! (-> v1-9 mysql-save-flag) (mysql-save-flag))
        (logior! (-> v1-9 mysql-save-flag) (mysql-save-flag insert))
        (set! (-> v1-9 runtime-edge-id) edge-id)
        (set! (-> v1-9 runtime-node-id) node-id)
        (set! (-> v1-9 nav_graph_id) (-> this nav_graph_id))
        v0-1
        )
      )
    )
  )

(defmethod exec-sql! ((this mysql-nav-node))
  "Executes the respective SQL operation specified by `mysql-save-flag`, return value indicates success"
  (if (and (logtest? (-> this mysql-save-flag) (mysql-save-flag insert))
           (logtest? (-> this mysql-save-flag) (mysql-save-flag delete))
           )
      (return #t)
      )
  (if (and (logtest? (-> this mysql-save-flag) (mysql-save-flag insert))
           (logtest? (-> this mysql-save-flag) (mysql-save-flag update))
           )
      (logclear! (-> this mysql-save-flag) (mysql-save-flag update))
      )
  (let ((s5-0 (clear *temp-string*)))
    (case (-> this mysql-save-flag)
      (((mysql-save-flag insert))
       (format s5-0 "insert nav_node set ")
       )
      (((mysql-save-flag update))
       (format s5-0 "update nav_node set ")
       )
      (((mysql-save-flag delete))
       (format s5-0 "delete from nav_node where ")
       )
      )
    (case (-> this mysql-save-flag)
      ((8 4)
       (format s5-0 "nav_graph_id=~D," (-> this nav_graph_id))
       (format s5-0 "x=~M," (-> this position x))
       (format s5-0 "y=~M," (-> this position y))
       (format s5-0 "z=~M," (-> this position z))
       (format s5-0 "level_name='~S'," (-> this level_name))
       (format s5-0 "angle=~R," (-> this angle))
       (format s5-0 "radius=~M," (-> this radius))
       (format s5-0 "nav_node_flag='")
       (let ((v1-20 #t))
         (when (logtest? (-> this nav_node_flag) (nav-node-flag visited))
           (if (not v1-20)
               (format s5-0 ",")
               )
           (format s5-0 "visited")
           (set! v1-20 #f)
           )
         (when (logtest? (-> this nav_node_flag) (nav-node-flag blocked))
           (if (not v1-20)
               (format s5-0 ",")
               )
           (format s5-0 "blocked")
           (set! v1-20 #f)
           )
         (when (logtest? (-> this nav_node_flag) (nav-node-flag pedestrian))
           (if (not v1-20)
               (format s5-0 ",")
               )
           (format s5-0 "pedestrian")
           (set! v1-20 #f)
           )
         (when (logtest? (-> this nav_node_flag) (nav-node-flag selected))
           (if (not v1-20)
               (format s5-0 ",")
               )
           (format s5-0 "selected")
           (set! v1-20 #f)
           )
         (when (logtest? (-> this nav_node_flag) (nav-node-flag hidden))
           (if (not v1-20)
               (format s5-0 ",")
               )
           (format s5-0 "hidden")
           )
         )
       (format s5-0 "',")
       (format s5-0 "nav_mesh_id=~D" (-> this nav_mesh_id))
       (if (logtest? (-> this mysql-save-flag) (mysql-save-flag update))
           (format s5-0 " where nav_node_id=~D" (-> this nav_node_id))
           )
       (let ((a2-9 (sql-query s5-0)))
         (when (!= (-> a2-9 error) 'modify)
           (format 0 "ERROR: sql: modify error ~A for ~A~%" a2-9 this)
           (return #f)
           )
         )
       (when (logtest? (-> this mysql-save-flag) (mysql-save-flag insert))
         (let ((v1-40 (sql-query "select LAST_INSERT_ID()")))
           (if (= (-> v1-40 error) 'select)
               (set! (-> this nav_node_id) (the-as uint (string->int (-> v1-40 data 0))))
               )
           )
         )
       )
      (((mysql-save-flag delete))
       (format s5-0 "nav_node_id=~D" (-> this nav_node_id))
       (let ((a2-11 (sql-query s5-0)))
         (when (!= (-> a2-11 error) 'modify)
           (format 0 "ERROR: sql: modify error ~A for ~A~%" a2-11 this)
           (return #f)
           )
         )
       )
      )
    )
  (logclear! (-> this mysql-save-flag) (mysql-save-flag insert))
  (logclear! (-> this mysql-save-flag) (mysql-save-flag update))
  #t
  )

(defmethod exec-sql! ((this mysql-nav-edge))
  "Executes the respective SQL operation specified by `mysql-save-flag`, return value indicates success"
  (if (and (logtest? (-> this mysql-save-flag) (mysql-save-flag insert))
           (logtest? (-> this mysql-save-flag) (mysql-save-flag delete))
           )
      (return #t)
      )
  (if (and (logtest? (-> this mysql-save-flag) (mysql-save-flag insert))
           (logtest? (-> this mysql-save-flag) (mysql-save-flag update))
           )
      (logclear! (-> this mysql-save-flag) (mysql-save-flag update))
      )
  (let ((s5-0 (clear *temp-string*)))
    (case (-> this mysql-save-flag)
      (((mysql-save-flag insert))
       (format s5-0 "insert nav_edge set ")
       )
      (((mysql-save-flag update))
       (format s5-0 "update nav_edge set ")
       )
      (((mysql-save-flag delete))
       (format s5-0 "delete from nav_edge where ")
       )
      )
    (case (-> this mysql-save-flag)
      ((8 4)
       (format s5-0 "nav_graph_id=~D," (-> this nav_graph_id))
       (format s5-0 "nav_node_id_1=~D," (-> this nav_node_id_1))
       (format s5-0 "nav_node_id_2=~D," (-> this nav_node_id_2))
       (let ((t9-7 format)
             (a0-21 s5-0)
             (a1-8 "directionality='~S',")
             (v1-20 (-> this directionality))
             )
         (t9-7 a0-21 a1-8 (cond
                            ((= v1-20 (nav-directionality directed))
                             "directed"
                             )
                            ((= v1-20 (nav-directionality bi_directional))
                             "bi_directional"
                             )
                            (else
                              "default"
                              )
                            )
               )
         )
       (format s5-0 "speed_limit=~M," (-> this speed_limit))
       (format s5-0 "density=~F," (-> this density))
       (format s5-0 "traffic_edge_flag='")
       (let ((v1-21 #t))
         (when (logtest? (-> this traffic_edge_flag) 1)
           (if (not v1-21)
               (format s5-0 ",")
               )
           (format s5-0 "pedestrian")
           )
         )
       (format s5-0 "',")
       (format s5-0 "nav_clock_mask='")
       (let ((v1-24 #t))
         (when (logtest? (-> this nav_clock_mask) (nav-clock-mask phase-1))
           (if (not v1-24)
               (format s5-0 ",")
               )
           (format s5-0 "phase-1")
           (set! v1-24 #f)
           )
         (when (logtest? (-> this nav_clock_mask) (nav-clock-mask phase-1a))
           (if (not v1-24)
               (format s5-0 ",")
               )
           (format s5-0 "phase-1a")
           (set! v1-24 #f)
           )
         (when (logtest? (-> this nav_clock_mask) (nav-clock-mask phase-2))
           (if (not v1-24)
               (format s5-0 ",")
               )
           (format s5-0 "phase-2")
           (set! v1-24 #f)
           )
         (when (logtest? (-> this nav_clock_mask) (nav-clock-mask phase-2a))
           (if (not v1-24)
               (format s5-0 ",")
               )
           (format s5-0 "phase-2a")
           (set! v1-24 #f)
           )
         (when (logtest? (-> this nav_clock_mask) (nav-clock-mask phase-3))
           (if (not v1-24)
               (format s5-0 ",")
               )
           (format s5-0 "phase-3")
           (set! v1-24 #f)
           )
         (when (logtest? (-> this nav_clock_mask) (nav-clock-mask phase-3a))
           (if (not v1-24)
               (format s5-0 ",")
               )
           (format s5-0 "phase-3a")
           (set! v1-24 #f)
           )
         (when (logtest? (-> this nav_clock_mask) (nav-clock-mask phase-4))
           (if (not v1-24)
               (format s5-0 ",")
               )
           (format s5-0 "phase-4")
           (set! v1-24 #f)
           )
         (when (logtest? (-> this nav_clock_mask) (nav-clock-mask phase-4a))
           (if (not v1-24)
               (format s5-0 ",")
               )
           (format s5-0 "phase-4a")
           )
         )
       (format s5-0 "',")
       (let ((t9-32 format)
             (a0-82 s5-0)
             (a1-33 "nav_clock_type='~S',")
             (v1-41 (-> this nav_clock_type))
             )
         (t9-32 a0-82 a1-33 (cond
                              ((= v1-41 (nav-clock-type clock2))
                               "clock2"
                               )
                              ((= v1-41 (nav-clock-type clock3))
                               "clock3"
                               )
                              ((= v1-41 (nav-clock-type clock4))
                               "clock4"
                               )
                              (else
                                "no-clock"
                                )
                              )
                )
         )
       (format s5-0 "width=~M," (-> this width))
       (format s5-0 "minimap_edge_flag='")
       (let ((v1-42 #t))
         (when (logtest? (-> this minimap_edge_flag) (nav-minimap-edge-flag pass-red))
           (if (not v1-42)
               (format s5-0 ",")
               )
           (format s5-0 "pass-red")
           (set! v1-42 #f)
           )
         (when (logtest? (-> this minimap_edge_flag) (nav-minimap-edge-flag pass-green))
           (if (not v1-42)
               (format s5-0 ",")
               )
           (format s5-0 "pass-green")
           (set! v1-42 #f)
           )
         (when (logtest? (-> this minimap_edge_flag) (nav-minimap-edge-flag pass-yellow))
           (if (not v1-42)
               (format s5-0 ",")
               )
           (format s5-0 "pass-yellow")
           (set! v1-42 #f)
           )
         (when (logtest? (-> this minimap_edge_flag) (nav-minimap-edge-flag pass-blue))
           (if (not v1-42)
               (format s5-0 ",")
               )
           (format s5-0 "pass-blue")
           )
         )
       (format s5-0 "'")
       (if (logtest? (-> this mysql-save-flag) (mysql-save-flag update))
           (format s5-0 " where nav_edge_id=~D" (-> this nav_edge_id))
           )
       (let ((a2-14 (sql-query s5-0)))
         (when (!= (-> a2-14 error) 'modify)
           (format 0 "ERROR: sql: modify error ~A for ~A~%" a2-14 this)
           (return #f)
           )
         )
       (when (logtest? (-> this mysql-save-flag) (mysql-save-flag insert))
         (let ((v1-60 (sql-query "select LAST_INSERT_ID()")))
           (if (= (-> v1-60 error) 'select)
               (set! (-> this nav_edge_id) (the-as uint (string->int (-> v1-60 data 0))))
               )
           )
         )
       )
      (((mysql-save-flag delete))
       (format s5-0 "nav_edge_id=~D" (-> this nav_edge_id))
       (let ((a2-16 (sql-query s5-0)))
         (when (!= (-> a2-16 error) 'modify)
           (format 0 "ERROR: sql: modify error ~A for ~A~%" a2-16 this)
           (return #f)
           )
         )
       )
      )
    )
  (logclear! (-> this mysql-save-flag) (mysql-save-flag insert))
  (logclear! (-> this mysql-save-flag) (mysql-save-flag update))
  #t
  )

(defmethod exec-sql! ((this mysql-nav-visnode))
  "Executes the respective SQL operation specified by `mysql-save-flag`, return value indicates success"
  (if (and (logtest? (-> this mysql-save-flag) (mysql-save-flag insert))
           (logtest? (-> this mysql-save-flag) (mysql-save-flag delete))
           )
      (return #t)
      )
  (if (and (logtest? (-> this mysql-save-flag) (mysql-save-flag insert))
           (logtest? (-> this mysql-save-flag) (mysql-save-flag update))
           )
      (logclear! (-> this mysql-save-flag) (mysql-save-flag update))
      )
  (let ((s5-0 (clear *temp-string*)))
    (case (-> this mysql-save-flag)
      (((mysql-save-flag insert))
       (format s5-0 "insert nav_visible_nodes set ")
       )
      (((mysql-save-flag update))
       (format s5-0 "update nav_visible_nodes set ")
       )
      (((mysql-save-flag delete))
       (format s5-0 "delete from nav_visible_nodes where ")
       )
      )
    (case (-> this mysql-save-flag)
      ((8 4)
       (format s5-0 "nav_graph_id=~D," (-> this nav_graph_id))
       (format s5-0 "nav_edge_id=~D," (-> this nav_edge_id))
       (format s5-0 "nav_node_id=~D" (-> this nav_node_id))
       (let ((a2-3 (sql-query s5-0)))
         (when (!= (-> a2-3 error) 'modify)
           (format 0 "ERROR: sql: modify error ~A for ~A~%" a2-3 this)
           (return #f)
           )
         )
       )
      (((mysql-save-flag delete))
       (format s5-0 "nav_graph_id=~D and " (-> this nav_graph_id))
       (format s5-0 "nav_edge_id=~D and " (-> this nav_edge_id))
       (format s5-0 "nav_node_id=~D" (-> this nav_node_id))
       (let ((a2-7 (sql-query s5-0)))
         (when (!= (-> a2-7 error) 'modify)
           (format 0 "ERROR: sql: modify error ~A for ~A~%" a2-7 this)
           (return #f)
           )
         )
       )
      )
    )
  (logclear! (-> this mysql-save-flag) (mysql-save-flag insert))
  (logclear! (-> this mysql-save-flag) (mysql-save-flag update))
  #t
  )

(defmethod indexof-nav-node ((this mysql-nav-graph) (node-id int))
  "Iterate through the `node-array` and return the index for the first [[mysql-nav-node]] whom's `nav_node_id` matches the provided id
returns `-1` if none is found"
  (dotimes (v1-0 (-> this node-array length))
    (if (= node-id (-> (the-as mysql-nav-node (-> this node-array data v1-0)) nav_node_id))
        (return v1-0)
        )
    )
  -1
  )

(defmethod indexof-nav-edge ((this mysql-nav-graph) (edge-id int))
  "Iterate through the `edge-array` and return the index for the first [[mysql-nav-edge]] whom's `nav_edge_id` matches the provided id
returns `-1` if none is found"
  (dotimes (v1-0 (-> this edge-array length))
    (if (= edge-id (-> (the-as mysql-nav-edge (-> this edge-array data v1-0)) nav_edge_id))
        (return v1-0)
        )
    )
  -1
  )

;; WARN: new jak 2 until loop case, check carefully
;; WARN: new jak 2 until loop case, check carefully
;; WARN: new jak 2 until loop case, check carefully
;; WARN: new jak 2 until loop case, check carefully
;; WARN: new jak 2 until loop case, check carefully
;; WARN: new jak 2 until loop case, check carefully
;; WARN: new jak 2 until loop case, check carefully
(defmethod init-from-sql! ((this mysql-nav-graph) (arg0 string) (arg1 string))
  "Query the database and initialize the [[mysql-nav-graph]] and all it's related components"
  (local-vars (sv-16 string) (sv-32 int) (sv-48 int) (sv-64 int))
  (set! (-> this node-array length) 0)
  (set! (-> this edge-array length) 0)
  (set! (-> this visnode-array length) 0)
  (let ((s3-0 (clear *temp-string*)))
    (format s3-0 "select nav_graph_id from nav_graph where name='~S'" arg0)
    (let ((a2-2 (sql-query s3-0)))
      (when (!= (-> a2-2 error) 'select)
        (format 0 "ERROR: sql: select error ~A for ~A~%" a2-2 this)
        (return #f)
        )
      (set! (-> this nav_graph_id) (the-as uint (string->int (-> a2-2 data 0))))
      )
    )
  (format #t "Loading nodes ...~%")
  (let ((s4-1 0)
        (s3-1 256)
        )
    (until #f
      (let ((s2-0 (clear *temp-string*)))
        (format
          s2-0
          "select nav_node_id,x,y,z,level_name,angle,radius,nav_node_flag,nav_mesh_id,nav_graph_id from nav_node"
          )
        (if arg1
            (format s2-0 " where level_name='~S'" arg1)
            )
        (format s2-0 " limit ~D,~D" s4-1 s3-1)
        (let ((s2-1 (sql-query s2-0)))
          (when (!= (-> s2-1 error) 'select)
            (format 0 "ERROR: sql: select error ~A for ~A~%" s2-1 this)
            (return #f)
            )
          (let ((s1-0 0))
            (while (< s1-0 (-> s2-1 len))
              (when (= (string->int (-> s2-1 data (+ s1-0 9))) (-> this nav_graph_id))
                (let ((nav-node (-> this node-array data (-> this node-array length))))
                  (set! (-> nav-node mysql-save-flag) (mysql-save-flag))
                  (set! (-> nav-node runtime-id) (the-as uint (-> this node-array length)))
                  (set! (-> nav-node nav_graph_id) (-> this nav_graph_id))
                  (set! (-> nav-node nav_node_id) (the-as uint (string->int (-> s2-1 data s1-0))))
                  (set! (-> nav-node position x) (* 4096.0 (string->float (-> s2-1 data (+ s1-0 1)))))
                  (set! (-> nav-node position y) (* 4096.0 (string->float (-> s2-1 data (+ s1-0 2)))))
                  (set! (-> nav-node position z) (* 4096.0 (string->float (-> s2-1 data (+ s1-0 3)))))
                  (set! (-> nav-node level_name) (string->symbol (-> s2-1 data (+ s1-0 4))))
                  (set! (-> nav-node angle) (* 182.04445 (string->float (-> s2-1 data (+ s1-0 5)))))
                  (set! (-> nav-node radius) (* 4096.0 (string->float (-> s2-1 data (+ s1-0 6)))))
                  (set! (-> nav-node nav_node_flag) (nav-node-flag))
                  (set! sv-16 (new 'global 'string 0 (-> s2-1 data (+ s1-0 7))))
                  (copy-string<-string sv-16 (-> s2-1 data (+ s1-0 7)))
                  (until #f
                    (cond
                      ((string-prefix= "visited" sv-16)
                       (logior! (-> nav-node nav_node_flag) (nav-node-flag visited))
                       )
                      ((string-prefix= "blocked" sv-16)
                       (logior! (-> nav-node nav_node_flag) (nav-node-flag blocked))
                       )
                      ((string-prefix= "pedestrian" sv-16)
                       (logior! (-> nav-node nav_node_flag) (nav-node-flag pedestrian))
                       )
                      ((string-prefix= "selected" sv-16)
                       (logior! (-> nav-node nav_node_flag) (nav-node-flag selected))
                       )
                      ((string-prefix= "hidden" sv-16)
                       (logior! (-> nav-node nav_node_flag) (nav-node-flag hidden))
                       )
                      (else
                        #t
                        (goto cfg-27)
                        )
                      )
                    (let ((a1-16 (string-skip-to-char (-> sv-16 data) (the-as uint 44))))
                      (if (= (-> a1-16 0) 44)
                          (set! a1-16 (&-> a1-16 1))
                          )
                      (string-suck-up! sv-16 a1-16)
                      )
                    )
                  #f
                  (label cfg-27)
                  (set! (-> nav-node nav_mesh_id) (the-as uint (string->int (-> s2-1 data (+ s1-0 8)))))
                  )
                (+! (-> this node-array length) 1)
                )
              (+! s1-0 10)
              )
            )
          (when (< (-> s2-1 len) (* 10 s3-1))
            #t
            (goto cfg-34)
            )
          )
        )
      (+! s4-1 s3-1)
      )
    )
  #f
  (label cfg-34)
  (format #t "~D nodes.~%" (-> this node-array length))
  (format #t "Loading edges ...~%")
  (let ((s5-1 0)
        (s4-2 256)
        )
    (until #f
      (let ((s3-2 (clear *temp-string*)))
        (format
          s3-2
          "select nav_edge_id,nav_node_id_1,nav_node_id_2,directionality,speed_limit,density,traffic_edge_flag,nav_clock_mask,nav_clock_type,width,minimap_edge_flag,nav_graph_id from nav_edge limit ~D,~D"
          s5-1
          s4-2
          )
        (let ((s3-3 (sql-query s3-2)))
          (when (!= (-> s3-3 error) 'select)
            (format 0 "ERROR: sql: select error ~A for ~A~%" s3-3 this)
            (return #f)
            )
          (let ((s2-2 0))
            (while (< s2-2 (-> s3-3 len))
              (when (= (string->int (-> s3-3 data (+ s2-2 11))) (-> this nav_graph_id))
                (let ((s0-2 (string->int (-> s3-3 data (+ s2-2 1)))))
                  (set! sv-32 (string->int (-> s3-3 data (+ s2-2 2))))
                  (set! sv-48 (indexof-nav-node this s0-2))
                  (set! sv-64 (indexof-nav-node this sv-32))
                  (let ((nav-edge (-> this edge-array data (-> this edge-array length))))
                    (when (and (!= sv-48 -1) (!= sv-64 -1))
                      (set! (-> nav-edge nav_graph_id) (-> this nav_graph_id))
                      (set! (-> nav-edge nav_edge_id) (the-as uint (string->int (-> s3-3 data s2-2))))
                      (set! (-> nav-edge nav_node_id_1) (the-as uint s0-2))
                      (set! (-> nav-edge nav_node_id_2) (the-as uint sv-32))
                      (set! (-> nav-edge mysql-save-flag) (mysql-save-flag))
                      (set! (-> nav-edge runtime-id) (the-as uint (-> this edge-array length)))
                      (set! (-> nav-edge runtime-node-id-1) sv-48)
                      (set! (-> nav-edge runtime-node-id-2) sv-64)
                      (let ((s0-3 (-> s3-3 data (+ s2-2 3))))
                        (cond
                          ((string= "default" s0-3)
                           (set! (-> nav-edge directionality) (nav-directionality default))
                           0
                           )
                          ((string= "directed" s0-3)
                           (set! (-> nav-edge directionality) (nav-directionality directed))
                           )
                          ((string= "bi_directional" s0-3)
                           (set! (-> nav-edge directionality) (nav-directionality bi_directional))
                           )
                          )
                        )
                      (set! (-> nav-edge speed_limit) (* 4096.0 (string->float (-> s3-3 data (+ s2-2 4)))))
                      (set! (-> nav-edge density) (string->float (-> s3-3 data (+ s2-2 5))))
                      (set! (-> nav-edge traffic_edge_flag) 0)
                      (let ((s0-4 (new 'global 'string 0 (-> s3-3 data (+ s2-2 6)))))
                        (copy-string<-string s0-4 (-> s3-3 data (+ s2-2 6)))
                        (until #f
                          (cond
                            ((string-prefix= "pedestrian" s0-4)
                             (logior! (-> nav-edge traffic_edge_flag) 1)
                             )
                            (else
                              #t
                              (goto cfg-58)
                              )
                            )
                          (let ((a1-30 (string-skip-to-char (-> s0-4 data) (the-as uint 44))))
                            (if (= (-> a1-30 0) 44)
                                (set! a1-30 (&-> a1-30 1))
                                )
                            (string-suck-up! s0-4 a1-30)
                            )
                          )
                        )
                      #f
                      (label cfg-58)
                      (set! (-> nav-edge nav_clock_mask) (nav-clock-mask))
                      (let ((s0-5 (new 'global 'string 0 (-> s3-3 data (+ s2-2 7)))))
                        (copy-string<-string s0-5 (-> s3-3 data (+ s2-2 7)))
                        (until #f
                          (cond
                            ((string-prefix= "phase-1a" s0-5)
                             (logior! (-> nav-edge nav_clock_mask) (nav-clock-mask phase-1a))
                             )
                            ((string-prefix= "phase-1" s0-5)
                             (logior! (-> nav-edge nav_clock_mask) (nav-clock-mask phase-1))
                             )
                            ((string-prefix= "phase-2a" s0-5)
                             (logior! (-> nav-edge nav_clock_mask) (nav-clock-mask phase-2a))
                             )
                            ((string-prefix= "phase-2" s0-5)
                             (logior! (-> nav-edge nav_clock_mask) (nav-clock-mask phase-2))
                             )
                            ((string-prefix= "phase-3a" s0-5)
                             (logior! (-> nav-edge nav_clock_mask) (nav-clock-mask phase-3a))
                             )
                            ((string-prefix= "phase-3" s0-5)
                             (logior! (-> nav-edge nav_clock_mask) (nav-clock-mask phase-3))
                             )
                            ((string-prefix= "phase-4a" s0-5)
                             (logior! (-> nav-edge nav_clock_mask) (nav-clock-mask phase-4a))
                             )
                            ((string-prefix= "phase-4" s0-5)
                             (logior! (-> nav-edge nav_clock_mask) (nav-clock-mask phase-4))
                             )
                            (else
                              #t
                              (goto cfg-80)
                              )
                            )
                          (let ((a1-42 (string-skip-to-char (-> s0-5 data) (the-as uint 44))))
                            (if (= (-> a1-42 0) 44)
                                (set! a1-42 (&-> a1-42 1))
                                )
                            (string-suck-up! s0-5 a1-42)
                            )
                          )
                        )
                      #f
                      (label cfg-80)
                      (let ((s0-6 (-> s3-3 data (+ s2-2 8))))
                        (cond
                          ((string= "no-clock" s0-6)
                           (set! (-> nav-edge nav_clock_type) (nav-clock-type no-clock))
                           0
                           )
                          ((string= "clock2" s0-6)
                           (set! (-> nav-edge nav_clock_type) (nav-clock-type clock2))
                           )
                          ((string= "clock3" s0-6)
                           (set! (-> nav-edge nav_clock_type) (nav-clock-type clock3))
                           )
                          ((string= "clock4" s0-6)
                           (set! (-> nav-edge nav_clock_type) (nav-clock-type clock4))
                           )
                          )
                        )
                      (set! (-> nav-edge width) (* 4096.0 (string->float (-> s3-3 data (+ s2-2 9)))))
                      (set! (-> nav-edge minimap_edge_flag) (nav-minimap-edge-flag))
                      (let ((s0-7 (new 'global 'string 0 (-> s3-3 data (+ s2-2 10)))))
                        (copy-string<-string s0-7 (-> s3-3 data (+ s2-2 10)))
                        (until #f
                          (cond
                            ((string-prefix= "pass-red" s0-7)
                             (logior! (-> nav-edge minimap_edge_flag) (nav-minimap-edge-flag pass-red))
                             )
                            ((string-prefix= "pass-green" s0-7)
                             (logior! (-> nav-edge minimap_edge_flag) (nav-minimap-edge-flag pass-green))
                             )
                            ((string-prefix= "pass-yellow" s0-7)
                             (logior! (-> nav-edge minimap_edge_flag) (nav-minimap-edge-flag pass-yellow))
                             )
                            ((string-prefix= "pass-blue" s0-7)
                             (logior! (-> nav-edge minimap_edge_flag) (nav-minimap-edge-flag pass-blue))
                             )
                            (else
                              #t
                              (goto cfg-102)
                              )
                            )
                          (let ((a1-54 (string-skip-to-char (-> s0-7 data) (the-as uint 44))))
                            (if (= (-> a1-54 0) 44)
                                (set! a1-54 (&-> a1-54 1))
                                )
                            (string-suck-up! s0-7 a1-54)
                            )
                          )
                        )
                      #f
                      (label cfg-102)
                      (+! (-> this edge-array length) 1)
                      )
                    )
                  )
                )
              (+! s2-2 12)
              )
            )
          (when (< (-> s3-3 len) (* 12 s4-2))
            #t
            (goto cfg-109)
            )
          )
        )
      (+! s5-1 s4-2)
      )
    )
  #f
  (label cfg-109)
  (format #t "~D edges.~%" (-> this edge-array length))
  (format #t "Loading visnodes ...~%")
  (let ((s5-2 0)
        (s4-3 256)
        )
    (until #f
      (let ((s3-4 (clear *temp-string*)))
        (format s3-4 "select nav_edge_id,nav_node_id,nav_graph_id from nav_visible_nodes limit ~D,~D" s5-2 s4-3)
        (let ((s3-5 (sql-query s3-4)))
          (when (!= (-> s3-5 error) 'select)
            (format 0 "ERROR: sql: select error ~A for ~A~%" s3-5 this)
            (return #f)
            )
          (let ((s2-3 0))
            (while (< s2-3 (-> s3-5 len))
              (when (= (string->int (-> s3-5 data (+ s2-3 2))) (-> this nav_graph_id))
                (let ((nav-visnode (-> this visnode-array data (-> this visnode-array length))))
                  (set! (-> nav-visnode mysql-save-flag) (mysql-save-flag))
                  (set! (-> nav-visnode nav_graph_id) (-> this nav_graph_id))
                  (set! (-> nav-visnode nav_edge_id) (the-as uint (string->int (-> s3-5 data s2-3))))
                  (set! (-> nav-visnode nav_node_id) (the-as uint (string->int (-> s3-5 data (+ s2-3 1)))))
                  (set! (-> nav-visnode runtime-edge-id) (indexof-nav-edge this (the-as int (-> nav-visnode nav_edge_id))))
                  (set! (-> nav-visnode runtime-node-id) (indexof-nav-node this (the-as int (-> nav-visnode nav_node_id))))
                  )
                (+! (-> this visnode-array length) 1)
                )
              (+! s2-3 3)
              )
            )
          (when (< (-> s3-5 len) (* 3 s4-3))
            #t
            (goto cfg-122)
            )
          )
        )
      (+! s5-2 s4-3)
      )
    )
  #f
  (label cfg-122)
  (format #t "~D visnodes.~%" (-> this visnode-array length))
  #t
  )

(defmethod temp-edge-size ((this mysql-nav-node))
  "Returns the number of [[mysql-nav-edge]] stored in the `temp-edge-list`"
  (let ((v0-0 0))
    (let ((v1-0 (the-as object (-> this temp-edge-list))))
      (while v1-0
        (+! v0-0 1)
        (set! v1-0 (-> (the-as mysql-nav-edge v1-0) temp-next-edge))
        )
      )
    v0-0
    )
  )

(defmethod mysql-nav-graph-method-17 ((this mysql-nav-graph))
  (dotimes (v1-0 (-> this node-array length))
    (set! (-> (the-as mysql-nav-node (-> this node-array data v1-0)) temp-edge-list)
          (the-as (inline-array mysql-nav-edge) #f)
          )
    )
  (dotimes (v1-3 (-> this edge-array length))
    (set! (-> (the-as mysql-nav-edge (-> this edge-array data v1-3)) temp-next-edge) #f)
    )
  (countdown (v1-7 (-> this edge-array length))
    (let ((a1-17 (-> this edge-array data v1-7)))
      (when (not (logtest? (-> a1-17 mysql-save-flag) (mysql-save-flag delete)))
        (let ((a2-8 (-> this node-array data (-> a1-17 runtime-node-id-1))))
          (when (not (logtest? (-> a2-8 mysql-save-flag) (mysql-save-flag delete)))
            (cond
              ((-> a2-8 temp-edge-list)
               (set! (-> a1-17 temp-next-edge) (the-as mysql-nav-edge (-> a2-8 temp-edge-list)))
               (set! (-> a2-8 temp-edge-list) (the-as (inline-array mysql-nav-edge) a1-17))
               )
              (else
                (set! (-> a2-8 temp-edge-list) (the-as (inline-array mysql-nav-edge) a1-17))
                )
              )
            )
          )
        )
      )
    )
  0
  (none)
  )

(defmethod lookup-level-info2 ((this mysql-nav-graph) (arg0 mysql-nav-node) (arg1 symbol))
  "TODO - this was originally called `lookup-level-info` but it clashes with the function defined in `level`"
  (let ((s5-0 (the-as mysql-nav-graph-level-info #f)))
    (b! (>= (-> this level-info-last-lookup) (-> this level-info-array-length)) cfg-3 :delay #f)
    (let ((v1-5 (-> this level-info-array (-> this level-info-last-lookup))))
      (let ((a0-2 (-> v1-5 level)))
        (b! (!= (-> arg0 level_name) a0-2) cfg-3 :delay (empty-form))
        )
      (set! s5-0 v1-5)
      )
    (b! #t cfg-18 :delay (nop!))
    (label cfg-3)
    (let ((v1-6 0))
      (b! #t cfg-9 :delay (nop!))
      (label cfg-4)
      (let ((a0-6 (-> this level-info-array v1-6)))
        (let ((a3-1 (-> a0-6 level)))
          (b! (!= (-> arg0 level_name) a3-1) cfg-8 :delay (empty-form))
          )
        (if arg1
            (set! (-> this level-info-last-lookup) v1-6)
            )
        (set! s5-0 a0-6)
        )
      (b! #t cfg-18 :delay (nop!))
      (label cfg-8)
      (+! v1-6 1)
      (label cfg-9)
      (b! (< v1-6 (-> this level-info-array-length)) cfg-4)
      )
    (let ((v1-9 (-> this level-info-array-length)))
      (cond
        ((< v1-9 32)
         (if arg1
             (set! (-> this level-info-last-lookup) v1-9)
             )
         (set! s5-0 (-> this level-info-array v1-9))
         (set! (-> s5-0 level) (-> arg0 level_name))
         (set! (-> s5-0 node-count) 0)
         (+! (-> this level-info-array-length) 1)
         )
        (else
          (format
            0
            "mysql-nav-graph::lookup-level-info:  Error, too many unique level names in nav-graph.  May need to increase the max (currently ~d)~%"
            32
            )
          (let ((s4-0 0))
            (b! #t cfg-16 :delay (nop!))
            (label cfg-15)
            (let ((v1-17 (-> this level-info-array s4-0)))
              (format 0 "~d ~s~%" s4-0 (-> v1-17 level))
              )
            (+! s4-0 1)
            (label cfg-16)
            (b! (< s4-0 (-> this level-info-array-length)) cfg-15)
            )
          (break!)
          0
          )
        )
      )
    (label cfg-18)
    s5-0
    )
  )


(defmethod mysql-nav-graph-method-20 ((this mysql-nav-graph))
  (mysql-nav-graph-method-17 this)
  (mysql-nav-graph-method-19 this)
  0
  (none)
  )
