;Liquid War 6 is a unique multiplayer wargame.
;Copyright (C)  2005, 2006, 2007, 2008, 2009  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-make-cursor
  (lambda (cursor-key)
    (let (
	  (cursor (make-hash-table 13))
	  )
      (begin
	(hash-set! cursor "status" #f)
	(hash-set! cursor "key" cursor-key)
	(hash-set! cursor "id" (c-lw6sys-generate-id-16))
	(hash-set! cursor "x" -1)
	(hash-set! cursor "y" -1)
	(hash-set! cursor "mouse-controlled" #f)
	(hash-set! cursor "vx" 0.0)
	(hash-set! cursor "vy" 0.0)
	(hash-set! cursor "map-x" 0)
	(hash-set! cursor "map-y" 0)
	(hash-set! cursor "letter" #f)
	(hash-set! cursor "team-color" #f)
	(hash-set! cursor "mover" (lambda (c) #f))
	(hash-set! cursor "bot" #f)
	cursor
      ))))

(define lw6-get-cursor
  (lambda (cursor-key)
    (let* (
	   (cursors (lw6-get-game-global "cursors"))
	   (cursor (hash-ref cursors (string-concatenate (list "cursor" cursor-key))))
	   )
      cursor)))

(define lw6-disable-cursor
  (lambda (cursor-key)
    (let (
	  (cursors (lw6-get-game-global "cursors"))
	  )
      (begin
	(hash-set! cursors 
		   (string-concatenate (list "cursor" cursor-key))
		   (lw6-make-cursor cursor-key))))))

(define lw6-enable-cursor
  (lambda (cursor-key)
    (let* (
	   (cursors (lw6-get-game-global "cursors"))
	   (cursor (hash-ref cursors (string-concatenate (list "cursor" cursor-key))))
	   )
      (begin
	(hash-set! cursor "status" #t)
	cursor))))

(define lw6-cursor-set-configured-player!
  (lambda (game-state cursor-key server-id)
    (let* (
	   (player-status-key (string-concatenate (list "player" cursor-key "-status")))
	   (player-color-key (string-concatenate (list "player" cursor-key "-color")))
	   (player-control-key (string-concatenate (list "player" cursor-key "-control")))
	   (player-status (lw6-config-is-true? player-status-key))
	   (player-color (lw6-config-get-string player-color-key))
	   (player-control (lw6-config-get-string player-control-key))
	   )
      (if player-status 
	  (let* (
		 (cursor (lw6-enable-cursor cursor-key))
		 (cursor-id (hash-ref cursor "id"))
		 (server-id (lw6-get-game-global "server-id"))
		 )
	    (begin
	      (c-lw6ker-add-cursor game-state server-id cursor-id player-color)
	      ))
	  (lw6-disable-cursor cursor-key))
      )))

(define lw6-cursor-prepare-configured-player-command
  (lambda (game-state cursor-key server-id)
    (let* (
	   (player-status-key (string-concatenate (list "player" cursor-key "-status")))
	   (player-color-key (string-concatenate (list "player" cursor-key "-color")))
	   (player-control-key (string-concatenate (list "player" cursor-key "-control")))
	   (player-status (lw6-config-is-true? player-status-key))
	   (player-color (lw6-config-get-string player-color-key))
	   (player-control (lw6-config-get-string player-control-key))
	   )
      (if player-status 
	  (let* (
		 (cursor (lw6-enable-cursor cursor-key))
		 (cursor-id (lw6-get-cursor-id-not-in-game-state game-state))
		 (rounds (c-lw6ker-get-rounds game-state))
		 )
	    (begin
	      (hash-set! cursor "id" cursor-id)
	      (lw6-command-add rounds server-id cursor-id player-color)
	      ))
	  #f)
      )))

(define lw6-cursor-prepare-demo-player-command
  (lambda (game-state cursor-key server-id color)
    (let* (
	   (cursor (lw6-enable-cursor cursor-key))
	   (cursor-id (lw6-get-cursor-id-not-in-game-state game-state))
	   (rounds (c-lw6ker-get-rounds game-state))
	   )
      (begin
	(hash-set! cursor "id" cursor-id)
	(lw6-command-add rounds server-id cursor-id color)
	))))

(define lw6-cursor-prepare-quick-start-player-command
  lw6-cursor-prepare-demo-player-command)

(define lw6-get-cursor-id-not-in-game-state
  (lambda (game-state)
    (let (
	  (cursor-id (c-lw6sys-generate-id-16))
	  )
      (if (c-lw6ker-get-cursor-info game-state cursor-id)
	  (lw6-get-cursor-id-not-in-game-state game-state)
	  cursor-id))))

(define lw6-cursor-init-pos
  (lambda (game-state cursor-key)
    (let* (
	   (cursor (lw6-get-cursor cursor-key))
	   (cursor-id (hash-ref cursor "id"))
	   (cursor-info (c-lw6ker-get-cursor-info game-state cursor-id))
	   )
      (if cursor-info
	  (begin
	    (hash-set! cursor "x" (assoc-ref cursor-info "x"))
	    (hash-set! cursor "y" (assoc-ref cursor-info "y"))
	    (hash-set! cursor "letter" (assoc-ref cursor-info "letter"))
	    (hash-set! cursor "team-color" (assoc-ref cursor-info "team-color"))
	    )))))

(define lw6-cursor-init-configured-mover
  (lambda (cursor-key)
    (let* (
	   (cursor (lw6-get-cursor cursor-key))
	   (player-status-key (string-concatenate (list "player" cursor-key "-status")))
	   (player-bot-key (string-concatenate (list "player" cursor-key "-bot")))
	   (player-control-key (string-concatenate (list "player" cursor-key "-control")))
	   (player-status (lw6-config-is-true? player-status-key))
	   (player-bot (lw6-config-get-string player-bot-key))
	   (player-control (lw6-config-get-string player-control-key))
	   )
      (if player-status
	  (hash-set! cursor "mover" (if (or (equal? player-bot "") (not player-bot))
					(cond 
					 ((equal? player-control "mouse")
					  lw6-mover-mouse-func)
					 ((equal? player-control "keyboard")
					  lw6-mover-keyboard-func)
					 ((equal? player-control "joystick1")
					  lw6-mover-joystick1-func)
					 ((equal? player-control "joystick2")
					  lw6-mover-joystick2-func)
					 (#t
					  (lambda (c) #f))
					 )
					(let ( 
					      (bot (c-lw6bot-new 
						    player-bot
						    (lw6-get-game-global "game-state")
						    (lw6-get-game-global "pilot")
						    (lw6-config-get-number lw6def-dirty-read)
						    (hash-ref cursor "id")
						    (lw6-config-get-number lw6def-bot-speed)
						    (lw6-config-get-number lw6def-bot-iq)))
					      )
					  (begin
					    (hash-set! cursor "bot" bot)
					    lw6-mover-bot-func
					    )))))
      )))

(define lw6-cursor-init-bot-mover
  (lambda (cursor-key bot-engine)
    (let* (
	   (cursor (lw6-get-cursor cursor-key))
	   )
      (let ( 
	    (bot (c-lw6bot-new 
		  bot-engine
		  (lw6-get-game-global "game-state")
		  (lw6-get-game-global "pilot")
		  (lw6-config-get-number lw6def-dirty-read)
		  (hash-ref cursor "id")
		  (lw6-config-get-number lw6def-bot-speed)
		  (lw6-config-get-number lw6def-bot-iq)))
	    )
	(begin
	  (hash-set! cursor "bot" bot)
	  (hash-set! cursor "mover" lw6-mover-bot-func)
	  )))))

(define lw6-cursor-init-universal-mover
  (lambda (cursor-key)
    (let* (
	   (cursor (lw6-get-cursor cursor-key))
	   )
      (hash-set! cursor "mover" lw6-mover-universal-func)
      )))

(define lw6-cursor-does-config-match-universal?
  (lambda (cursor-key)
    (let* (
	   (player-status-key (string-concatenate (list "player" cursor-key "-status")))
	   (player-control-key (string-concatenate (list "player" cursor-key "-control")))
	   (player-bot-key (string-concatenate (list "player" cursor-key "-bot")))
	   (player-status (lw6-config-is-true? player-status-key))
	   (player-control (lw6-config-get-string player-control-key))
	   (player-bot (lw6-config-get-string player-bot-key))
	   )
      (begin
	(and player-status
	     (equal? player-bot "")
	     (or (equal? player-control "keyboard")
		 (equal? player-control "mouse")
		 (equal? player-control "joystick1")
		 (equal? player-control "joystick2")))
	)
      )))

(define lw6-cursor-set-universal-if-needed
  (lambda ()
    (if (and (lw6-cursor-does-config-match-universal? "1")
	     (not (lw6-cursor-does-config-match-universal? "2"))
	     (not (lw6-cursor-does-config-match-universal? "3"))
	     (not (lw6-cursor-does-config-match-universal? "4")))
	(let* (
	       (cursor (lw6-get-cursor "1"))
	       )
	  (hash-set! cursor "mover" lw6-mover-universal-func)))
    ))
	
