;;-*-Lisp-*-
(in-package goal)
(bundles "MAI.DGO")
(require "engine/anim/joint-h.gc")
(require "engine/gfx/mood/time-of-day.gc")

;; DECOMP BEGINS

(define *cavecrystal-engine* (new 'loading-level 'engine 'cavecrystal 64))

(deftype cavecrystal-light (structure)
  ((next           cavecrystal-light)
   (crystal-id     int32)
   (intensity      float)
   (fade-start     float)
   (fade-end       float)
   (crystal-handle handle)
   (trans          vector :inline)))

(deftype cavecrystal-light-control (basic)
  ((active-count          int32)
   (head                  cavecrystal-light)
   (last-known-valid-time time-frame)
   (crystal               cavecrystal-light 7 :inline))
  (:methods
   (cavecrystal-light-control-method-9 (_type_ int float process-drawable) none)
   (cavecrystal-light-control-method-10 (_type_ vector) float)
   (inc-intensities! (_type_) none)
   (cavecrystal-light-control-method-12 (_type_) none)
   (create-connection! (_type_ process-drawable res-lump (function object object object object object) int float) connection)
   (execute-connections (_type_) int)))

(define *cavecrystal-light-control* (new 'static 'cavecrystal-light-control :head #f))

(defun cavecrystal-light-control-default-callback ((arg0 (pointer process-drawable)) (arg1 int) (arg2 float))
  (let ((s5-0 (new 'stack-no-clear 'vector)))
    (let ((v1-1 (-> arg0 0 node-list)))
      (if (and (>= arg1 0) (nonzero? v1-1))
        (vector<-cspace! s5-0 (-> v1-1 data arg1))
        (set! (-> s5-0 quad) (-> arg0 0 root trans quad))))
    (set! (-> s5-0 w) arg2)
    (let ((f0-1 (cavecrystal-light-control-method-10 *cavecrystal-light-control* s5-0))
          (a2-2 (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0))
          (a1-5 (new 'static 'vector :x 0.05 :y 0.05 :z 0.05 :w 1.0)))
      (vector-lerp! (-> arg0 0 draw color-mult) a1-5 a2-2 f0-1)))
  (none))

(defmethod create-connection! ((this cavecrystal-light-control) (arg0 process-drawable) (arg1 res-lump) (arg2 (function object object object object object)) (arg3 int) (arg4 float))
  (if (nonzero? (res-lump-value arg1 'crystal-light uint128))
    (add-connection *cavecrystal-engine* arg0 arg2 (process->ppointer arg0) arg3 arg4)))

(defmethod execute-connections ((this cavecrystal-light-control))
  (execute-connections *cavecrystal-engine* #f))

(defmethod cavecrystal-light-control-method-12 ((this cavecrystal-light-control))
  (let ((v1-0 (-> this last-known-valid-time))
        (a1-1 (current-time)))
    (when (!= v1-0 a1-1)
      (set! (-> this last-known-valid-time) a1-1)
      (cond
        ((zero? v1-0)
         (set! (-> this active-count) 0)
         (set! (-> this head) #f)
         (dotimes (v1-1 7)
           (let ((a1-5 (-> this crystal v1-1)))
             (set! (-> a1-5 next) #f)
             (set! (-> a1-5 crystal-id) v1-1)
             (set! (-> a1-5 intensity) 0.0)
             (set! (-> a1-5 fade-start) 20480.0)
             (set! (-> a1-5 fade-end) 286720.0)
             (set! (-> a1-5 crystal-handle) (the-as handle #f)))))
        (else
         (when (> (-> this active-count) 0)
           (let ((v1-4 (the-as cavecrystal-light #f))
                 (a1-7 (-> this head)))
             (while a1-7
               (cond
                 ((handle->process (-> a1-7 crystal-handle)) (set! v1-4 a1-7) (set! a1-7 (-> a1-7 next)))
                 (else
                  (let ((a2-4 (-> a1-7 next)))
                    (+! (-> this active-count) -1)
                    (set! (-> a1-7 next) #f)
                    (set! (-> a1-7 intensity) 0.0)
                    (if v1-4 (set! (-> this head) a2-4) (set! (-> v1-4 next) a2-4))
                    (set! a1-7 a2-4)))))))))))
  (none))

(defmethod inc-intensities! ((this cavecrystal-light-control))
  (set! (-> this head) #f)
  (let ((a1-0 (the-as cavecrystal-light #f))
        (v0-0 0))
    (dotimes (v1-0 7)
      (let ((a2-3 (-> this crystal v1-0)))
        (set! (-> a2-3 next) #f)
        (when (< 0.0 (-> a2-3 intensity))
          (+! v0-0 1)
          (if a1-0 (set! (-> a1-0 next) a2-3) (set! (-> this head) a2-3))
          (set! a1-0 a2-3))))
    (set! (-> this active-count) v0-0))
  (none))

;; WARN: Function (method 9 cavecrystal-light-control) has a return type of none, but the expression builder found a return statement.
(defmethod cavecrystal-light-control-method-9 ((this cavecrystal-light-control) (arg0 int) (arg1 float) (arg2 process-drawable))
  (cavecrystal-light-control-method-12 this)
  (when (or (< arg0 0) (>= arg0 7))
    (format 0 "ERROR: Bogus cavecrystal id!~%")
    (return #f))
  (let ((s3-0 (-> this crystal arg0)))
    (cond
      ((and (< 0.0 arg1) (>= 0.0 (-> s3-0 intensity)))
       (+! (-> this active-count) 1)
       (set! (-> s3-0 intensity) arg1)
       (set! (-> s3-0 crystal-handle) (process->handle arg2))
       (set! (-> s3-0 trans quad) (-> arg2 root trans quad))
       (inc-intensities! this))
      ((and (>= 0.0 arg1) (< 0.0 (-> s3-0 intensity)))
       (+! (-> this active-count) -1)
       (set! (-> s3-0 intensity) 0.0)
       (inc-intensities! this))
      ((< 0.0 arg1) (set! (-> s3-0 intensity) arg1)))
    (set-fade! *palette-fade-controls* (+ arg0 1) arg1 0.0 (-> s3-0 trans)))
  (none))

(defmethod cavecrystal-light-control-method-10 ((this cavecrystal-light-control) (arg0 vector))
  (cavecrystal-light-control-method-12 this)
  (let ((s5-1 (-> this head))
        (f30-0 0.0))
    (when s5-1
      (until (not s5-1)
        (let* ((f26-0 (-> s5-1 fade-start))
               (f28-0 (- (-> s5-1 fade-end) f26-0))
               (f1-1 (fmin (fmax 0.0 (- (- (vector-vector-distance (-> s5-1 trans) arg0) (-> arg0 w)) f26-0)) f28-0))
               (f0-7 (* (- 1.0 (/ f1-1 f28-0)) (-> s5-1 intensity))))
          (if (< f30-0 f0-7) (set! f30-0 f0-7)))
        (set! s5-1 (-> s5-1 next)))
      (set! f30-0 (fmin 2.0 f30-0)))
    f30-0))
