;Liquid War 6 is a unique multiplayer wargame.
;Copyright (C)  2005, 2006, 2007, 2008  Christian Mauduit <ufoot@ufoot.org>
;
;This program is free software; you can redistribute it and/or modify
;it under the terms of the GNU 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 General Public License for more details.
;
;You should have received a copy of the GNU General Public License
;along with this program.  If not, see <http://www.gnu.org/licenses/>.
;
;
;Liquid War 6 homepage : http://www.gnu.org/software/liquidwar6/
;Contact author        : ufoot@ufoot.org

(define %lw6-sensitivity-correction 3.)

(define lw6-mover-slow-down
  (lambda (cursor sensitivity key)
    (let (
	  (value (hash-ref cursor key))
	  )
      (hash-set! cursor key (cond
			     ((> value 0)
			      (max 0 (- value (* 2.0 (/ sensitivity %lw6-sensitivity-correction)))))
			     ((< value 0)
			      (min 0 (+ value (* 2.0 (/ sensitivity %lw6-sensitivity-correction)))))
			     (#t 0)
			     )))))

(define lw6-mover-minus
  (lambda (cursor sensitivity max-cursor-speed key)
    (let (
	  (value (hash-ref cursor key))
	  )
      (hash-set! cursor key (cond
			     ((> value 0)
			      0)
			     (#t
			      (max (- 0 max-cursor-speed) (- value (/ sensitivity %lw6-sensitivity-correction))))
			     )))))

(define lw6-mover-plus
  (lambda (cursor sensitivity max-cursor-speed key)
    (let (
	  (value (hash-ref cursor key))
	  )
      (hash-set! cursor key (cond
			     ((< value 0)
			      0)
			     (#t
			      (min max-cursor-speed (+ value (/ sensitivity %lw6-sensitivity-correction))))
			     )))))

(define lw6-mover-generic
  (lambda (get-state-func sensitivity-func max-cursor-speed-func)
    (lambda (cursor)
      (let* (
	     (state (get-state-func))
	     (up (assoc-ref state "up"))
	     (down (assoc-ref state "down"))
	     (left (assoc-ref state "left"))
	     (right (assoc-ref state "right"))
	     (sensitivity (sensitivity-func))
	     (max-cursor-speed (max-cursor-speed-func))
	    )
	(begin
	  (if up 
	      (if down
		  #t		  
		  (lw6-mover-minus cursor sensitivity max-cursor-speed "vy"))
	      (if down
		  (lw6-mover-plus cursor sensitivity max-cursor-speed "vy")
		  (lw6-mover-slow-down cursor sensitivity "vy")))
	  (if left
	      (if right
		  #t		  
		  (lw6-mover-minus cursor sensitivity max-cursor-speed "vx"))
	      (if right
		  (lw6-mover-plus cursor sensitivity max-cursor-speed "vx")
		  (lw6-mover-slow-down cursor sensitivity "vx")))
	  (hash-set! cursor "x" (+ (hash-ref cursor "x") (hash-ref cursor "vx")))
	  (hash-set! cursor "y" (+ (hash-ref cursor "y") (hash-ref cursor "vy")))
	  )))))

(define lw6-mover-mouse-func
  (lambda (cursor)
    (let* (
	   (video-mode (c-lw6gfx-get-video-mode))
	   (width (assoc-ref video-mode "width"))
	   (height (assoc-ref video-mode "height"))
	   (center-x (inexact->exact (round (/ width 2))))
	   (center-y (inexact->exact (round (/ height 2))))
	   (mouse-state (c-lw6gfx-get-mouse-state))
	   (mouse-x (assoc-ref mouse-state "x"))
	   (mouse-y (assoc-ref mouse-state "y"))
	   (coef (/ (lw6-config-get-number lw6def-mouse-sensitivity) %lw6-sensitivity-correction))
	   (x (hash-ref cursor "x"))
	   (y (hash-ref cursor "y"))
	   )
      (if (not (lw6-menu-has-items? (lw6-current-menu)))
	  (begin
	    (hash-set! cursor "x" (+ x (* (- mouse-x center-x) coef)))
	    (hash-set! cursor "y" (+ y (* (- mouse-y center-y) coef)))
	    (c-lw6gfx-warp-mouse center-x center-y)
	    )))))

(define lw6-mover-keyboard-func
  (lw6-mover-generic c-lw6gfx-get-default-keys-state 
		     (lambda () (lw6-config-get-number lw6def-keyboard-sensitivity))
		     (lambda () (lw6-config-get-number lw6def-max-keyboard-cursor-speed))
		     ))

(define lw6-mover-joystick1-func
  (lw6-mover-generic (lambda () (let* (
				       (joystick-index (lw6-config-get-number lw6def-joystick1-index))
				       (joystick-button-a (lw6-config-get-number lw6def-joystick1-button-a))
				       (joystick-button-b (lw6-config-get-number lw6def-joystick1-button-b))
				       (state c-lw6gfx-get-joystick-state joystick-index joystick-button-a joystick-button-b)
				       (x (assoc-ref state x))
				       (y (assoc-ref state y))
				       (button-a (assoc-ref state button-a))
				       (button-b (assoc-ref state button-b))
				       )
				  (list (cons "up" (< y 0))
					(cons "down" (> y 0))
					(cons "left" (< x 0))
					(cons "right" (>  x 0)))))
		     (lambda () (lw6-config-get-number lw6def-joystick-sensitivity))
		     (lambda () (lw6-config-get-number lw6def-max-joystick-cursor-speed))
		     ))

(define lw6-mover-joystick2-func
  (lw6-mover-generic (lambda () (let* (
				       (joystick-index (lw6-config-get-number lw6def-joystick2-index))
				       (joystick-button-a (lw6-config-get-number lw6def-joystick2-button-a))
				       (joystick-button-b (lw6-config-get-number lw6def-joystick2-button-b))
				       (state c-lw6gfx-get-joystick-state joystick-index joystick-button-a joystick-button-b)
				       (x (assoc-ref state x))
				       (y (assoc-ref state y))
				       (button-a (assoc-ref state button-a))
				       (button-b (assoc-ref state button-b))
				       )
				  (list (cons "up" (< y 0))
					(cons "down" (> y 0))
					(cons "left" (< x 0))
					(cons "right" (>  x 0)))))
		     (lambda () (lw6-config-get-number lw6def-joystick-sensitivity))
		     (lambda () (lw6-config-get-number lw6def-max-joystick-cursor-speed))
		     ))

(define lw6-mover-bot-func
  (lambda (cursor)
    (let* (
	   (bot (hash-ref cursor "bot"))
	   (pos (if bot (c-lw6bot-next-move bot) #f))
	   )
      (if (and bot pos)
	  (begin
	    (hash-set! cursor "x" (assoc-ref pos "x"))
	    (hash-set! cursor "y" (assoc-ref pos "y"))
	    )))))

(define lw6-mover
  (lambda ()
    (map (lambda (cursor-key) (let* (
				     (game-state (lw6-get-game-global "game-state"))
				     (cursor (lw6-get-cursor cursor-key))
				     (mover (hash-ref cursor "mover"))
				     )
				(if (and game-state mover cursor)
				    (begin
				      (mover cursor)
				      (let* (					    
					     (coords (c-lw6pil-fix-coords game-state (hash-ref cursor "x") (hash-ref cursor "y")))
					     (x (assoc-ref coords "x"))
					     (y (assoc-ref coords "y"))
					     )
					(begin
					  (hash-set! cursor "x" x)
					  (hash-set! cursor "y" y)
					  )
					)
				      )
				    )))
	 (list "1" "2" "3" "4"))))
