#!/usr/bin/env python
# encoding: iso-8859-15
#
#Minë. Mundo Interactivo-Narrativo en Español [Tierra-Media]
#Copyright (C) 2002  Pablo Ruiz Múzquiz
#
#
#This program is free software; you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation; either version 2 of the License, or
#(at your option) any later version.
#
#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License
#along with this program; if not, write to the Free Software
#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#
#Fichero: InterfazPNJ.py

"""Clase InterfazPNJ."""

import logging
from utils import *
import Controlador
import FechaHoraMine
import CronoMine

log = logging.getLogger("PNJ")

class InterfazPNJ(Controlador.Controlador):
    """Interfaz controla directamente a una instancia de clase PersonajeNoJugador.

    El control es automático, no necesita intervención de ningún jugador. De momento
    es muy básico, sólo sabe quedarse quieto en una sala y responder a un ataque.
    
    La clase funciona como una maquina de estados, que acepta los eventos de
    Controlador, y reacciona apropiadamente en cada caso.

    Contiene los siguientes atributos:
    
     - __personaje (Personaje): el personaje que controlamos
     - __estado (string): el estado en el que se encuentra el interfaz
     - __sub_estado (int): algunos estados tienen fases intermedias. Si no, None.
     - __crono (CronoMine): cronometro usado opcionalmente
     - __oponente (Personaje): otro personaje con quien el nuestro está combatiendo
    
     Los siguientes atributos provocan ajustes automáticos al ser modificados:

     - __personaje: se modifica también al personaje para que tenga a este interfaz como
                  controlador
     """


    def __init__(self):
	"""Crea un interfaz nuevo para un personaje recien creado o cargado de disco."""
	self.__personaje = None
	self.__estado = ""
	self.__sub_estado = None
        self.__crono = None
        self.__oponente = None
        self.estado_normal()
            
            
    def __del__(self):
        """Realiza ajustes automáticos al ser destruido"""
	if self.__personaje != None:
            self.liberar_personaje()


    def personaje(self):
    	return self.__personaje


    def controlar_personaje(self, personaje):
        """Pasar a estar controlando un personaje.
	
	Requiere:
	  self.__personaje == None
	  personaje != None
	"""
        self.__personaje = personaje
	self.__personaje.controlar(self)


    def liberar_personaje(self):
        """Soltar al personaje actual y dejarlo libre.

	Requiere:
	  self.__personaje != None
	"""
        self.__personaje.liberar()
	self.__personaje = None
        
        
    # -------------------------------------------------
    # Metodos de manejo de eventos (ver controlador.py)
    # -------------------------------------------------
    
    def entra_personaje(self, personaje):
        pass # algún día se puede hacer que el PNJ salude o amenace
                        
                        
    def sale_personaje(self, personaje, nombre_sala_destino):
        pass  # a lo mejor se puede hacer que se despida
                        
                        
    def habla_personaje(self, personaje, mensaje):
        pass  # se podría hacer que los PNJ entiendan conversaciones


    def susurra_personaje(self, personaje, mensaje):
        pass  # se podría hacer que los PNJ entiendan conversaciones
 
    
    def grita_personaje(self, personaje, mensaje):
        pass  # id

                        
    def actua_personaje(self, personaje, accion):
        pass  # se podría hacer que los PNJ reaccionen a acciones
 

    def actua_individual_personaje(self, personaje, accion):
        pass  # id
                       

    def actua_uno_mismo(self, accion):
        pass  # aqui no se me ocurre nada
                        

    def actua_global_personaje(self, personaje, accion):
        pass  # se podría hacer que los PNJ reaccionen a acciones
 

    def suceso_entorno(self, mensaje):
	pass # aqui tampoco se me ocurre nada, en principio
       
    
    def ataca_personaje(self, personaje, result):
        pass
#%% funciones de combate desactivadas
#%%        # Llamar a la función correspondiente según estado
#%%        nombre_func = "ataque_" + self.estado
#%%        if self.sub_estado != None: nombre_func += "_" + str(self.sub_estado)
#%%        
#%%        func = getattr(self, nombre_func, None)
#%%        if func == None:
#%%            log.error("Recibido ataque en estado " + self.estado + \
#%%                      ((self.sub_estado != None and "_" + str(self.sub_estado)) or "") + \
#%%                      ((self.personaje != None and  "(" + self.personaje.nombre + ")") or "")
#%%        else:
#%%            func(personaje, result)


    def movimiento_automatico(self):
	pass


    def paga_personaje(self, personaje, monedas):
	pass
        
        
    def lanzar_crono(self, segundos_vencimiento):
        """Lanza un cronometro que vence al cabo del numero de segundos indicado.
        
        Se admiten decimales.
        """
        import Mundo
        if self.crono != None: self.crono.parar()
        self.crono = CronoMine.crear(Mundo.cronoMine_control,
	                             FechaHoraMine.crear_rel(segundos=segundos_vencimiento),
			             self.vencimiento)
        
        
    def vencimiento(self, crono):
        """Metodo llamado cuando vence el cronometro."""
        
        self.crono = None
        
        # Llamar a la función correspondiente según estado
        nombre_func = "vencimiento_" + self.estado
        if self.sub_estado != None: nombre_func += "_" + str(self.sub_estado)

        func = getattr(self, nombre_func, None)
        if func == None:
	    log.error("Recibido vencimiento en estado %s%s%s" %
		      (self.estado,
		       (self.sub_estado != None and "_" + str(self.sub_estado)) or "",
                       (self.personaje != None and  "(" + self.personaje.nombre + ")") or ""))
        else:
            func()
        
        
    # -------------
    # ESTADO NORMAL
    # -------------


    def estado_normal(self):
        self.estado = "normal"
        self.sub_estado = None
            
            
