;; -*- mode: scheme; -*-
;; Planet Fluxus Copyright (C) 2013 Dave Griffiths
;;
;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU Affero General Public License as
;; published by the Free Software Foundation, either version 3 of the
;; License, or (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU Affero General Public License for more details.
;;
;; You should have received a copy of the GNU Affero General Public License
;; along with this program.  If not, see <http://www.gnu.org/licenses/>.

(define textures ())
(define textures-load-outstanding 0)
(define textures-total-load 0)

(define (get-texture name)
  (foldl
   (lambda (t r)
     (if (and (not r) (eq? (car t) name))
         (cadr t) r))
   #f
   textures))

(define (textures-loaded?)
  (eq? textures-load-outstanding 0))

(define (load-texture-impl! gl name)
  (if (assoc name textures)
      name
      (let ((texture (gl.createTexture)))
		(set! textures-load-outstanding (+ textures-load-outstanding 1))
		(set! textures-total-load (+ textures-total-load 1))
        (set! texture.image 
			  (load-resource-img 
			   name
			   (lambda (image)
				 ;;(msg (list "loaded" name))
				 (set! textures-load-outstanding (- textures-load-outstanding 1))
				 (gl.bindTexture gl.TEXTURE_2D texture)
				 (gl.pixelStorei gl.UNPACK_FLIP_Y_WEBGL true)
				 (gl.texImage2D gl.TEXTURE_2D 0 gl.RGBA gl.RGBA gl.UNSIGNED_BYTE image)
				 (gl.generateMipmap gl.TEXTURE_2D)
				 ;;(gl.texParameteri gl.TEXTURE_2D gl.TEXTURE_MAG_FILTER gl.LINEAR)
				 (gl.texParameteri gl.TEXTURE_2D gl.TEXTURE_MIN_FILTER gl.LINEAR_MIPMAP_LINEAR)
				 (gl.texParameteri gl.TEXTURE_2D gl.TEXTURE_MAG_FILTER gl.LINEAR)
				 ;;(gl.texParameteri gl.TEXTURE_2D gl.TEXTURE_MIN_FILTER gl.LINEAR)
				 (gl.texParameteri gl.TEXTURE_2D gl.TEXTURE_WRAP_S gl.REPEAT) ;; gl.CLAMP_TO_EDGE
				 (gl.texParameteri gl.TEXTURE_2D gl.TEXTURE_WRAP_T gl.REPEAT) ;; gl.CLAMP_TO_EDGE
				 (gl.bindTexture gl.TEXTURE_2D null)
				 (set! textures (cons (list name texture) textures))
				 ;;(console.log (+ "processed " name))
				 )))
        ;;(console.log (+ "loading " name))
        name)))

(define (bind-texture gl shader name)
  (let ((texture (get-texture name)))
    ;; may not have loaded yet
    (cond
	 (texture
	  (gl.activeTexture gl.TEXTURE0)
	  (gl.bindTexture gl.TEXTURE_2D texture)
	  (gl.uniform1i shader.texture 0)
	  #t)
	 (else #f))))
