#!/usr/bin/env python

import sys
import threading
import string
import re
import math
import time
import random

opcions_robot = {
	'SIGNAL':					2,
	'SEND_SIGNAL':				0,
	'SEND_ROTATION_REACHED':	1,
	'USE_NON_BLOCKING':			3
}

opcions_joc = {
	'ROBOT_MAX_ROTATE':				0,
	'ROBOT_CANNOT_MAX_ROTATE':		1,
	'ROBOT_RADAR_MAX_ROTATE':		2,
	'ROBOT_MAX_ACCELERATION':		3,
	'ROBOT_MIN_ACCELERATION':		4,
	'ROBOT_START_ENERGY':			5,
	'ROBOT_MAX_ENERGY':				6,
	'ROBOT_ENERGY_LEVELS':			7,
	'SHOT_SPEED':					8,
	'SHOT_MIN_ENERGY':				9,
	'SHOT_MAX_ENERGY':				10,
	'SHOT_ENERGY_INCREASE_SPEED':	11,
	'TIMEOUT':						12,
	'DEBUG_LEVEL':					13,
	'SEND_ROBOT_COORDINATES':		14
}

tipus_objecte = {
	'NO_OBJECT':			-1,
	'ROBOT':				0,
	'SHOT':					1,
	'WALL':					2,
	'COOKIE':				3,
	'MINE':					4,
	'LAST_OBJECT_TYPE':		5
}

parts_robot = {
	'ROBOT':	1,
	'CANO':		2,
	'RADAR':	4
}

############################################################
#	Classe RealTimeBattle
############################################################
		
class RealTimeBattle:
	def __init__(self):
		self.entrada = sys.stdin
		self.sortida = sys.stdout
		self.events = {}
		self.robots_restants = None
		
		self.registre = open("/tmp/robot.log", "w")
		
		self.afegir_gestor_event("RobotsLeft", self.event_robots_restants)
		
	def enviar_missatge(self, missatge):
		# self.enregistrar("SORTIDA: \"" + missatge + "\"")
		
		self.sortida.write(missatge + "\n")
		self.sortida.flush()
		
	def enregistrar(self, missatge):
		if self.registre:
			self.registre.write(missatge + "\n")
		
	def processar_events(self):
		while 1:
			missatge = self.entrada.readline()
			
			# EOF?
			if missatge == '': break
			
			# Eliminem els enters finals
			while missatge[-1] == '\n': missatge = missatge[:-1]
			
			# self.enregistrar("ENTRADA: \"" + missatge + "\"")
			
			# Processem el missatge
			metode = None
			arguments = []
			missatge_parts = string.split(missatge)
			index = 0
			for missatge_part in missatge_parts:
				if not missatge_part == " ":
					if index == 0:
						metode = missatge_part
					else:
						arguments.append(eval(missatge_part))
					
					index += 1
					
			# Mirem si hi ha algun mtode registrat per l'event i cridem cadascun d'ells
			if metode != None and self.events.has_key(metode):
				for gestor in self.events[metode]:
					gestor(*arguments)
			
	def afegir_gestor_event(self, event, gestor):
		if self.events.has_key(event):
			self.events[event].append(gestor)
		else:
			self.events[event] = [gestor]
			
	############################################################
	#	Events
	############################################################
	
	def event_robots_restants(self, robots):
		self.robots_restants = robots
		
############################################################
#	Classe Robot
############################################################
		
