(require :asdf)

(pushnew #P"/usr/local/asdf-install/site-systems/" asdf:*central-registry*)

(handler-bind ((style-warning #'muffle-warning))
  (asdf:operate 'asdf:load-op 'cl-opengl :verbose nil)
  (asdf:operate 'asdf:load-op 'cl-glu :verbose nil)
  (asdf:operate 'asdf:load-op 'cl-glut :verbose nil))

(load "about.lisp")

(in-package #:approx-ft-about)

(defclass about-window (glut:window)
  ((idle-func :initform nil)
   buf
   texture
   (ww :initarg :ww)
   (hh :initarg :hh))
  (:default-initargs :width 256
                     :height 256
		     :ww 256
		     :hh 256
		     :title "approx-ft-about"
		     :mode '(:double :rgb :depth)))

(defmethod initialize-instance :after ((w about-window) &key)
  (with-slots (buf ww hh) w
    (setf buf (make-array (* ww hh)
			  :element-type '(unsigned-byte 8)
			  :initial-element 0))))

(defmethod glut:display-window :before ((w about-window))
  (gl:clear-color 0 0 0 0)
  (gl:cull-face :back)
  (gl:front-face :ccw)
  (gl:line-width 3.0)
  (gl:point-size 9.0)
  (gl:shade-model :smooth)
  (gl:blend-func :one :zero)
  (gl:enable :blend :texture-2d)
  (with-slots (texture) w
    (setf texture (first (gl:gen-textures 1)))
    (gl:bind-texture :texture-2d texture))
  (gl:tex-parameter :texture-2d :texture-min-filter :linear)
  (gl:tex-parameter :texture-2d :texture-mag-filter :linear))

(defmethod glut:display ((w about-window))
  (gl:matrix-mode :modelview)
  (gl:load-identity)
  (gl:clear :color-buffer-bit)
  (with-slots (texture) w
    (gl:bind-texture :texture-2d texture))
  (gl:color 1 1 1)
  (gl:with-primitives :quads
    (gl:tex-coord 0 1)
    (gl:vertex -1 -1)
    (gl:tex-coord 1 1)
    (gl:vertex  1 -1)
    (gl:tex-coord 1 0)
    (gl:vertex  1  1)
    (gl:tex-coord 0 0)
    (gl:vertex -1 1))
  (glut:swap-buffers)
  (gl:flush))

(defmethod glut:idle ((w about-window))
  (with-slots (idle-func ww hh) w
    (when idle-func
      (gl:tex-image-2d :texture-2d 0 :intensity ww hh 0
		       :luminance :unsigned-byte (funcall idle-func))
      (sleep 0.75)
      (glut:post-redisplay))))
  
(defmethod glut:reshape ((w about-window) width height)
  (gl:viewport 0 0 width height)
  (gl:matrix-mode :projection)
  (gl:load-identity)
  (gl:ortho -1 1 -1 1 -1.0 1.0)
  #+nope (gl:frustum -1 1 -1 1 1.5 500)
  (gl:matrix-mode :modelview))

(defmethod glut:keyboard ((w about-window) key xx yy)
  (declare (ignore xx yy))
  (with-slots (idle-func buf ww hh) w
    (cond
      ((eql key #\a) (setf idle-func
			   (make-amplitude-cycler 0.75 0.2 buf ww hh)))
      ((eql key #\f) (setf idle-func
			   (make-frequency-cycler 8.0 0.2 buf ww hh)))
      ((eql key #\t) (setf idle-func
			   (make-angle-cycler 0.0 0.2 buf ww hh)))
      ((eql key #\o) (setf idle-func
			   (make-offset-cycler 0.0 0.2 buf ww hh)))
      ((eql key #\l) (setf idle-func
			   (make-list-cycler +waves+ buf ww hh)))
      ((eql key #\n) (setf idle-func nil))
      ((eql key #\q) (glut:destroy-current-window))))
  (glut:post-redisplay))

(glut:display-window (make-instance 'about-window :steps 20
				                   :range 0.5))

