#!/usr/bin/env python
# -*- coding: utf-8 -*-
# GGZBoard: Board game client container application
# Copyright (C) 2004 - 2006 Josef Spillner <josef@ggzgamingzone.org>
# Published under GNU GPL conditions

import pygame
from pygame.locals import *
from Numeric import *
import sys
import time
import os, pwd
import imp
import re
import gettext
import glob

import rsvgsdl
import sdlnewstuff

try:
	import ggzsettings
	DATAPATH = ggzsettings.DATAPATH + "/ggzboard/"
	MODULEPATH = ggzsettings.MODULEPATH + "/ggzboard/"
	I18NPATH = ggzsettings.I18NPATH
	sys.path = [ggzsettings.MODULEPATH + "/ggzboard/"] + sys.path
	sys.path = [ggzsettings.MODULEPATH + "/common/"] + sys.path
except:
	DATAPATH = "./"
	MODULEPATH = "./"
	I18NPATH = "./"
	sys.path = ["../lib/"] + sys.path

import playertable

gettext.install("ggzpython", I18NPATH, 1)

def asciify(str):
		asciistr = str.encode("ascii", "replace")
		return asciistr

def username():
	return pwd.getpwuid(os.geteuid())[0]

def playsound(theme):
	file = DATAPATH + "SOUNDS/" + theme + ".wav"
	try:
		sound = pygame.mixer.Sound(file)
		sound.play()
	except:
		print "Sound error:", file
		pass

class Conf:
	def __init__(self):
		self.alpha = 120
		self.background = "background.png"
		self.cellwidth = 50
		self.cellheight = 50
		self.cellspace = 0 #10
		self.marginwidth = 20
		self.marginheight = 100
		self.tilecolor = (100, 100, 100)
		self.darktilecolor = (50, 50, 50)
		self.resolution = (800, 700)
		self.fullscreen = 0

class GGZBoardUI:
	def __init__(self, resolution):
		self.origsurface = None
		self.surface = None
		self.backgroundarea = pygame.Surface(resolution)

		self.screen = None
		self.origres = resolution
		self.currentres = resolution
		self.isfullscreen = 0

		self.font = None
		self.smallfont = None

	def initfonts(self):
		self.font = pygame.font.SysFont("vera", 48)
		self.smallfont = pygame.font.SysFont("vera", 24)

	def togglefullscreen(self):
		self.isfullscreen = not self.isfullscreen
		self.currentres = None
		if self.isfullscreen:
			info = pygame.display.Info()
			try:
				# Pygame 1.8+ only
				w = info.current_w
				h = info.current_h
			except:
				# Pygame up to 1.7 don't know the current screen resolution
				w = -1
				h = -1
			modes = pygame.display.list_modes(0, FULLSCREEN)
			if modes != -1:
				safemodes = ((1024, 768), (800, 600))
				for mode in modes:
					if pygame.display.mode_ok(mode, DOUBLEBUF | FULLSCREEN):
						if w == -1:
							if not self.currentres:
								self.currentres = mode
							if mode in safemodes:
								self.currentres = mode
								break
						if w == mode[0] and h == mode[1]:
							self.currentres = mode
							break
				if self.currentres:
					self.screen = pygame.display.set_mode(self.currentres, DOUBLEBUF | FULLSCREEN)
			else:
				pygame.display.toggle_fullscreen()
		else:
			self.currentres = self.origres
			self.screen = pygame.display.set_mode(self.currentres, DOUBLEBUF)

		if self.origsurface.get_size() == self.currentres:
			self.surface = self.deepcopy(self.origsurface)
		else:
			self.surface = pygame.transform.scale(self.origsurface, self.currentres)
		self.backgroundarea = self.deepcopy(self.surface)

	def deepcopy(self, surface):
		s = pygame.Surface(surface.get_size())
		s.blit(surface, (0, 0))
		return s

	def setsurface(self, surface):
			if surface:
				self.origsurface = pygame.image.load(DATAPATH + surface)
				self.surface = pygame.transform.scale(self.origsurface, self.currentres)
				self.backgroundarea = self.deepcopy(self.surface)
			else:
				self.origsurface = pygame.Surface(self.currentres)
				self.surface = self.deepcopy(self.origsurface)
				self.backgroundarea = self.deepcopy(self.surface)