#%% funciones de combate desactivadas
#%%    def ataque_normal(self, personaje, result):
#%%        # Al recibir un ataque, pasamos inmediantamente a estado combate
#%%        
#%%        self.oponente = personaje
#%%        self.cbt_empieza_combate_defiendes()
#%%        self.cbt_te_pegan(result)
#%%        
#%%        if (self.personaje.estado == "muerto") or (self.oponente.estado == "muerto"):
#%%            self.cbt_termina_combate()
#%%            self.estado_normal()
#%%        else:
#%%            # Al poner un crono de 3 segundos, el combate funciona como
#%%            # una sucesion de golpes alternados cada 3 segundos.
#%%            self.lanzar_crono(3)
#%%            self.estado_combate()
#%%
#%%
#%%    # --------------
#%%    # ESTADO COMBATE
#%%    # --------------
#%%            
#%%            
#%%    def estado_combate(self):
#%%        self.estado = "combate"
#%%        self.sub_estado = None
#%%
#%%
#%%    def ataque_combate(self, oponente, result):
#%%        self.cbt_te_pegan(result)        
#%%        if (self.personaje.estado == "muerto") or (self.oponente.estado == "muerto"):
#%%            self.cbt_termina_combate()
#%%            self.estado_normal()
#%%        else:
#%%            self.estado_combate()
#%%            
#%%        
#%%    def vencimiento_combate(self):
#%%        self.cbt_pegar()        
#%%        if (self.personaje.estado == "muerto") or (self.oponente.estado == "muerto"):
#%%            self.cbt_termina_combate()
#%%            self.estado_normal()
#%%        else:
#%%            self.lanzar_crono(6)
#%%            self.estado_combate()           
#%%        
#%%        
#%%    def cbt_empieza_combate_defiendes(self):
#%%        pass
#%%
#%%        
#%%    def cbt_pegar(self):
#%%        self.personaje.hablar("\n" + color(33) + "\n" + self.personaje.nombre + 
#%%                              " ataca a " + self.oponente.nombre + finl)
#%%        
#%%        result = self.personaje.ataque_fisico(self.oponente)
#%%        
#%%        if result == Personaje.ATAQUE_EXITO:
#%%            self.personaje.hablar(self.personaje.nombre + " ha conseguido golpear")
#%%        elif result == Personaje.ATAQUE_FALLADO:
#%%            self.personaje.hablar(self.personaje.nombre + " ha fallado, su ataque no hace nada")
#%%        elif result == Personaje.ATAQUE_CRITICO:
#%%            self.personaje.hablar(self.personaje.nombre + " ha ejecutado un golpe impresionante")
#%%        elif result == Personaje.ATAQUE_PIFIA:
#%%            self.personaje.hablar("¡" + self.personaje.nombre + " ha fallado estrepitosamente, se daña a si mismo/a!")
#%%        else:
#%%            print "ERROR: recibido resultado de combate " + str(result) + \
#%%                  " (" + self.personaje.nombre + ")"
#%%                  
#%%        self.personaje.hablar("A " + self.personaje.nombre + " le quedan " + 
#%%                              str(self.personaje.vida) + " puntos de vida")
#%%        self.personaje.hablar("Y a " + self.oponente.nombre + " le quedan " + 
#%%                              str(self.oponente.vida) + " puntos de vida")
#%%                  
#%%        if self.oponente.estado == "muerto":
#%%            self.cbt_oponente_muerto()
#%%        elif self.personaje.estado == "muerto":
#%%            self.cbt_personaje_muerto()
#%%            
#%%    
#%%    def cbt_te_pegan(self, result):
#%%        if self.oponente.estado == "muerto":
#%%            self.cbt_oponente_muerto()
#%%        elif self.personaje.estado == "muerto":
#%%            self.cbt_personaje_muerto()
#%%                              
#%%    
#%%    def cbt_oponente_muerto(self):
#%%        self.personaje.hablar("\n" + color(31) + self.oponente.nombre +
#%%                              " ha muerto. RIP." + finl)
#%%        # puntos de experiencia, objetos... (aún sin hacer)
#%%        
#%%        
#%%    def cbt_personaje_muerto(self):
#%%        # pues no se, habra que ver que hacemos aqui
#%%        pass
#%%        
#%%        
#%%    def cbt_termina_combate(self):
#%%        self.oponente = None
#%%        if self.crono != None:
#%%            self.crono.parar()
#%%            self.crono = None


# Código para pruebas unitarias del módulo.

if (__name__ == '__main__'):
    print "No hay código para pruebas unitarias del módulo. Para probar, ejecutar ambar.py"
    print "y conectarse via telnet."
