#!/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: DialogoCrear.py

"""Clase DialogoCrear."""

import logging
import string
from copy import *
from utils import *
import Mundo
import Sala
import Dialogo
import Personaje
import PersonajeJugador
import Profesion
import Idioma
import Raza

log = logging.getLogger("Dialogos")

class DialogoCrear(Dialogo.Dialogo):
    """Dialogo mantenido con el jugador para crear un personaje nuevo.

    Contiene los siguientes atributos:
     - __id
     - __clave
     - __es_maia
     - __nombre
     - __descripcion
     - __descripcion_ok
     - __descripcion_especial_ok
     - __experiencia
     - __nivel
     - __vida
     - __volumen
     - __estado_pj
     - __sala
     - __atrib
     - __atrib_ok
     - __idiomas
     - __idiomas_ok
     - __dinero
     - __raza
     - __profesion
     - __sexo
     - __edad
     - __altura
     - __peso
     - __color_de_ojos
     - __color_de_pelo
     - __aura
     - __ptos_atrib
     - __ptos_atrib_max
     - __ptos_idiomas
     - __ptos_idiomas_max
    """

    def __init__(self, padre, conn):
        Dialogo.Dialogo.__init__(self, padre, conn)
        self.__id = None
        self.__clave = None
        self.__es_maia = None
        self.__nombre = None
        self.__descripcion = None
        self.__descripcion_ok = None
        self.__descripcion_especial_ok = None
        self.__experiencia = None
        self.__nivel = None
        self.__vida = None
        self.__volumen = None
        self.__estado_pj = None
        self.__sala = None
        self.__atrib = None
        self.__atrib_ok = None
        self.__idiomas = None
        self.__idiomas_ok = None
	self.__dinero = None
        self.__raza = None
        self.__profesion = None
        self.__sexo = None
        self.__edad = None
        self.__altura = None
        self.__peso = None
        self.__color_de_ojos = None
        self.__color_de_pelo = None
        self.__aura = None
        self.__ptos_atrib = None
        self.__ptos_atrib_max = None
        self.__ptos_idiomas = None
        self.__ptos_idiomas_max = None

        self.estado_0()


    def estado_0(self):
        self.poner_estado(0)

        self.conn().send('Creación de personaje')
        self.conn().send('')
        self.conn().send('¡Bienvenido a la Tierra Media! Tu cuerpo está tomando forma')
        self.conn().send('pero es necesario el hálito vital de Eru para conseguir')
        self.conn().send('que abras los ojos y respires.')
        self.conn().send('')
        self.conn().send('Desde el primer momento serás testigo de maravillas sólo')
        self.conn().send('posibles en este universo mágico que te permitirán viajar a')

        self.conn().send('lugares fantásticos y conocer a gente real en una Arda ')
        self.conn().send('tan real como tu imaginación...')
        self.conn().send('')
        self.conn().send('Estás a punto de entrar en la aventura literaria más emocionante')
        self.conn().send('de tu vida pues participarás, junto con otra mucha gente, del')
        self.conn().send('trabajo de decenas de amantes de la obra de Tolkien que han')
        self.conn().send('conseguido poco a poco reconstruir una Tierra Media para todos.')
        self.conn().send('')
        self.conn().send('Es necesario hacerte algunas preguntas para saber qué personaje')
        self.conn().send('deseas ser. tómate el tiempo que necesites para responder cada')
        self.conn().send('una de ellas.')
        self.conn().send('')
        self.conn().send('')
        self.conn().send(color(32) + 'En todo momento puedes escribir ? para recibir ayuda' + finl)
        self.conn().send(color(32) + '                                - para retroceder al paso anterior' + finl)
        self.conn().send(color(32) + '                                + para avanzar al paso siguiente' + finl)
        self.conn().send('')

        self.estado_1()
        log.info('Creando un personaje...')
	return None
        

    def estado_1(self):
        self.poner_estado(1)
	self.conn().send(color(32) + 'Puedes crear un personaje automático escribiendo "peregrino".' + finl)
	self.conn().send(color(33) + '¿Qué nombre deseas tener? ' + color(32) + '(? - +): ' + finl, 0)
	return None

        
    def comando_1(self, cmd_list):
	dlg = None
	if len(cmd_list) == 0:
            self.conn().send('Debes introducir un nombre (1 sola palabra). Pulsa ? para ayuda.')
            dlg = self.estado_1()
        elif cmd_list[0] == '?':
            self.conn().send('El nombre es el identificador de tu personaje. Consiste en')
            self.conn().send('UNA SOLA palabra, que puede contener letras y números, pero no')
            self.conn().send('espacios o símbolos especiales.')
            dlg = self.estado_1()
        elif cmd_list[0] == '-':
            self.conn().send('No puedes retroceder, estás en el primer paso.')
            dlg = self.estado_1()
        elif cmd_list[0] == '+':
	    if self.__id == None:
                self.conn().send('Antes de avanzar tienes que introducir un nombre.')
            	dlg = self.estado_1()
	    else:
                self.conn().send('')
		dlg = self.estado_2()
        else:
            id = cmd_list[0]
	    if id != "peregrino":

		#Comprobamos que no es un nombre raro
		no_valido = 0
		caracteres_no_validos = ''
		for i in id:
		    if (i not in string.letters) and (i not in string.digits):
			no_valido = 1
			caracteres_no_validos += ' '+i
		    elif len(id) > 25:
			no_valido = 1
			caracteres_no_validos = 'El nombre es demasiado largo'

		if no_valido:
		    self.conn().send("El nombre introducido contiene caracteres que no son letras o dígitos")
		    self.conn().send("o es demasiado largo.")
		    self.conn().send("Caracteres no válidos: "+caracteres_no_validos)
		    dlg = self.estado_1()
			
		#Comprobamos que no existe ya un pj con mismo ID
		elif Mundo.pjs_activos.has_key(id) or \
		   Mundo.localizar_sala(Mundo.ID_SALA_LIMBO).personajes.has_key(id):
		    self.conn().send('Ya existe en juego un personaje con el nombre de ' + id + ', prueba con otro...')
		    dlg = self.estado_1()

		#Procedemos a crear el pj
		else:
		    self.__id = id
		    self.conn().send('El nombre de tu personaje es ' + str(self.__id))
		    log.info('El nombre que ha elegido el jugador es: ' + self.__id)
		    self.conn().send('')
		    dlg = self.estado_101()

	    else:

		#Creacion de un personaje peregrino automatico
		self.__id = id + Mundo.nuevo_id_peregrino()
		self.__clave = "peregrino"
		self.__es_maia = 0
		self.__raza = Raza.buscar("humano")
		self.__sexo = "masculino"
		self.__edad = 20
		self.__altura = 1.60
		self.__peso = 60
		self.__color_de_ojos = "negro"
		self.__color_de_pelo = "negro"
		self.__profesion = Profesion.buscar("bribon")
		self.__atrib = {}
		for atributo in self.__raza.modif_atrib.keys():
		    self.__atrib[atributo] = 9 + \
			       PersonajeJugador.modif_atrib_total(atributo,
								  self.__raza,
								  self.__profesion)
		    if self.__atrib[atributo] < 1:
			self.__atrib[atributo] = 1
		self.__idiomas = {}
		for idioma in self.__raza.idiomas_base.keys():
		    self.__idiomas[idioma] = self.__raza.idiomas_base[idioma] + 2
		    if self.__idiomas[idioma] > 5:
			self.__idiomas[idioma] = 5
		self.__descripcion = [{"dificultad": 0,
		                       "texto": "Un tipo anonimo, de lo mas corriente. Un vagabundo como " + 
				                "los que te puedes encontrar en cualquier camino...",
				       "personaje_mira": None}]

		self.conn().send('Se ha creado un personaje automático para tí')
		self.conn().send('El nombre de tu personaje es ' + str(self.__id))
		self.conn().send('Y la contraseña ' + str(self.__clave))
		log.info('El nombre que ha elegido el jugador es: ' + self.__id)
		self.conn().send('')

		dlg = self.estado_20()

	return dlg

    def estado_101(self):
        self.poner_estado(101)
        self.conn().send(color(33) + 'Introduce una clave: ' + color(32) + '(? - +): ' + finl, 0)
        return None
    
    
    def comando_101(self, cmd_list):
        dlg = None
        if len(cmd_list) == 0:
            self.conn().send('Debes introducir una clave/contraseña tan larga como quieras [una palabra].')
            self.conn().send('Intenta que no sea fácil de adivinar. Pulsa ? para ayuda.')
            dlg = self.estado_101()
        elif cmd_list[0] == '?':
            self.conn().send('La clave es un dato personal y que está asociada a un personaje.')
            self.conn().send('Necesitarás introducir la clave cada vez que desees recuperar')
            self.conn().send('a tu personaje. Para ello evita claves fácil de adivinar o cortas')
            dlg = self.estado_101()
        elif cmd_list[0] == '-':
            self.conn().send('')
            dlg = self.estado_1()
        elif cmd_list[0] == '+':

            if self.__clave == None:
                self.conn().send('Antes de avanzar tienes que introducir una clave.')
                dlg = self.estado_101()
            else:
                self.conn().send('')
                dlg = self.estado_2()
        else:
            clave = cmd_list[0]
            self.__clave = clave
            log.info('La clave que ha elegido el jugador es: ' + self.__clave)
            self.conn().send('La clave no se muestra.')
            self.conn().send('')

            #Es la clave de los Maiar?

            if clave == file('clave_maiar.txt','r').readlines()[0][:-1]:
                self.__es_maia = 1
            else:
                self.__es_maia = 0
            
            dlg = self.estado_2()
        return dlg        
                
    def estado_2(self):
        self.poner_estado(2)
        self.conn().send(color(33) + '¿A qué raza quieres pertenecer? ' + color(32) + '(? - +): ' + finl, 0)
	return None

        
    def comando_2(self, cmd_list):
	dlg = None
        if len(cmd_list) == 0:
            self.conn().send('Debes introducir una raza. Pulsa ? para ayuda.')
            dlg = self.estado_2()
        elif cmd_list[0] == '?':
            self.conn().send('La raza determina totalmente las cualidades y caracterización')
            self.conn().send('del personaje. Existen las siguientes razas:')
	    for nombre in [raza.nombre for raza in Raza.lista]:
		self.conn().send(nombre)
            dlg = self.estado_2()
        elif cmd_list[0] == '-':
            self.conn().send('')
            dlg = self.estado_101()
        elif cmd_list[0] == '+':
	    if self.__raza == None:
                self.conn().send('Antes de avanzar tienes que introducir una raza.')
            	dlg = self.estado_2()
	    else:
                self.conn().send('')
		dlg = self.estado_3()
        else:
	    raza = Raza.buscar(cmd_list[0])
	    if raza == None:
                self.conn().send('La raza ' + cmd_list[0] + ' no existe.')
                dlg = self.estado_2()
	    else:
	    	self.__raza = raza
                self.conn().send('La raza de tu personaje es ' + str(self.__raza.nombre))
                log.info('La raza que ha elegido el jugador es: ' + self.__raza.nombre)
                self.conn().send('')
                dlg = self.estado_201()
	return dlg
        

    def estado_201(self):
        self.poner_estado(201)
        self.conn().send(color(33) + '¿De qué sexo es tu personaje (m/f)? ' + color(32) + '(? - +): ' + finl, 0)
	return None


    def comando_201(self, cmd_list):
	dlg = None
        if len(cmd_list) == 0:
            self.conn().send('Debes introducir "m" o "f". Pulsa ? para ayuda.')
            dlg = self.estado_201()
        elif cmd_list[0] == '?':
            self.conn().send('El sexo no tiene efecto práctico en el juego, pero')
            self.conn().send('forma parte de la caracterización del personaje.')
	    self.conn().send('Los posibles valores son "m" para masculino y "f" para femenino')
            dlg = self.estado_201()
        elif cmd_list[0] == '-':
            self.conn().send('')
            dlg = self.estado_2()
        elif cmd_list[0] == '+':
	    if self.__sexo == None:
                self.conn().send('Antes de avanzar tienes que introducir un sexo válido.')
            	dlg = self.estado_201()
	    else:
                self.conn().send('')
		dlg = self.estado_3()
        else:
	    sexo = cmd_list[0]

	    if sexo != "m" and sexo != "f":
		self.conn().send('Debes introducir un sexo válido. Pulsa ? para ayuda.')
		dlg = self.estado_201()
	    else:
		if sexo == "m":
		    self.__sexo = "masculino"
		else:
		    self.__sexo = "femenino"
		self.conn().send('El sexo de tu personaje es ' + str(self.__sexo))
                log.info('El sexo que ha elegido el jugador es: ' + self.__sexo)
                self.conn().send('')
		dlg = self.estado_3()
	return dlg


    def estado_3(self):
        self.poner_estado(3)
        self.conn().send(color(33) + '¿Qué edad tiene tu personaje (en años)? ' + color(32) + '(? - +): ' + finl, 0)
	return None

        
    def comando_3(self, cmd_list):
	dlg = None
        if len(cmd_list) == 0:
            self.conn().send('Debes introducir una edad. Pulsa ? para ayuda.')
            dlg = self.estado_3()

        elif cmd_list[0] == '?':
            self.conn().send('La edad no tiene efecto en las tiradas del juego, pero')
            self.conn().send('forma parte de la caracterización del personaje.')
            self.conn().send('Intenta ser coherente con la raza elegida.')
            dlg = self.estado_3()
        elif cmd_list[0] == '-':
            self.conn().send('')
            dlg = self.estado_201()
        elif cmd_list[0] == '+':
	    if self.__edad == None:
                self.conn().send('Antes de avanzar tienes que introducir una edad.')
            	dlg = self.estado_3()
	    else:
                self.conn().send('')
		dlg = self.estado_4()
        else:
            try:
                self.__edad = int(cmd_list[0])
                
                #Casos de edades para diferentes razas
                if self.__raza.nombre == 'elfo' and self.__edad < 25:
                    self.conn().send('Esta edad no es válida para un elfo. Prueba con una edad mayor')
                    raise ValueError
                elif self.__raza.nombre == 'elfo' and self.__edad > 3000:
                    self.conn().send('Esta edad no es válida para un elfo joven. Prueba con una edad menor')
                    raise ValueError
                elif self.__raza.nombre == 'enano' and self.__edad < 25:
                    self.conn().send('Esta edad no es válida para un enano. Prueba con una edad mayor')
                    raise ValueError
                elif self.__raza.nombre == 'enano' and self.__edad > 300:
                    self.conn().send('Esta edad no es válida para un enano joven. Prueba con una edad menor')
                    raise ValueError
                elif self.__raza.nombre == 'orco' and self.__edad < 15:
                    self.conn().send('Esta edad no es válida para un orco. Prueba con una edad mayor')
                    raise ValueError
                elif self.__raza.nombre == 'orco' and self.__edad > 55:
                    self.conn().send('Esta edad no es válida para un orco joven. Prueba con una edad menor')
                    raise ValueError
                elif self.__raza.nombre == 'humano' and self.__edad < 18:
                    self.conn().send('Esta edad no es válida para un humano. Prueba con una edad mayor')
                    raise ValueError
                elif self.__raza.nombre == 'humano' and self.__edad > 70:
                    self.conn().send('Esta edad no es válida para un humano joven. Prueba con una edad menor')
                    raise ValueError
                elif self.__raza.nombre == 'hobbit' and self.__edad < 18:
                    self.conn().send('Esta edad no es válida para un hobbit. Prueba con una edad mayor')
                    raise ValueError
                elif self.__raza.nombre == 'hobbit' and self.__edad > 70:
                    self.conn().send('Esta edad no es válida para un hobbit joven. Prueba con una edad menor')
                    raise ValueError

                else:
                    self.conn().send('La edad de tu personaje es ' + str(self.__edad) + " años.")
                    log.info('La edad que ha elegido el jugador es: ' + str(self.__edad))
                    self.conn().send('')
                    dlg = self.estado_4()
            except ValueError:
                self.conn().send('Debes introducir una edad válida. Pulsa ? para ayuda.')
                dlg = self.estado_3()
	return dlg
        

    def estado_4(self):
        self.poner_estado(4)
	self.conn().send(color(33) + '¿Qué altura tiene tu personaje (m.cm)? ' + color(32) + '(? - +): ' + finl, 0)
	return None

        
    def comando_4(self, cmd_list):
	dlg = None
        if len(cmd_list) == 0:
            self.conn().send('Debes introducir una altura. Pulsa ? para ayuda.')
            dlg = self.estado_4()
        elif cmd_list[0] == '?':
            self.conn().send('La altura no tiene efecto en las tiradas del juego, pero')
            self.conn().send('forma parte de la caracterización del personaje.')
            self.conn().send('El formato es metros punto centímetros (por ejemplo,')
            self.conn().send('introducir 1.80 significa 1 metro y 80 centímetros).')
            self.conn().send('Ten en cuenta las limitaciones de la raza escogida.')
            dlg = self.estado_4()
        elif cmd_list[0] == '-':
            self.conn().send('')
            dlg = self.estado_3()
        elif cmd_list[0] == '+':
	    if self.__altura == None:
                self.conn().send('Antes de avanzar tienes que introducir una altura.')
            	dlg = self.estado_4()
	    else:
                self.conn().send('')
		dlg = self.estado_5()
        else:
            try:
                self.__altura = float(cmd_list[0])
                #Casos de alturas para diferentes razas
                if self.__raza.nombre == 'elfo' and (self.__altura > 2.30 or self.__altura < 1.75):
                    raise ValueError
                elif self.__raza.nombre == 'enano' and (self.__altura > 1.70 or self.__altura < 1.00):
                    raise ValueError
                elif self.__raza.nombre == 'hobbit' and (self.__altura > 1.70 or self.__altura < 0.80):
                    raise ValueError
                elif self.__raza.nombre == 'orco' and (self.__altura > 1.65 or self.__altura < 0.90):
                    raise ValueError
                elif self.__raza.nombre == 'humano' and (self.__altura > 2.10 or self.__altura < 1.50):
                    raise ValueError
                else:
                    self.conn().send('La altura de tu personaje es %0.2f metros' % self.__altura)
                    log.info('La altura que ha elegido el jugador es: ' + str(self.__altura))
                    self.conn().send('')
                    dlg = self.estado_5()
            except ValueError:
                self.conn().send('Esta altura no es válida para un '+self.__raza.nombre+'.')
                self.conn().send('Debes introducir una altura válida. Pulsa ? para ayuda.')
                dlg = self.estado_4()
	return dlg
        

    def estado_5(self):
        self.poner_estado(5)
        self.conn().send(color(33) + '¿Cuánto pesa tu personaje (kg)? ' + color(32) + '(? - +): ' + finl, 0)
	return None

        
    def comando_5(self, cmd_list):
	dlg = None
        if len(cmd_list) == 0:
            self.conn().send('Debes introducir un peso. Pulsa ? para ayuda.')
            dlg = self.estado_5()
        elif cmd_list[0] == '?':
            self.conn().send('El peso no tiene efecto en las tiradas del juego, pero')
            self.conn().send('forma parte de la caracterización del personaje.')
            self.conn().send('Intenta ser coherente con la raza elegida.')
            dlg = self.estado_5()
        elif cmd_list[0] == '-':
            self.conn().send('')
            dlg = self.estado_4()
        elif cmd_list[0] == '+':
	    if self.__peso == None:
                self.conn().send('Antes de avanzar tienes que introducir un peso.')
            	dlg = self.estado_5()
	    else:
                self.conn().send('')
		dlg = self.estado_6()
        else:
            try:
                self.__peso = int(cmd_list[0])
                #Casos de pesos para diferentes razas
                if self.__raza.nombre == 'elfo' and (self.__peso > 120 or self.__peso < 40):
                    raise ValueError
                elif self.__raza.nombre == 'enano' and (self.__peso > 350 or self.__peso < 70):
                    raise ValueError
                elif self.__raza.nombre == 'orco' and (self.__peso > 150 or self.__peso < 35):
                    raise ValueError
                elif self.__raza.nombre == 'humano' and (self.__peso > 200 or self.__peso < 40):
                    raise ValueError
                elif self.__raza.nombre == 'hobbit' and (self.__peso > 200 or self.__peso < 35):
                    raise ValueError
                else:
                    self.conn().send('El peso de tu personaje es ' + str(self.__peso) + ' kilos.')
                    log.info('El peso que ha elegido el jugador es: ' + str(self.__peso))
                    self.conn().send('')
                    dlg = self.estado_6()
            except ValueError:
                self.conn().send('Este peso no es válido para un '+self.__raza.nombre+'.')
                self.conn().send('Debes introducir un peso válido. Pulsa ? para ayuda.')
                dlg = self.estado_5()
	return dlg
        

    def estado_6(self):
        self.poner_estado(6)
        self.conn().send(color(33) + '¿Cuál es el color de ojos de tu personaje? ' + color(32) + '(? - +): ' + finl, 0)
	return None

        
    def comando_6(self, cmd_list):
	dlg = None
        if len(cmd_list) == 0:
            self.conn().send('Debes introducir un color. Pulsa ? para ayuda.')
            dlg = self.estado_6()
        elif cmd_list[0] == '?':
            self.conn().send('El color de ojos no tiene efecto en las tiradas del juego,')
            self.conn().send('pero forma parte de la caracterización del personaje.')
            self.conn().send('Introducir el color en masculino y singular. Por ejemplo,')
            self.conn().send('negro, verde, azul.')
            dlg = self.estado_6()
        elif cmd_list[0] == '-':
            self.conn().send('')
            dlg = self.estado_5()
        elif cmd_list[0] == '+':
	    if self.__color_de_ojos == None:
                self.conn().send('Antes de avanzar tienes que introducir un color.')
            	dlg = self.estado_6()
	    else:
                self.conn().send('')
		dlg = self.estado_7()
        else:
	    if not cmd_list[0].isalpha():
                self.conn().send('Debes introducir un color válido. Pulsa ? para ayuda.')
                dlg = self.estado_6()
            else:
                self.__color_de_ojos = cmd_list[0]
                self.conn().send('El personaje tiene los ojos de color ' + self.__color_de_ojos)
                log.info('El color de ojos que ha elegido el jugador es: ' + self.__color_de_ojos)
                self.conn().send('')
                dlg = self.estado_7()
	return dlg
        

    def estado_7(self):
        self.poner_estado(7)
        self.conn().send(color(33)+'¿Cuál es el color de pelo de tu personaje? ' + color(32) + '(? - +): ' + finl, 0)
	return None

        
    def comando_7(self, cmd_list):
	dlg = None
        if len(cmd_list) == 0:
            self.conn().send('Debes introducir un color. Pulsa ? para ayuda.')
            dlg = self.estado_7()
        elif cmd_list[0] == '?':
            self.conn().send('El color de pelo no tiene efecto en las tiradas del juego,')
            self.conn().send('pero forma parte de la caracterización del personaje.')
            self.conn().send('Introducir el color en masculino y singular. Por ejemplo,')
            self.conn().send('negro, rubio, castaño.')
            dlg = self.estado_7()
        elif cmd_list[0] == '-':
            self.conn().send('')
            dlg = self.estado_6()
        elif cmd_list[0] == '+':
	    if self.__color_de_pelo == None:
                self.conn().send('Antes de avanzar tienes que introducir un color.')
            	dlg = self.estado_7()
	    else:
                self.conn().send('')
		dlg = self.estado_8()
        else:
	    if not cmd_list[0].isalpha():
                self.conn().send('Debes introducir un color válido. Pulsa ? para ayuda.')
                dlg = self.estado_7()
            else:
                self.__color_de_pelo = cmd_list[0]
                self.conn().send('El personaje tiene el pelo de color ' + self.__color_de_pelo)
                log.info('El color de pelo que ha elegido el jugador es: ' + self.__color_de_pelo)
                self.conn().send('')
                dlg = self.estado_8()
	return dlg
        

    def estado_8(self):
        self.poner_estado(8)
        self.conn().send(color(33) + '¿Qué profesión se ajusta mejor a tu personaje? ' + color(32) + '(? - +): ' + finl, 0)
	return None

        
    def comando_8(self, cmd_list):
	dlg = None
        if len(cmd_list) == 0:
            self.conn().send('Debes introducir una profesion. Pulsa ? para ayuda.')
            dlg = self.estado_8()
        elif cmd_list[0] == '?':
            self.conn().send('La profesión complementa la raza para determinar')
            self.conn().send('las cualidades y caracterización del personaje. ')
            self.conn().send('Existen las siguientes profesiones:')
	    for profesion in Profesion.lista:
                self.conn().send(profesion.nombre)
            dlg = self.estado_8()
        elif cmd_list[0] == '-':
            self.conn().send('')
            dlg = self.estado_7()
        elif cmd_list[0] == '+':
	    if self.__profesion == None:
                self.conn().send('Antes de avanzar tienes que introducir una profesion.')
            	dlg = self.estado_8()
	    else:
                self.conn().send('')
		dlg = self.estado_9()
        else:
	    profesion = Profesion.buscar(cmd_list[0])
	    if profesion == None:
                self.conn().send('La profesion ' + cmd_list[0] + ' no existe.')
                dlg = self.estado_8()
	    elif profesion.nombre in self.__raza.profesiones_prohibidas:
		self.conn().send('Un ' + self.__raza.nombre + ' no puede ser ' + 
		                 profesion.nombre + ".")
		dlg = self.estado_8()
	    else:

		# Caso particular: si cambiamos la profesion una vez que ya se han
		# definido los atributos, hay que volver a recalcularlos.
		if self.__profesion != None and self.__profesion != profesion:
		    self.__atrib_ok = None

		self.__profesion = profesion
                self.conn().send('La profesion del personaje es ' + profesion.nombre)
                log.info('La profesión que ha elegido el jugador es: ' + profesion.nombre)
                self.conn().send('')
                dlg = self.estado_9()
	return dlg
        

    def estado_9(self):
        self.poner_estado(9)
        
	# La variable atrib_ok indica si el jugador ya ha terminado de
	# definir sus atributos.
	if self.__atrib_ok == None:
	    self.__atrib_ok = 0

	    # Aqui se inicializan los valores iniciales de los atributos y los puntos para repartir.
	    self.__ptos_atrib = 0
	    self.__ptos_atrib_max = 72 - PersonajeJugador.ptos_obligatorios(self.__raza,
								            self.__profesion)

	    # El nivel inicial de cada atributo es 12 más el modificador por raza y
	    # por profesión.
	    self.__atrib = {}								 
	    for atributo in self.__raza.modif_atrib.keys():
		self.__atrib[atributo] = 12 + \
			       PersonajeJugador.modif_atrib_total(atributo,
								  self.__raza,
								  self.__profesion)

	self.conn().send('Tienes 72 puntos para repartir entre los atributos de')
	self.conn().send('Fuerza, Destreza, Constitución, Inteligencia, Sabiduría')
	self.conn().send('y Carisma.')
	self.conn().send('')
	self.conn().send('Los niveles mínimos y maximos dependen de la raza')
	self.conn().send('y profesion. Los atributos ya han sido rellenados')
	self.conn().send('hasta el nivel medio. Si quieres aumentar un atributo,')
	self.conn().send('tendras que reducir otro primero.')
	self.conn().send('')
	self.conn().send(color(31)+'------ Pulsa ENTER ------ '+finl,0)

	return None
	

    def comando_9(self, cmd_list):
        return self.estado_10()
            
        
    def estado_10(self):
	self.poner_estado(10)
	self.conn().send('')
	self.conn().send(color(32) + 'Tus niveles actuales de atributos son:')
	for atributo in self.__atrib.keys():
	    self.conn().send("%-13s" % (atributo), 0)
	    self.conn().send(" [" + str(PersonajeJugador.min_atrib(atributo,
	                                                           self.__raza,
								   self.__profesion)), 0)
	    self.conn().send("-" + str(PersonajeJugador.max_atrib(atributo,
	                                                          self.__raza,
								  self.__profesion)), 0)
	    self.conn().send("]: " + str(self.__atrib[atributo]))
	self.conn().send(finl)
	self.conn().send(color(33) + 'Tienes ' + str(self.__ptos_atrib) + ' puntos para repartir')
	self.conn().send('Atributo a modificar (escribe "fin" para terminar) ' + color(32) + '(? - +): ' + finl, 0)
	return None

        
    def comando_10(self, cmd_list):
	dlg = None
        if len(cmd_list) == 0:
	    self.conn().send('')
            dlg = self.estado_10()
        elif cmd_list[0] == '?':
	    self.conn().send('Introduce el nombre de un atributo y el numero de puntos')
	    self.conn().send('que quieres sumarle (o restar si es negativo).')
	    self.conn().send('Por ejemplo, fuerza 12 o destreza -4.')
	    self.conn().send('')
	    self.conn().send('El significado de los atributos es el siguiente:')
	    self.conn().send('Fuerza: indica la capacidad del personaje para acciones')
	    self.conn().send('        como levantar cargas, romper cosas y golpear.')
	    self.conn().send('Destreza: indica la capacidad del personaje para acciones')
	    self.conn().send('          como manipular mecanismos, combatir con armas')
	    self.conn().send('          de mano, disparar o abrir cerraduras.')
	    self.conn().send('Constitucion: indica la capacidad del personaje para')
	    self.conn().send('              soportar esfuerzos y heridas.')
	    self.conn().send('Inteligencia: indica la capacidad del personaje para')
	    self.conn().send('              aprender, descifrar enigmas, observar el')
	    self.conn().send('              entorno y encontrar cosas escondidas.')
	    self.conn().send('Sabiduría: refleja el conocimiento del mundo que tiene el')
	    self.conn().send('           personaje, incluyendo reconocer lugares,')
	    self.conn().send('           conocer propiedades de objetos y entender')
	    self.conn().send('           la magia.')
	    self.conn().send('Carisma: indica la capacidad del personaje para interactuar')
	    self.conn().send('         con otros personajes, caerles bien, hacerse obedecer,')
	    self.conn().send('         y ¿por que no? tambien engañar.')
            dlg = self.estado_10()
        elif cmd_list[0] == '-':
            self.conn().send('')
            dlg = self.estado_8()
        elif cmd_list[0] == '+':
	    if self.__atrib_ok == 0:
                self.conn().send('Antes de avanzar tienes que terminar de definir los atributos.')
            	dlg = self.estado_10()
	    else:
                self.conn().send('')
		dlg = self.estado_12()
	elif len(cmd_list) == 1 and cmd_list[0] == "fin":
            dlg = self.estado_11()
        elif len(cmd_list) != 2:
	    self.conn().send('Introduce un nombre de atributo y un numero.')
            dlg = self.estado_10()
        else:
	    try:
	        atributo = cmd_list[0]
	        if not self.__atrib.has_key(atributo):
	    	    self.conn().send(atributo + " no es un atributo.")
		    raise ValueError

	        try:
	            valor = int(cmd_list[1])
		except ValueError:
	    	    self.conn().send(cmd_list[1] + " no es un numero valido.")
		    raise ValueError

		if self.__ptos_atrib - valor < 0:
		    self.conn().send("No tienes tantos puntos para repartir. Quita de otro atributo primero.")
		    raise ValueError

		if self.__ptos_atrib - valor > self.__ptos_atrib_max:
		    self.conn().send("No puedes quitar tantos puntos. Añade algunos a otro atributo.")
		    raise ValueError

		valor_atrib = self.__atrib[atributo]

		if valor_atrib + valor < PersonajeJugador.min_atrib(atributo,
		                                                    self.__raza,
								    self.__profesion):
		    self.conn().send("Ese atributo no puede ser tan pequeño")
		    raise ValueError

		if valor_atrib + valor > PersonajeJugador.max_atrib(atributo,
		                                                    self.__raza,
								    self.__profesion):
		    self.conn().send("Ese atributo no puede ser tan grande")
		    raise ValueError

		self.__atrib[atributo] = valor_atrib + valor
		self.__ptos_atrib -= valor

	    except ValueError:
		pass

	    dlg = self.estado_10()

	return dlg


    def estado_11(self):
	dlg = None
	self.poner_estado(11)
	if self.__ptos_atrib != 0:
	    self.conn().send("")
	    self.conn().send("Todavía tienes puntos por repartir.")
	    self.conn().send("¿Seguro que quieres terminar?")
	else:
	    self.__atrib_ok = 1
            dlg = self.estado_12()
	return dlg
                
	            
    def comando_11(self, cmd_list):
	dlg = None
        if len(cmd_list) == 0:
            dlg = self.estado_11()
        elif cmd_list[0] == "no":
	    dlg = self.estado_10()
	elif cmd_list[0] == "si":
	    self.__atrib_ok = 1
            dlg = self.estado_12()
	else:
	    self.conn().send("Introduce si o no, por favor")
	    dlg = self.estado_11()
	return dlg
        

    def estado_12(self):
	self.poner_estado(12)
        
	# La variable idiomas_ok indica si el jugador ya ha terminado de
	# definir sus idiomas.
	if self.__idiomas_ok == None:
	    self.__idiomas_ok = 0

	    # Ahora inicializamos los niveles iniciales de idiomas, que dependen de
	    # la raza. OJO-> no se puede usar el método copy() sobre idiomas_base porque
	    # posiblemente crearía instancias nuevas de la clase idioma. Comprobar.
	    self.__idiomas = {}
	    for idioma in self.__raza.idiomas_base.keys():
		self.__idiomas[idioma] = self.__raza.idiomas_base[idioma]

	    # Y los puntos para repartir en idiomas.
	    self.__ptos_idiomas_max = 13
	    self.__ptos_idiomas = 13
	    for idioma in self.__idiomas.keys():
		self.__ptos_idiomas -= self.__idiomas[idioma]

	self.conn().send('')
	self.conn().send('Ahora tienes otros 13 puntos para repartir entre los')
	self.conn().send('idiomas que conoce tu personaje.')
	self.conn().send('')
	self.conn().send('Los niveles mínimos y maximos son 0 y 5 para todos')
	self.conn().send('los idiomas. Los niveles iniciales ya han sido rellenados')
	self.conn().send('segun la raza, pero no se han gastado todos los puntos.')
	self.conn().send('Puedes aumentar niveles en los idiomas que quieras.')
	self.conn().send('No es recomendable bajar mucho el oestron ni el')
	self.conn().send('idioma natal del personaje (los que lo tengan).')
	self.conn().send('')
	self.conn().send(color(31) + '------ Pulsa ENTER ------ ' + finl, 0)

	return None
	

    def comando_12(self, cmd_list):
        return self.estado_13()


    def estado_13(self):
	self.poner_estado(13)
	self.conn().send('')
	self.conn().send(color(32) + 'Tus niveles actuales de idiomas son:')
	for idioma in self.__idiomas.keys():
	    self.conn().send("%-10s" % (idioma.nombre), 0)
	    self.conn().send("[0-5]: " + str(self.__idiomas[idioma]))
	self.conn().send(finl)
	self.conn().send(color(33) + 'Tienes '+ str(self.__ptos_idiomas)+' puntos para repartir')
	self.conn().send('Idioma a modificar (escribe "fin" para terminar) ' + color(32) + '(? - +): ' + finl, 0)
	return None

        
    def comando_13(self, cmd_list):
	dlg = None
        if len(cmd_list) == 0:
	    self.conn().send('')
            dlg = self.estado_13()
        elif cmd_list[0] == '?':
	    self.conn().send('Introduce el nombre de un idioma y el numero de puntos')
	    self.conn().send('que quieres sumarle (o restar si es negativo).')
	    self.conn().send('Por ejemplo, enano 3 o quenya -1.')
            dlg = self.estado_13()
        elif cmd_list[0] == '-':
            self.conn().send('')
            dlg = self.estado_9()
        elif cmd_list[0] == '+':
	    if self.__idiomas_ok == 0:
                self.conn().send('Antes de avanzar tienes que terminar de definir los idiomas.')
            	dlg = self.estado_13()
	    else:
                self.conn().send('')
		dlg = self.estado_16()
	elif len(cmd_list) == 1 and cmd_list[0] == "fin":
            dlg = self.estado_14()
        elif len(cmd_list) != 2:
	    self.conn().send('Introduce un nombre de idioma y un numero.')
            dlg = self.estado_13()
        else:
	    try:
	        idioma = Idioma.buscar(cmd_list[0])
		if idioma == None:
	    	    self.conn().send(cmd_list[0] + " no es un idioma.")
		    raise ValueError

	        try:
	            valor = int(cmd_list[1])
		except ValueError:
	    	    self.conn().send(cmd_list[1] + " no es un numero valido.")
		    raise ValueError

		if self.__ptos_idiomas - valor < 0:
		    self.conn().send("No tienes tantos puntos para repartir. Quita puntos de otro idioma primero.")
		    raise ValueError

		if self.__ptos_idiomas - valor > self.__ptos_idiomas_max:
		    self.conn().send("No puedes quitar tantos puntos. Añade algunos a otro idioma.")
		    raise ValueError

		valor_idioma = self.__idiomas[idioma]

		if valor_idioma + valor < 0:
		    self.conn().send("El valor de un idioma no puede ser menor que 0")
		    raise ValueError

		if valor_idioma + valor > 5:
		    self.conn().send("El valor de un idioma no puede ser mayor que 5")
		    raise ValueError

		self.__idiomas[idioma] = valor_idioma + valor
		self.__ptos_idiomas -= valor

	    except ValueError:
		pass

	    dlg = self.estado_13()

	return dlg


    def estado_14(self):
	dlg = None
        self.poner_estado(14)
	if self.__ptos_idiomas != 0:
	    self.conn().send("")
	    self.conn().send("Todavía tienes puntos por repartir.")
	    self.conn().send("¿Estas seguro de que quieres terminar?")
	else:
	    self.__idiomas_ok = 1
            dlg = self.estado_16()
	return dlg
	    
        
    def comando_14(self, cmd_list):
	dlg = None
        if len(cmd_list) == 0:
            dlg = self.estado_14()
        elif cmd_list[0] == "no":
	    dlg = self.estado_13()
	elif cmd_list[0] == "si":
	    self.__idiomas_ok = 1
            dlg = self.estado_16()
        else:
	    self.conn().send("Introduce si o no, por favor")
	    dlg = self.estado_14()
	return dlg

	
    def estado_16(self):
        self.poner_estado(16)

	if self.__descripcion_ok == None:
	    self.__descripcion_ok = 0
	    self.__descripcion_especial_ok = 0
	    self.__descripcion = deepcopy(self.__raza.descripcion_base)

	self.conn().send('')
	self.conn().send('')
 	self.conn().send('Hemos llegado a la parte final de la creación del personaje.')
	self.conn().send('')
	self.conn().send('Queda tan sólo que escribas una descripción de entre 3 y 6')
	self.conn().send('líneas de cómo te ven los demás. A continuación te presentamos')	
	self.conn().send('una descripción. Puedes aceptarla o redactar otra tú mismo.')
	self.conn().send('')

	if len(self.__descripcion) > 0:
	    self.conn().send(color(31) + self.__descripcion[0]["texto"] + finl)
	    self.conn().send('')
	else:
	    self.conn().send(color(31) + "(vacia)" + finl)
	    self.conn().send('')
	
	self.conn().send(color(33) + '¿Deseas conservar esta descripción (S/n)? ' + color(32) + '(? - +): '+ finl, 0)
	return None


    def comando_16(self, cmd_list):
	dlg = None
        if len(cmd_list) == 0:
	    cmd_list = ['s']

	if cmd_list[0] == 'n' or cmd_list[0] == 'no':
	    self.__descripcion = []
            dlg = self.estado_17()
	elif cmd_list[0] == 's' or cmd_list[0] == 'si':
	    self.__descripcion_ok = 1
            dlg = self.estado_18()
        elif cmd_list[0] == '-':
            self.conn().send('')
            dlg = self.estado_12()
        elif cmd_list[0] == '+':
	    if self.__descripcion_ok == 0:
                self.conn().send('Antes de avanzar tienes que terminar de definir tu descripcion.')
            	dlg = self.estado_16()
	    else:
                self.conn().send('')
		dlg = self.estado_18()
	else:
	    self.conn().send('Por favor, responde "si" o "no"')
            dlg = self.estado_16()

	return None

	    
    def estado_17(self):
	self.poner_estado(17)
	self.conn().send('')
	self.conn().send(color(33) + 'Escribe tu descripción: ', 0)
	return None

		
    def comando_17(self, cmd_list):
	dlg = None
        if len(cmd_list) == 0:
	    self.conn().send('La descripcion no puede ir vacia')
	    dlg = self.estado_17()
	else:
	    texto = " ".join(cmd_list)
	    self.__descripcion.append({"dificultad":0, "texto":texto, "personaje_mira": None})
	    dlg = self.estado_16()
	return dlg


    def estado_18(self):
	self.poner_estado(18)
	self.conn().send('')
	self.conn().send('')
	self.conn().send('Minë te permite, al comienzo, incluir una pequeña descripción')
	self.conn().send('especial algo difícil de detectar por la gente. Puede referirse a')
	self.conn().send('una marca especial, un rasgo característico, un objeto particular, etc,')
	self.conn().send('que sea relevante para la historia de tu personaje aunque no tenga')
	self.conn().send('repecursión "práctica" en Minë. Tu descripcion especial actual es:')
	self.conn().send('')

	if len(self.__descripcion) > 1:
	    self.conn().send(color(31) + self.__descripcion[1]["texto"] + finl)
	    self.conn().send('')
	else:
	    self.conn().send(color(31) + "(vacia)" + finl)
	    self.conn().send('')
	
	self.conn().send(color(33) + '¿Deseas conservar esta descripción especial (S/n)?  ' + color(32) + '(? - +): '+ finl, 0)
	return None


    def comando_18(self, cmd_list):
	dlg = None
        if len(cmd_list) == 0:
	    cmd_list = ['s']

	if cmd_list[0] == 'n' or cmd_list[0] == 'no':
	    if len(self.__descripcion) > 1:
		del self.__descripcion[1]
            dlg = self.estado_19()
	elif cmd_list[0] == 's' or cmd_list[0] == 'si':
	    self.__descripcion_especial_ok = 1
            dlg = self.estado_20()
        elif cmd_list[0] == '-':
            self.conn().send('')
            dlg = self.estado_16()
        elif cmd_list[0] == '+':
	    if self.__descripcion_especial_ok == 0:
                self.conn().send('Antes de avanzar tienes que definir tu descripcion especial.')
            	dlg = self.estado_18()
	    else:
                self.conn().send('')
		dlg = self.estado_20()
	else:
	    self.conn().send('Por favor, responde "si" o "no"')
            dlg = self.estado_18()

	return dlg
	    
	    
    def estado_19(self):
	self.poner_estado(19)
	self.conn().send('')
	self.conn().send(color(33)+'Escribe tu descripción especial: ', 0)
	return None
        
		
    def comando_19(self, cmd_list):
	dlg = None
        if len(cmd_list) == 0:
	    if len(self.__descripcion) > 1:
		del self.__descripcion[1]
	    dlg = self.estado_18()
	else:
	    texto = " ".join(cmd_list)
	    self.__descripcion.append({"dificultad":30, "texto":texto, "personaje_mira": None})
	    dlg = self.estado_18()
	return dlg

	
    def estado_20(self):
        import DialogoNormal

	self.poner_estado(20)

        #%%self.conn().send('Los puntos de vida son el doble que la Constitucion',0)
	self.__vida = self.__atrib["constitucion"] * 2

	# El nombre largo del personaje será el id seguido de su raza (teniendo
	# en cuenta masculino y femenino).
	self.__nombre = self.__id + " " + \
		        self.__raza.nombre_genero[self.__sexo]

	self.__volumen = self.__raza.volumen_base
	self.__estado_pj = "vivo"
        self.__idioma_base = Idioma.oestron
        
	self.__aura = self.__raza.aura_base
	self.__sala = Mundo.localizar_sala(Mundo.ID_SALA_ENTRADA)

	self.__nivel = 1
	self.__experiencia = 0

	self.__dinero = Personaje.DINERO_INICIAL

	# Ya tenemos todos los datos, podemos crear el personaje
	# y pasar por fin al estado normal.

	personaje = PersonajeJugador.PersonajeJugador(
		                     self.__id,
                                     self.__clave,
                                     self.__es_maia,
				     self.__nombre,
				     self.__descripcion,
				     self.__experiencia,
				     self.__nivel,
				     self.__vida,
				     self.__volumen,
				     self.__estado_pj,
				     self.__aura,
				     self.__sala,
				     None,
				     self.__atrib,
				     self.__idiomas,
                                     self.__idioma_base,
				     self.__dinero,
				     self.__raza,
				     self.__profesion,
				     self.__sexo,
				     self.__edad,
				     self.__altura,
				     self.__peso,
				     self.__color_de_ojos,
				     self.__color_de_pelo)

	self.padre().controlar_personaje(personaje)

	log.info("Personaje llamado " + personaje.id + " creado.")

	Mundo.salvar_todo()

	return DialogoNormal.DialogoNormal(self.padre(), self.conn(), self.padre().personaje())
	    
	    
# Código para pruebas unitarias del módulo.

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

