; The port on which the server listens ("default 8080")
(setq port 8888)
; Type of game you want to play (uis, is, 1P, 2P)
(setq gametype "1P")
; Only for gametype 2P: t if you want to create a 2P-game, nil if you want to join a 2P-game
(setq create NIL)
; Host where the server is (default: "localhost")
(setq host "localhost")
; File name where the agent code is

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; PRACTICAL EXERCISE -- make sure this is planning.lisp 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(setq agent "planning.lisp")    

(eval-when (compile eval load)
	(defpackage "SQCLIENT"
		(:export "START")))

(asdf:operate 'asdf:load-op 's-xml)
(asdf:operate 'asdf:load-op 's-base64)
(asdf:operate 'asdf:load-op 's-sysdeps)
(asdf:operate 'asdf:load-op 's-xml-rpc)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; PRACTICAL EXERCISE
;; Make sure *ucpop-dir* points to the directory with 
;; UCPOP (where loader.lisp can be found)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defparameter *ucpop-dir* "../ucpop/")

(load (concatenate 'string *ucpop-dir* "loader.lisp"))
(load-ucpop)
(compile-ucpop)
(load-ucpop)

(defun start ()
	"Starts the Agent."
	; Reads the strategy from file
	(setq strat (get-strategy-from-file agent))
	; Calls the server to register the game
	(register-client gametype)

	(if (equal gametype "2P")
		(print "Waiting for Opponent..."))

	; In 2-Player games server closes connection after some timelimit 
	; if no opponent found, so we have to reconnect 
	(loop until
				(not (equal '(STOP RECONNECT) output))
	do
		(progn
			(register-client gametype)
			(print "Still Waiting...")))
			

	; If the game is over the client stops
	(loop until 
		(equal 'UCPOP::STOP (car output))
	do
		(send-response))

;	(handler-case
;		(funcall strat output)
;	(error () (print "Bad return value by agent!")))
;	(print "STOP from Server. Client finished."))
)

(defun get-strategy-from-file (filename)
	"Read and evaluate the strategy closure from file filename."
 	(with-open-file (stream filename)
					 	  (eval (read stream)))
;;	(load filename)
	)

(defun register-client (gametype)
	"Begin communication with server, get id and starting informations."

	(cond 
		((equal gametype "uis")
			(setq response
	 			(s-xml-rpc::xml-rpc-call (s-xml-rpc::encode-xml-rpc-call "squirrel.regSearch" gametype) :host host :port port)))
		((equal gametype "is")
			(setq response
	 			(s-xml-rpc::xml-rpc-call (s-xml-rpc::encode-xml-rpc-call "squirrel.regSearch" gametype) :host host :port port)))
		((equal gametype "1P")
			(setq response
	 			(s-xml-rpc::xml-rpc-call (s-xml-rpc::encode-xml-rpc-call "squirrel.reg1P") :host host :port port)))
		((equal gametype "2P")
			(setq response
	 			(s-xml-rpc::xml-rpc-call (s-xml-rpc::encode-xml-rpc-call "squirrel.reg2P" create) :host host :port port)))
		(t (print "Gametype not known")))

	; Get the id and output from server answer
	(setq id 
		(s-xml-rpc::get-xml-rpc-struct-member response :|id|))
	(setq output
		(handler-case
			(read-from-string (s-xml-rpc::get-xml-rpc-struct-member response :|output|))
			(error () (print "Error while reading server answer")))))

	; Call the agent
(defun send-response ()
  (setq out (funcall strat output))

	(cond
		((or (equal gametype "uis") (equal gametype "is"))
		 (setq server-call "squirrel.submitMoveSearch"))
		((equal gametype "1P")
		 (setq server-call "squirrel.submitMove1P"))
		((equal gametype "2P")
		 (setq server-call "squirrel.submitMove1P")))

	(format t "from client: ~s" out)
	; Send response to server
	(setq output
		(handler-case
			(read-from-string 
				(s-xml-rpc::xml-rpc-call (s-xml-rpc::encode-xml-rpc-call server-call id (write-to-string out)) :host host :port port))
			(error () (print "Error while reading server answer")))))
(in-package :sqclient)