class GGZBoard:
	def __init__(self):
		self.conf = None
		self.game = None
		self.net = None
		self.modulelist = []
		self.modulefilelist = []
		self.ui = None
		self.ggzmode = 0
		self.ggzsuccess = 0
		self.shutdown = 0
		self.currentgame = None
		self.nextgame = None
		self.gamedirs = {}

	def ggzinit(self, ggzmode):
		self.ggzmode = ggzmode

	def rect(self, surface, color, x1, y1, w, h, bgcolor):
		tmp = pygame.Surface((w, h))
		tmp.fill(bgcolor)
		tmp.set_alpha(self.conf.alpha)
		surface.blit(tmp, (x1, y1))
		if color:
			surface.fill(color, ((x1, y1), (1, h)))
			surface.fill(color, ((x1, y1), (w, 1)))
			surface.fill(color, ((x1, y1 + h), (w, 1)))
			surface.fill(color, ((x1 + w, y1), (1, h)))

	def svgsurface(self, filename, width, height):
		if not filename:
			return None
		if filename[-4:] == ".png":
			return pygame.image.load(filename)
		if filename[0] != "/":
			# pyrsvgsdl needs absolute filenames
			filename = os.getcwd() + "/" + filename
		svg = rsvgsdl.render(filename, width, height)
		rawdata = svg.data()
		if rawdata:
			surface = pygame.image.fromstring(rawdata, (width, height), "RGBA")
		else:
			surface = pygame.Surface((width, height))
		return surface

	def walker(self, arg, dirname, fnames):
		ex = re.compile("^module_(\S+)\.py$")
		for file in fnames:
			m = ex.match(file)
			if m:
				self.gamedirs[m.group(1)] = dirname
				self.loadgame(m.group(1))
				if not self.ggzmode or self.ggzsuccess:
					self.modulefilelist.append(m.group(1))
					self.modulelist.append(self.game.name())
		self.game = None

	def load(self, gamename, list):
		os.path.walk(MODULEPATH, self.walker, None)
		os.path.walk(os.getenv("HOME") + "/.ggz/games/ggzboard", self.walker, None)

		if list:
			for (module, modulefile) in zip(self.modulelist, self.modulefilelist):
				moduledir = self.gamedirs.setdefault(modulefile, None)
				print "%-20s %s" % (module, "(" + moduledir + ")")
			sys.exit(0)

		if gamename:
			self.loadgame(gamename)

	def loadgame(self, gamename):
		dir = self.gamedirs.setdefault(gamename, None)
		try:
			(fileobj, filename, desc) = imp.find_module("module_" + gamename, [dir])
		except:
			print _("GGZBoard game %s not found") % gamename
			sys.exit(1)
		mod = imp.load_module("ggzboardgame", fileobj, filename, desc)
		fileobj.close()
		self.game = mod.ggzboardgame

		if self.ggzmode:
			try:
				(fileobj, filename, desc) = imp.find_module("net_" + gamename, None)
				mod = imp.load_module("ggzboardnet", fileobj, filename, desc)
				fileobj.close()
				self.net = mod.ggzboardnet
				self.ggzsuccess = 1
			except:
				self.net = None
				self.ggzsuccess = 0

		self.currentgame = gamename

	def main(self, fullscreen):
		self.conf = Conf()
		self.ui = GGZBoardUI(self.conf.resolution)

		if fullscreen:
			self.conf.fullscreen = 1

		pygame.init()
		pygame.display.set_caption(asciify(_("GGZBoard")))

		icon = pygame.image.load(DATAPATH + "common/icon.png")
		pygame.display.set_icon(icon)

		self.ui.initfonts()

		self.ui.screen = pygame.display.set_mode(self.ui.currentres, DOUBLEBUF)
		self.ui.setsurface(self.conf.background)
		if self.conf.fullscreen:
			self.ui.togglefullscreen()

		while not self.shutdown:
			if not self.game:
				self.intro()
			if self.game:
				self.rungame()
				self.game = None
				if self.nextgame:
					self.loadgame(self.nextgame)
					self.nextgame = None
				if self.ggzmode:
					self.shutdown = 1
			elif not self.shutdown:
				self.about()

	def selectscreen(self):
		ui = self.ui
		conf = self.conf
		game = self.game

		title = ui.font.render(_("GGZBoard: piece selection"), 1, (255, 200, 0))

		pygame.event.clear()

		updatescreen = 1

		x = -1
		y = -1
		selected = -1
		quit = 0

		(posx, posy) = pygame.mouse.get_pos()

		while quit == 0:
			pygame.event.pump()
			if updatescreen:
				event = pygame.event.poll()
			else:
				event = pygame.event.wait()

			if event.type == KEYDOWN:
				key = event.key
				if key == K_ESCAPE or pygame.event.peek(QUIT):
					break
				if key == K_f:
					self.ui.togglefullscreen()
					updatescreen = 1

			if event.type == MOUSEMOTION:
				(posx, posy) = event.pos

			if event.type == MOUSEBUTTONDOWN:
				w = ui.backgroundarea.get_width()
				h = ui.backgroundarea.get_height()
				x = conf.marginwidth
				y = h - 25 #h - conf.marginheight + 40
				if posx > x and posx < x + 150 and posy > y and posy < y + 20:
					updatescreen = 1
					selected = 1
					quit = 1
				#bx = 20 + i * conf.cellwidth + i * 10
				#by=200
				# i * c + i * 10 = i * (c + 10)
				if posy > 200 and posy < 200 + conf.cellheight:
					px = posx - 20
					if px > 0:
						i = int(px / (conf.cellwidth + 10))
						if px > i * conf.cellwidth + 10:
							if i < len(game.selection):
								print "I", i
								print game.selection
								return game.selection[i]

			if updatescreen:
				ui.backgroundarea = ui.deepcopy(ui.surface)
				ui.backgroundarea.blit(title, (20, 30))

				text = []
				text.append(_("Please select one of the following pieces:"))
				if game.help:
					for line in game.help:
						text.append(line)
				i = 0
				for line in text:
					img = ui.smallfont.render(line, 1, (255, 200, 0))
					ui.backgroundarea.blit(img, (30, i * 20 + 100 + 10))
					i += 1

				w = ui.backgroundarea.get_width()
				h = ui.backgroundarea.get_height()
				x = conf.marginwidth
				y = h - 25 #h - conf.marginheight + 40

				color = conf.tilecolor
				if selected == 1:
					(r, g, b) = color
					color = (min(r + 50, 255), min(g + 50, 255), min(b + 50, 255))
				self.rect(ui.backgroundarea, (255, 255, 255), x, y, 150, 20, color)
				img = ui.smallfont.render(_("Cancel selection"), 1, (255, 200, 0))
				ui.backgroundarea.blit(img, (x + 10, y + 1))

				i = 0
				for piece in game.selection:
					img = self.svgsurface(game.figure(piece), conf.cellwidth, conf.cellheight)
					if not img:
						img = game.figuregfx(piece)
					bx = 20 + i * conf.cellwidth + i * 10
					by = 200
					i += 1
					ui.backgroundarea.blit(img, (bx, by))
					#if j == oldy and i == oldx:
					#	overlay = pygame.Surface(tilepicture.get_size())
					#	overlay.fill((255, 255, 255))
					#	overlay.set_alpha(70)
					#	ui.backgroundarea.blit(overlay, (bx, by))

				ui.screen.blit(ui.backgroundarea, (0, 0))
				updatescreen = 0

				pygame.display.flip()

	def helpscreen(self):
		ui = self.ui
		conf = self.conf
		game = self.game

		pygame.display.set_caption(asciify(_("GGZBoard: help screen")))

		title = ui.font.render(_("GGZBoard: help screen"), 1, (255, 200, 0))

		pygame.event.clear()

		updatescreen = 1

		x = -1
		y = -1
		selected = -1
		quit = 0

		(posx, posy) = pygame.mouse.get_pos()

		while quit == 0:
			pygame.event.pump()
			if updatescreen:
				event = pygame.event.poll()
			else:
				event = pygame.event.wait()

			if event.type == KEYDOWN:
				key = event.key
				if key == K_ESCAPE or pygame.event.peek(QUIT):
					break
				if key == K_f:
					self.ui.togglefullscreen()
					updatescreen = 1

			if event.type == MOUSEMOTION:
				(posx, posy) = event.pos

			if event.type == MOUSEBUTTONDOWN:
				w = ui.backgroundarea.get_width()
				h = ui.backgroundarea.get_height()
				x = conf.marginwidth
				y = h - 25 #h - conf.marginheight + 40
				if posx > x and posx < x + 150 and posy > y and posy < y + 20:
					updatescreen = 1
					selected = 1
					quit = 1

			if updatescreen:
				ui.backgroundarea = ui.deepcopy(ui.surface)
				ui.backgroundarea.blit(title, (20, 30))

				text = []
				text.append(_("Common GGZBoard functions:"))
				text.append(_("a: restart a local game"))
				text.append(_("u: download new games, levels, themes"))
				text.append(_("p: display the player list"))
				text.append(_("s: produce a screen shot"))
				text.append(_("f: toggle fullscreen display"))
				text.append(_("ESC: quit a running game"))
				text.append("")
				text.append(_("Game-specific help:"))
				if game.help:
					for line in game.help:
						text.append(line)
				i = 0
				for line in text:
					img = ui.smallfont.render(line, 1, (255, 200, 0))
					ui.backgroundarea.blit(img, (30, i * 20 + 100 + 10))
					i += 1

				w = ui.backgroundarea.get_width()
				h = ui.backgroundarea.get_height()
				x = conf.marginwidth
				y = h - 25 #h - conf.marginheight + 40

				color = conf.tilecolor
				if selected == 1:
					(r, g, b) = color
					color = (min(r + 50, 255), min(g + 50, 255), min(b + 50, 255))
				self.rect(ui.backgroundarea, (255, 255, 255), x, y, 150, 20, color)
				img = ui.smallfont.render(_("Return to game"), 1, (255, 200, 0))
				ui.backgroundarea.blit(img, (x + 10, y + 1))

				ui.screen.blit(ui.backgroundarea, (0, 0))
				updatescreen = 0

				pygame.display.flip()

	def about(self):
		ui = self.ui
		conf = self.conf

		pygame.display.set_caption(asciify(_("GGZBoard: about screen")))

		title = ui.font.render(_("GGZBoard: about screen"), 1, (255, 200, 0))

		pygame.event.clear()

		updatescreen = 1

		x = -1
		y = -1
		selected = -1
		quit = 0

		(posx, posy) = pygame.mouse.get_pos()

		while quit == 0:
			pygame.event.pump()
			if updatescreen:
				event = pygame.event.poll()
			else:
				event = pygame.event.wait()

			if event.type == KEYDOWN:
				key = event.key
				if key == K_ESCAPE or pygame.event.peek(QUIT):
					break
				if key == K_f:
					self.ui.togglefullscreen()
					updatescreen = 1

			if event.type == MOUSEMOTION:
				(posx, posy) = event.pos

			if event.type == MOUSEBUTTONDOWN:
				x = posx
				y = posy
				if x > 20 and x < 300 + 20:
					if ((y - 100) % 50) < 40:
						selected = (y - 100) / 50
						updatescreen = 1
						if selected == 8:
							quit = 1

			if updatescreen:
				ui.backgroundarea = ui.deepcopy(ui.surface)
				ui.backgroundarea.blit(title, (20, 30))

				text = []
				text.append(_("GGZBoard: A multi-engine game container"))
				text.append(_("Copyright (C) 2004 - 2006 Josef Spillner <josef@ggzgamingzone.org>"))
				text.append("")
				text.append(_("GGZBoard contains several board games, each of which can be played"))
				text.append(_("either alone against the artificial intelligence (AI) or against"))
				text.append(_("other humans or AIs over the network, using the GGZ Gaming Zone system."))
				text.append(_("Each of the games provides an in-game helpscreen."))
				text.append("")
				text.append(_("More information can be found on the GGZBoard homepage:"))
				text.append(_("http://www.ggzgamingzone.org/gameclients/ggzboard/"))
				i = 0
				for line in text:
					img = ui.smallfont.render(line, 1, (255, 200, 0))
					ui.backgroundarea.blit(img, (30, i * 20 + 100 + 10))
					i += 1

				i = 8
				color = conf.tilecolor
				if i == selected:
					(r, g, b) = color
					color = (min(r + 50, 255), min(g + 50, 255), min(b + 50, 255))
				self.rect(ui.backgroundarea, (255, 255, 255), 20, i * 50 + 100, 300, 40, color)
				img = ui.smallfont.render(_("Return to main screen"), 1, (255, 200, 0))
				ui.backgroundarea.blit(img, (30, i * 50 + 100 + 10))

				ui.screen.blit(ui.backgroundarea, (0, 0))
				updatescreen = 0

				pygame.display.flip()

	def intro(self):
		ui = self.ui
		conf = self.conf

		pygame.display.set_caption(asciify(_("GGZBoard: game selection")))

		title = ui.font.render(_("GGZBoard: game selection"), 1, (255, 200, 0))

		pygame.event.clear()

		updatescreen = 1

		x = -1
		y = -1
		selected = -1
		gamename = None
		about = 0

		(posx, posy) = pygame.mouse.get_pos()

		while not gamename and not about:
			pygame.event.pump()
			if updatescreen:
				event = pygame.event.poll()
			else:
				event = pygame.event.wait()

			if event.type == KEYDOWN:
				key = event.key
				if key == K_ESCAPE or pygame.event.peek(QUIT):
					self.shutdown = 1
					updatescreen = 1
				if key == K_f:
					self.ui.togglefullscreen()
					updatescreen = 1

			if event.type == MOUSEMOTION:
				(posx, posy) = event.pos

			if event.type == MOUSEBUTTONDOWN:
				x = posx
				y = posy
				if x > 20 and x < 300 + 20:
					if ((y - 100) % 50) < 40:
						selected = (y - 100) / 50
						updatescreen = 1
						if selected < len(self.modulefilelist):
							gamename = self.modulefilelist[selected]
						elif selected == len(self.modulefilelist) + 1:
							about = 1
						elif selected == len(self.modulefilelist) + 2:
							self.shutdown = 1

			if updatescreen:
				ui.backgroundarea = ui.deepcopy(ui.surface)
				ui.backgroundarea.blit(title, (20, 30))

				i = 0
				for module in self.modulelist:
					color = conf.tilecolor
					if i == selected:
						(r, g, b) = color
						color = (min(r + 50, 255), min(g + 50, 255), min(b + 50, 255))
					self.rect(ui.backgroundarea, (255, 255, 255), 20, i * 50 + 100, 300, 40, color)

					img = ui.smallfont.render(module, 1, (255, 200, 0))
					ui.backgroundarea.blit(img, (30, i * 50 + 100 + 10))
					i += 1

				i += 1
				color = conf.tilecolor
				if i == selected:
					(r, g, b) = color
					color = (min(r + 50, 255), min(g + 50, 255), min(b + 50, 255))
				self.rect(ui.backgroundarea, (255, 255, 255), 20, i * 50 + 100, 300, 40, color)
				img = ui.smallfont.render(_("About..."), 1, (255, 200, 0))
				ui.backgroundarea.blit(img, (30, i * 50 + 100 + 10))

				i += 1
				color = conf.tilecolor
				if i == selected:
					(r, g, b) = color
					color = (min(r + 50, 255), min(g + 50, 255), min(b + 50, 255))
				self.rect(ui.backgroundarea, (255, 255, 255), 20, i * 50 + 100, 300, 40, color)
				img = ui.smallfont.render(_("Quit..."), 1, (255, 200, 0))
				ui.backgroundarea.blit(img, (30, i * 50 + 100 + 10))

				ui.screen.blit(ui.backgroundarea, (0, 0))
				updatescreen = 0

				pygame.display.flip()

			if self.shutdown:
				break

		if gamename:
			self.loadgame(gamename)

	def themeselection(self, themes):
		ui = self.ui
		conf = self.conf

		pygame.display.set_caption(asciify(_("GGZBoard: theme selection")))

		title = ui.font.render(_("GGZBoard: theme selection"), 1, (255, 200, 0))

		pygame.event.clear()

		updatescreen = 1

		x = -1
		y = -1
		selected = -1
		themename = None
		back = 0

		(posx, posy) = pygame.mouse.get_pos()

		while not themename and not back:
			pygame.event.pump()
			if updatescreen:
				event = pygame.event.poll()
			else:
				event = pygame.event.wait()

			if event.type == KEYDOWN:
				key = event.key
				if key == K_ESCAPE or pygame.event.peek(QUIT):
					self.shutdown = 1
					updatescreen = 1
				if key == K_f:
					self.ui.togglefullscreen()
					updatescreen = 1

			if event.type == MOUSEMOTION:
				(posx, posy) = event.pos

			if event.type == MOUSEBUTTONDOWN:
				x = posx
				y = posy
				if x > 20 and x < 300 + 20:
					if ((y - 100) % 50) < 40:
						selected = (y - 100) / 50
						updatescreen = 1
						if selected < len(themes.keys()):
							themename = themes.keys()[selected]
						elif selected == len(themes.keys()) + 1:
							back = 1

			if updatescreen:
				ui.backgroundarea = ui.deepcopy(ui.surface)
				ui.backgroundarea.blit(title, (20, 30))

				i = 0
				for theme in themes.keys():
					color = conf.tilecolor
					if i == selected:
						(r, g, b) = color
						color = (min(r + 50, 255), min(g + 50, 255), min(b + 50, 255))
					self.rect(ui.backgroundarea, (255, 255, 255), 20, i * 50 + 100, 300, 40, color)

					img = ui.smallfont.render(theme, 1, (255, 200, 0))
					ui.backgroundarea.blit(img, (30, i * 50 + 100 + 10))
					i += 1

				i += 1
				color = conf.tilecolor
				if i == selected:
					(r, g, b) = color
					color = (min(r + 50, 255), min(g + 50, 255), min(b + 50, 255))
				self.rect(ui.backgroundarea, (255, 255, 255), 20, i * 50 + 100, 300, 40, color)
				img = ui.smallfont.render(_("Back..."), 1, (255, 200, 0))
				ui.backgroundarea.blit(img, (30, i * 50 + 100 + 10))

				ui.screen.blit(ui.backgroundarea, (0, 0))
				updatescreen = 0

				pygame.display.flip()

		if themename:
			return themes[themename]

	def playernames(self):
		playernames = None
		if self.ggzsuccess:
			if self.net.playernames:
				playernames = self.net.playernames
		if not playernames:
			playernames = []
			playernames.append(username())
			for i in range(self.game.players - 1):
				playernames.append(_("AI #%s") % str(i + 1))
		return playernames

	def rungame(self):
		conf = self.conf
		game = self.game
		ui = self.ui
		net = self.net

		themes = {}
		themedirs = glob.glob(os.getenv("HOME") + "/.ggz/games/ggzboard/*/" + self.currentgame)
		for themedir in themedirs:
			theme = themedir.split("/")[-2]
			themes[theme] = themedir + "/../" # FIXME: hack!

		if len(themes) == 0:
			themepath = DATAPATH
		else:
			themes[_("(Default GGZBoard)")] = DATAPATH
			themepath = self.themeselection(themes)
			if not themepath:
				return

		game.init(themepath)

		if self.ggzsuccess:
			ret = net.connect()
			if ret < 0:
				self.ggzsuccess = 0

		self.ui.backgroundarea = self.ui.deepcopy(self.ui.surface)

		pygame.display.set_caption(asciify(_("GGZBoard: ") + game.name()))

		ggzstr = ""
		if self.ggzmode:
			ggzstr = _(" (running on GGZ)")
			if not self.ggzsuccess:
				ggzstr += _(" (unavailable)")
		title = ui.font.render(_("GGZBoard: ") + game.name() + ggzstr, 1, (255, 200, 0))

		pygame.event.clear()

		updatescreen = 1
		rescalescreen = 1

		board = game.board

		oldx = -1
		oldy = -1
		aiturn = 0
		lastturn = -1
		shift = 0
		sleep = 0
		skipplayer = 0
		selected = -1
		savex = -1
		savey = -1

		thinking = 0
		inputallowed = 1
		if self.ggzmode:
				inputallowed = 0
				#game.toggleplayer() # FIXME: reversi specific? (player is black originally)

		(posx, posy) = pygame.mouse.get_pos()

		while 1:
			if self.ggzsuccess:
				net.handle_network()
				if net.error():
					ggzstr = _(" (running on GGZ)")
					ggzstr += _(" (unavailable)")
					title = ui.font.render(_("GGZBoard: ") + game.name() + ggzstr, 1, (255, 200, 0))
					self.ggzsuccess = 0
					updatescreen = 1
				else:
					if net.allowed() != inputallowed:
						inputallowed = net.allowed()
						updatescreen = 1
					if net.thinking() != thinking:
						thinking = net.thinking()
						updatescreen = 1
					move = net.netmove()
					if move:
						(frompos, topos) = move
						game.toggleplayer()
						game.domove(frompos, topos)
						playsound("oppmove")
						updatescreen = 1

			pygame.event.pump()
			if updatescreen or self.ggzsuccess:
				event = pygame.event.poll()
			else:
				event = pygame.event.wait()

			if rescalescreen:
				if game.autoscaletiles:
					conf.cellwidth = (ui.currentres[1] - 150) / game.width
					conf.cellheight = (ui.currentres[1] - 150) / game.height

				width = (conf.cellwidth + conf.cellspace)
				height = (conf.cellheight + conf.cellspace)

				rescalescreen = 0
				updatescreen = 1

			if event.type == KEYDOWN:
				key = event.key
				if key == K_ESCAPE or pygame.event.peek(QUIT):
					break
				if key == K_f:
					self.ui.togglefullscreen()
					rescalescreen = 1
				#if key == K_r:
				#	updatescreen = 1
				if key == K_u:
					#sdlnewstuff.gethotnewstuff(game.name())
					engine = sdlnewstuff.ghnsengine()
					engine.conf.providers = "http://www.ggzcommunity.org/hotstuff/providers.xml"
					engine.conf.installdir = ".ggz/games/ggzboard"
					engine.conf.alpha_darkness = 180
					engine.conf.color_background = (50, 50, 150)
					engine.conf.color_foreground = (255, 255, 255)
					engine.conf.color_box = (100, 100, 100)
					engine.conf.color_activebox = (200, 200, 200)
					engine.conf.color_titlebox = (255, 200, 0)
					engine.conf.color_action = (120, 255, 120)
					files = engine.gethotnewstuff("ggzboard")
				if key == K_p:
					playertable.show()
				if key == K_s:
					pygame.image.save(ui.screen, "ggzboard-screenshot.bmp")
				if key == K_a:
					self.nextgame = self.currentgame
					break

			if event.type == MOUSEMOTION:
				(posx, posy) = event.pos

			if event.type == MOUSEBUTTONDOWN:
				w = ui.backgroundarea.get_width()
				h = ui.backgroundarea.get_height()
				x = w - conf.marginwidth
				y = h - 25 #h - conf.marginheight + 40
				for i in range(4):
					xpos = x - (4 - i) * 160
					if posx > xpos and posx < xpos + 150 and posy > y and posy < y + 20:
						selected = i
						updatescreen = 1

			if event.type == MOUSEBUTTONDOWN and inputallowed and not thinking:
				considered = 0
				if game.intersections:
					x = (posx - conf.marginwidth + 5) % width
					y = (posy - conf.marginheight + 5) % height
					if x < 10 and y < 10:
						x = ((posx - conf.marginwidth + 5) / width)
						y = ((posy - conf.marginheight + 5) / height)
						considered = 1
				else:
					x = (posx - conf.marginwidth) % width
					y = (posy - conf.marginheight) % height
					if x < conf.cellwidth and y < conf.cellheight:
						x = ((posx - conf.marginwidth) / width)
						y = ((posy - conf.marginheight) / height)
						considered = 1
				if considered:
					if x >= game.width or y >= game.height or x < 0 or y < 0:
						considered = 0
					elif game.boardstyle and game.noemptytiles:
						if not game.boardstyle[y][x]:
							considered = 0
				if considered:
					if oldx == -1:
						if game.setonly or "selectpiece" in dir(game):
							# XXX: sync
							game.selectpiece((x, y))
							if not game.selection:
								if game.setonly:
									ret = game.trymove(None, (x, y))
									if ret:
										if self.ggzmode:
											net.domove(None, (x, y))
											playsound("move")
										else:
											game.domove(None, (x, y))
											playsound("move")
											game.toggleplayer()
											aiturn = 1
											thinking = 1
								else:
									# failed selectpiece() for normal games
									oldx = x
									oldy = y
									if game.boardhints:
										game.initmove(x, y)
							else:
								savex = x
								savey = y
						else:
							oldx = x
							oldy = y
							if game.boardhints:
								game.initmove(x, y)
						updatescreen = 1
					else:
						frompos = (oldx, oldy)
						topos = (x, y)
						ret = game.trymove(frompos, topos)
						print "RET(trymove)", ret
						if ret:
							if self.ggzmode:
								net.domove(frompos, topos)
								playsound("move")
							else:
								game.domove(frompos, topos)
								playsound("move")
								game.toggleplayer()
								aiturn = 1
								thinking = 1

						updatescreen = 1

						oldx = -1
						oldy = -1

			if self.ggzsuccess:
				if net.modified:
					updatescreen = 1
					net.modified = 0

			if updatescreen:
				ui.backgroundarea = ui.deepcopy(ui.surface)
				ui.backgroundarea.blit(title, (20, 30))

				if lastturn != game.turnplayer and not game.over():
					lastturn = game.turnplayer
					if game.dice and not self.ggzsuccess:
						ret = game.rolldice()
						playsound("dice")
						sleep = 2
						if ret == 0:
							skipplayer = 1

				if not inputallowed:
					w = ui.backgroundarea.get_width()
					h = ui.backgroundarea.get_height()
					x = w - conf.marginwidth
					y = h - conf.marginheight - 40
					self.rect(ui.backgroundarea, None, 0, 0, w, h, (0, 0, 0))

					caption = ui.smallfont.render(_("Game over!"), 1, (255, 200, 0))
					ui.backgroundarea.blit(caption, (x - caption.get_width(), y))
					if game.winner is not None:
						playsound("winner")
						winner = self.playernames()[game.winner]
						caption = ui.smallfont.render(_("The winner is %s") % winner, 1, (255, 200, 0))
						ui.backgroundarea.blit(caption, (w - caption.get_width() - conf.marginwidth, y + 20))

				if game.boardstyle:
					# FIXME: implicit linking of board images to board size variables
					conf.cellwidth = game.boardwidth
					conf.cellheight = game.boardheight
					width = (conf.cellwidth + conf.cellspace)
					height = (conf.cellheight + conf.cellspace)

				if "boardbackground" in dir(game):
					w = conf.cellwidth * game.width
					h = conf.cellheight * game.height
					img = self.svgsurface(game.boardbackground, w, h)
					ui.backgroundarea.blit(img, (conf.marginwidth, conf.marginheight))

				for j in range(0, game.height):
					for i in range(0, game.width):
						color = conf.tilecolor
						tilepicture = None
						if game.swaptiles and (i + j) % 2:
							color = conf.darktilecolor
						if game.boardstyle:
							style = game.boardstyle[j][i]
							if style:
								if len(style) == 3:
									(r, g, b) = color
									(rd, gd, bd) = style
									color = (min(r + rd, 255), min(g + gd, 255), min(b + bd, 255))
								else:
									tilepicture = pygame.image.load(game.datapath + style)
							elif game.noemptytiles:
								continue
						if j == oldy and i == oldx:
							(r, g, b) = color
							color = (min(r + 50, 255), min(g + 50, 255), min(b + 50, 255))
						sx = i * width + conf.marginwidth
						sy = j * height + conf.marginheight
						if not game.intersections or (j != game.height - 1 and i != game.width - 1):
							self.rect(ui.backgroundarea, (255, 255, 255), sx, sy, conf.cellwidth, conf.cellheight, color)
							if tilepicture:
								ui.backgroundarea.blit(tilepicture, (sx, sy))
							if game.boardhints:
								hint = game.boardhints[j][i]
								if hint == 1:
									self.rect(ui.backgroundarea, (255, 255, 255), sx + 2, sy + 2, conf.cellwidth - 4, conf.cellheight - 4, color)
						if board[j][i]:
							img = self.svgsurface(game.figure(board[j][i]), conf.cellwidth, conf.cellheight)
							if not img:
								img = game.figuregfx(board[j][i])
							bx = sx
							by = sy
							if game.intersections:
								bx = sx - conf.cellwidth / 2
								by = sy - conf.cellwidth / 2
							ui.backgroundarea.blit(img, (bx, by))
							if j == oldy and i == oldx:
								if tilepicture:
									overlay = pygame.Surface(tilepicture.get_size())
									overlay.fill((255, 255, 255))
									overlay.set_alpha(70)
									ui.backgroundarea.blit(overlay, (bx, by))
							# FIXME: boardhints is used twice
							if game.boardhints:
								hint = game.boardhints[j][i]
								if hint == 1:
									self.rect(ui.backgroundarea, (255, 255, 255), sx + 2, sy + 2, conf.cellwidth - 4, conf.cellheight - 4, color)

				playernames = self.playernames()
				if playernames:
					w = ui.backgroundarea.get_width()
					h = ui.backgroundarea.get_height()
					i = 0
					for player in playernames:
						x = w - conf.marginwidth
						y = conf.marginheight + i * 50
						playerstr = _("Player %s:") % str(i + 1)
						if i == game.turnplayer:
							playerstr = "*** " + playerstr
						caption = ui.smallfont.render(playerstr, 1, (255, 200, 0))
						ui.backgroundarea.blit(caption, (x - caption.get_width(), y))
						playercolour = (255, 200, 0)
						if game.playercolours:
							playercolour = game.playercolours[i]
						player = ui.smallfont.render(player, 1, playercolour)
						ui.backgroundarea.blit(player, (x - player.get_width(), y + 18))
						i += 1

				if game.dice:
					w = ui.backgroundarea.get_width()
					h = ui.backgroundarea.get_height()
					i = 3
					for dice in game.dice:
						x = w - conf.marginwidth
						y = h - conf.marginheight - i * 30
						caption = ui.smallfont.render(_("Dice: ") + str(dice), 1, (255, 200, 0))
						ui.backgroundarea.blit(caption, (x - caption.get_width(), y))
						i += 1

						# FIXME!
						img = self.svgsurface(DATAPATH + "madn/dice-" + str(dice) + ".svg", 50, 50)
						ui.backgroundarea.blit(img, (x - caption.get_width() - 100, y - 20))

				if thinking:
					w = ui.backgroundarea.get_width()
					h = ui.backgroundarea.get_height()
					x = w - conf.marginwidth
					y = h - conf.marginheight - 60
					caption = ui.smallfont.render(_("Thinking..."), 1, (255, 200, 0))
					ui.backgroundarea.blit(caption, (x - caption.get_width(), y))

				w = ui.backgroundarea.get_width()
				h = ui.backgroundarea.get_height()
				x = w - conf.marginwidth
				y = h - 25 #h - conf.marginheight + 40

				i = 0
				itemlist = (_("Themes & games"), _("Player list"), _("Game help"), _("Main menu"))
				for caption in itemlist:
					color = conf.tilecolor
					if i == selected:
						(r, g, b) = color
						color = (min(r + 50, 255), min(g + 50, 255), min(b + 50, 255))
					xpos = x - (len(itemlist) - i) * 160
					self.rect(ui.backgroundarea, (255, 255, 255), xpos, y, 150, 20, color)
					img = ui.smallfont.render(caption, 1, (255, 200, 0))
					ui.backgroundarea.blit(img, (xpos + 10, y + 1))
					i += 1

				ui.screen.blit(ui.backgroundarea, (0, 0))
				updatescreen = 0

				pygame.display.flip()

			if inputallowed and game.over():
				aiturn = 0
				inputallowed = 0
				updatescreen = 1

			if aiturn and not skipplayer:
				if self.ggzsuccess:
					aiturn = 0
				else:
					if game.turnplayer == game.players - 1:
						aiturn = 0
						thinking = 0
				(ret, frompos, topos) = game.aimove()
				print "RET(find)", ret
				if ret:
					game.domove(frompos, topos)
					playsound("oppmove")
					game.toggleplayer()
				else:
					game.toggleplayer()

				updatescreen = 1

				oldx = -1
				oldy = -1

			if sleep:
				pygame.time.delay(500)
				sleep -= 0.5
				if sleep < 0:
					sleep = 0

			if skipplayer:
				if game.turnplayer == 0:
					aiturn = 1
					thinking = 1
				elif game.turnplayer == game.players - 1:
					aiturn = 0
					thinking = 0
				game.toggleplayer()
				skipplayer = 0
				updatescreen = 1

			if game.selection:
				sel = self.selectscreen()
				print "SEL", sel
				updatescreen = 1
				game.selection = None
				if sel:
					x = savex
					y = savey
					game.selected = sel
					# FIXME: merge with mouse-press stuff
					ret = game.trymove(None, (x, y))
					if ret:
						if self.ggzmode:
							net.domove(None, (x, y))
							playsound("selmove")
						else:
							game.domove(None, (x, y))
							playsound("selmove")
							game.toggleplayer()
							aiturn = 1
							thinking = 1

			if selected == 0:
				sdlnewstuff.gethotnewstuff(game.name())
			elif selected == 1:
				playertable.show()
			elif selected == 2:
				self.helpscreen()
			elif selected == 3:
				break
			if selected != -1:
				selected = -1
				updatescreen = 1

