#!/usr/bin/env python

import os,sys
import random
from string import *

import ckhetpkg.Robot as Robot
import ckhetpkg.Network as Network
from ckhetpkg.State import GameOpts, netStrToGameOpts
from ckhetpkg.CursesUI import CursesUI, SPRITES
from ckhetpkg.DumbUI import DumbUI
from ckhetpkg.Layouts import LAYOUTS

if __name__ == "__main__":
    import getopt
    try: getopt = getopt.gnu_getopt
    except: getopt = getopt.getopt
    (opts, argame) = getopt(sys.argv[1:],
	    'p:r:RW:H:g:Gmdhl:L',
	    ["port=", "robot=", "robots", "heights=", "width=", "graphics=", "monochrome", "dumb", "listgraphics", "help", "layout=", "listlayouts"])

    port = Network.PORT
    Player = CursesUI
    playerOpts = {}
    layout = 0
    for (opt, val) in opts:
	def robotList():
	    return ("Known robots:\n" +
		join(["\t\"%s\" - %s\n" % (
			robotName,robot.shortDesc)
			for (robotName,robot) in
			Robot.robots.iteritems()],
		    ''))
	def usage():
	    sys.stdout.write(
"""Usage: %s [options] [hostname]
If hostname is given, attempts to connect to a server running there;
else, starts a server.
General options:
    -p, --port=PORT:    select port to connect to or serve on
    -r, --robot=ROBOT:  select a robot (AI) to run
    -R, --robots:       list available robots
    -H, --height=N:	square height
    -W, --width=N:	square width
    -g, --graphics=SET	select graphics style
    -G, --listgraphics	list available graphics styles
    -m, --monochrome	monochrome mode
    -d, --dumb		dumb terminal UI
    -h, --help:         this help
Game options (server chooses):
    -l, --layout=N:	initial board layout
    -L, --listlayouts:  list available layouts
""")
		    
	if opt in ["-p", "--port"]:
	    port=int(val)
	elif opt in ["-r", "--robot"]:
	    try:
		import re
		m = re.match('([^:]*):?(.*)', val)
		Player = Robot.robots[m.group(1)]
		if m.group(2):
		    playerOpts["robotParams"] = m.group(2)
	    except KeyError:
		sys.stderr.write("Unknown robot: %s\n" % val)
		sys.stderr.write(robotList())
		sys.exit(2)
	elif opt in ["-R", "--robots"]:
	    sys.stdout.write(robotList())
	    sys.exit(0)
	elif opt in ["-H", "--height"]:
	    playerOpts["sqHeight"] = int(val)
	elif opt in ["-W", "--width"]:
	    playerOpts["sqWidth"] = int(val)
	elif opt in ["-g", "--graphics"]:
	    if SPRITES.has_key(val):
		playerOpts["spriteset"] = val
	elif opt in ["-G", "--listgraphics"]:
	    print SPRITES.keys()
	    sys.exit(0)
	elif opt in ["-m", "--monochrome"]:
	    playerOpts["monochrome"] = True
	elif opt in ["-d", "--dumb"]:
	    Player = DumbUI
	elif opt in ["-h", "--help"]:
	    usage()
	    sys.exit(0)
	elif opt in ["-l", "--layout"]:
	    layout = int(val)
	elif opt in ["-L", "--listlayouts"]:
	    for i,l in enumerate(LAYOUTS):
		print "%d - %s"  % (i, l[0])
	    sys.exit(0)

    if argame == []:
	print "Waiting for connection on port %s" % port
	socket = Network.serve(port)
	gameOpts = GameOpts(layout)
	socket.send(gameOpts.netStr())
	isServer = True
    else:
	host = argame[0]
	# TODO: parse "host:port"; accept port as a second argument
	print "Connecting to %s:%s" % (host, port)
	socket = Network.connect(host, port)
	gameOpts = netStrToGameOpts(socket.recvFixed(GameOpts.NETSTR_LEN))
	isServer = False

    random.seed() # FIXME: should use /dev/random if available

    player = Player(socket, isServer, gameOpts, playerOpts)
    try:
	player.interact()
    except KeyboardInterrupt:
	socket.close()
	sys.exit(0)