class Robot:
	def __init__(self, nom, color = "000000"):
		self.rtb = RealTimeBattle()
		self.nom = nom
		self.color = color
		self.cano = RobotCano(self)
		self.radar = RobotRadar(self)
		
		self.rtb.enviar_missatge("RobotOption %d 0" % opcions_robot['USE_NON_BLOCKING'])
		
		# Enregistrem els events ms genrics
		self.rtb.afegir_gestor_event("Initialize", self.event_inicialitzar)
		self.rtb.afegir_gestor_event("Energy", self.event_obtenir_nivell_energia)
		self.rtb.afegir_gestor_event("Warning", self.event_advertencia)
		
	############################################################
	#	Funcions pbliques
	############################################################
		
	def comencar(self):
		# Llencem un fil que va processant els events
		threading.Thread(target = self.rtb.processar_events).start()
		
	def accelerar(self, acceleracio):
		self.rtb.enviar_missatge("Brake 0")
		self.rtb.enviar_missatge("Accelerate %d" % acceleracio)
		
	def frenar(self, quantitat):
		self.rtb.enviar_missatge("Brake %d" % quantitat)
		
	def rotar_fins(self, angle, velocitat):
		self.rtb.enviar_missatge("RotateAmount %d %d %d" % (parts_robot['ROBOT'], velocitat, angle))
		
	def rotar(self, velocitat):
		self.rtb.enviar_missatge("Rotate %d %d" % (parts_robot['ROBOT'], velocitat))
		
	def rotar_quantitat(self, velocitat, angle):
		self.rtb.enviar_missatge("RotateAmount %d %f %f" % (parts_robot['ROBOT'], velocitat, angle))
		
	############################################################
	#	Events
	############################################################
		
	def event_inicialitzar(self, inici):
		if inici:
			self.rtb.enviar_missatge("Name " + self.nom)
			self.rtb.enviar_missatge("Colour " + self.color)
			
	def event_obtenir_nivell_energia(self, energia):
		self.energia = energia
		
	def event_advertencia(self, tipus, missatge):
		advertencia = "ADVERTENCIA: %s" % missatge
		
		self.rtb.enregistrar(advertencia)
		
############################################################
#	Classe RobotCano
############################################################
		
class RobotCano:
	def __init__(self, robot):
		self.robot = robot
		self.angle = 0
		
	def disparar(self, potencia):
		self.robot.rtb.enregistrar("Disparo a %d" % potencia)
		self.robot.rtb.enviar_missatge("Shoot %d" % potencia)
		
	def escombrada(self, velocitat, angle_esquerre, angle_dret):
		self.robot.rtb.enviar_missatge("Sweep %d %f %f %f" % (parts_robot['CANO'], velocitat, angle_esquerre, angle_dret))
		
############################################################
#	Classe RobotRadar
############################################################

class RobotRadar:
	def __init__(self, robot):
		self.robot = robot
		self.angle = 0
		
	def rotar(self, velocitat):
		self.rtb.enviar_missatge("Rotate %d %f" % (parts_robot['RADAR'], velocitat))
		
	def rotar_quantitat(self, velocitat, angle):
		self.rtb.enviar_missatge("RotateAmount %d %f %f" % (parts_robot['RADAR'], velocitat, angle))
		
	def escombrada(self, velocitat, angle_esquerre, angle_dret):
		self.robot.rtb.enviar_missatge("Sweep %d %f %f %f" % (parts_robot['RADAR'], velocitat, angle_esquerre, angle_dret))

############################################################
#	Classe RobotAlmogaver
############################################################
		
class RobotAlmogaver(Robot):
	def __init__(self, *arguments):
		Robot.__init__(self, *arguments)
	
		# Enregistrem els events
		self.rtb.afegir_gestor_event("GameStarts", self.event_joc_comenca)
		self.rtb.afegir_gestor_event("Radar", self.event_radar)
		
		self.direccio = -math.pi
		
	############################################################
	#	Events
	############################################################
		
	def event_joc_comenca(self):
		# El robot comena avanant (fins trobar una paret)
		self.accelerar(1)
		
	def event_radar(self, distancia, objecte, angle):
		# Evitem els obstacles
		if objecte == tipus_objecte['WALL']:
			if distancia < 6:
				if random.randint(0, 400) == 0:
					self.direccio *= -1
			
				self.accelerar(0)
				self.frenar(1)
				self.rotar_quantitat(1, self.direccio)
			else:
				self.accelerar(1)
				self.rotar(0)
				
		if objecte == tipus_objecte['MINE']:
			self.cano.disparar(1)		
			
		if objecte == tipus_objecte['ROBOT']:
			self.cano.disparar(1)

############################################################
#	Inici
############################################################
		
if __name__ == '__main__':
	robot = RobotAlmogaver("ferriv", "0000ff")
	robot.comencar()