if __name__ == "__main__":
	ggzmode = 0
	help = 0
	version = 0
	gamename = None
	param = 0
	fullscreen = 0
	list = 0

	for i in range(1, len(sys.argv)):
		if sys.argv[i] == "-g" or sys.argv[i] == "--ggz":
			ggzmode = 1
		elif sys.argv[i] == "-h" or sys.argv[i] == "--help":
			help = 1
		elif sys.argv[i] == "-v" or sys.argv[i] == "--version":
			version = 1
		elif sys.argv[i] == "-f" or sys.argv[i] == "--fullscreen":
			fullscreen = 1
		elif sys.argv[i] == "-G" or sys.argv[i] == "--game":
			if i < len(sys.argv) - 1:
				gamename = sys.argv[i + 1]
				param = 1
			else:
				print _("Argument required for %s.") % sys.argv[i]
				sys.exit(1)
		elif sys.argv[i] == "-l" or sys.argv[i] == "--list":
			list = 1
		else:
			if param:
				param = 0
			elif gamename:
				print _("Unknown option: %s") % sys.argv[i]
				sys.exit(1)
			else:
				gamename = sys.argv[i]

	if help:
		print _("GGZBoard - common board game client for GGZ")
		print _("Copyright (C) 2004 - 2006 Josef Spillner <josef@ggzgamingzone.org>")
		print _("Published under GNU GPL conditions")
		print ""
		print _("Options:")
		print _("[-h | --help           ] Display this game help")
		print _("[-v | --version        ] Show version information")
		print _("[-g | --ggz            ] Request game in GGZ mode")
		print _("[-G | --game <gamename>] Skip intro screen and launch game directly")
		print _("[-l | --list           ] List available games and their location")
		print _("[-f | --fullscreen     ] Start in fullscreen mode")
		sys.exit(0)

	if version:
		print "0.0.3"
		sys.exit(0)

	print ">>>>> ggzboard: starting with datapath", DATAPATH, "modulepath", MODULEPATH
	print ">>>>> ggzboard: args", sys.argv

	core = GGZBoard()
	core.ggzinit(ggzmode)
	core.load(gamename, list)
	core.main(fullscreen)

