# -*- coding: utf-8 -*-
"""
UTc! module: src.lobby.game

Purpose
=======
 Manages forked game processes in a dedicated thread.
 
Legal
=====
 All code, unless otherwise indicated, is original, and subject to the
 terms of the GPLv3, which is provided in COPYING.
 
 (C) Neil Tallim, 2009
"""
import os
import subprocess
import threading

class Game(threading.Thread):
	"""
	A thread dedicated to managing a forked UTc! game process.
	"""
	_callback = None #: The function to invoke when the game ends.
	_popen = None #: The game process.
	
	def __init__(self, callback, python, player_name, host, port, fps, width, height, fsaa, render_mode, sound, hud_red, hud_green, hud_blue):
		"""
		Initialises and launches the game process.
		
		@type callback: callable
		@param callback: The function to be invoked when the game terminates.
		@type python: basestring
		@param python: The shell-recognizable Python binary identifier.
		@type player_name: basestring
		@param player_name: The name of the player to use to identify to the UTc!
		    server.
		@type host: basestring
		@param host: The address of the server that is hosting the game.
		@type port: basestring
		@param port: The port on the host at which the game is running.
		@type fps: basestring
		@param fps: The framerate at which to run the game.
		@type width: basestring
		@param width: The width, in pixels, of the game window.
		@type height: basestring
		@param height: The height, in pixels, of the game window.
		@type fsaa: bool
		@param fsaa: True if FSAA is to be used.
		@type render_mode: int
		@param render_mode: The render style identifier that determines how the
		    game will look.
		@type sound: bool
		@param sound: True if sounds are to be used.
		@type hud_red: int
		@param hud_red: The red value of the HUD.
		@type hud_green: int
		@param hud_green: The green value of the HUD.
		@type hud_blue: int
		@param hud_blue: The blue value of the HUD.
		"""
		threading.Thread.__init__(self)
		self.setDaemon(False)
		
		self._callback = callback
		args = [
		 python, 'game.py', player_name,
		 '--host', host, '--port', port,
		 '--fps', fps, '--width', width, '--height', height,
		 '--render_mode', render_mode,
		 '--hud_red', hud_red, '--hud_green', hud_green, '--hud_blue', hud_blue
		]
		if fsaa:
			args.append('--fsaa')
		if sound:
			args.append('--sound')
		self._popen = subprocess.Popen(args, stdout=subprocess.PIPE)
		
	def run(self):
		"""
		Waits until the game terminates, then informs the GUI using the provided
		callback function.
		
		If the game provided an error message upon termination, that is presented
		to the GUI as part of the callback.
		"""
		self._popen.wait()
		
		output = [line for line in self._popen.stdout.read().split(os.linesep) if line.strip()]
		if output:
			output = output[-1]
			if output == 'OKAY':
				output = None
			elif output == ')':
				output = "An unknown OpenGL error occurred. Try using 'basic' rendering."
		else:
			output = "Game process did not provide a termination code."
		try:
			self._callback(output)
		except Exception, e:
			print e
			