#!/usr/bin/env python
#
#Ambar. Another MiddleEarth Based RPG
#Copyright (C) 2001  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., 675 Mass Ave, Cambridge, MA 02139, USA.
#
#Fichero: pnjtester.py

"""Clase pnj."""


from xml.dom import minidom
import random
import sys
import string
import os


class Pnj:
    """Un personaje no jugador.
    FIXME!
    Contiene los siguientes atributos:
     - nombre (string): identifica univocamente al pnj
     - descripcion (string): texto largo que explica todo lo que cualquier jugador ve al entrar
     - descripcion_especial (string): texto describiendo mas cosas que solo se ven superando
                                      una tirada de percepcion
     - direcciones (string[]): lista con los nombres de las salas accesibles desde esta
     - encuentro (PersonajeNoJugador): el PersonajeNoJugador que hay en la sala o None si no hay ninguno
     - tesoro (string): nombre del objeto que hay en la sala, o "" si no hay ninguno
     - personajes (Personaje{}): diccionario con los personajes que se encuentran en la sala,
                              indexado por nombre. NO MODIFICAR DIRECTAMENTE, SINO CON
                              entrar_personaje() Y salir_personaje()
     - n_jugadores (int): numero de personajes de tipo PersonajeJugador dentro de la sala
    
    Al instanciar una sala, se crea nueva y se lee desde el fichero de descripcion de sala,
    poniendola en su estado inicial (se lee el tesoro y se crea un PersonajeNoJugador partiendo
    del valor del atributo "encuentro"). Mas tarde, se puede salvar en un fichero de sala,
    borrarla y cargarla despues, manteniendo su estado (situacion del tesoro y de los personajes
    contenidos).
    
    Importante: al salvar una sala se salvan también todos los objetos y todos los personajes
    contenidas en ella. El módulo "Pickle" se encarga de todo, incluyendo la resolución del bucle
    formado por el atributo "sala" de la clase Personaje.
    """

    DIR_DESC_PNJS = 'desc_pnjs'
    DIR_PNJS = 'pnjs'



    def __init__(self, archivo):

	"""Método inicial para leer los datos de un fichero de pnj"""

	self.id = archivo	
	self.archivo=archivo+".xml"
	self.archivo=os.path.join(Pnj.DIR_DESC_PNJS, self.archivo)
	print self.archivo
	fuente = openAnything(self.archivo)
	self.source = minidom.parse(fuente).documentElement
	fuente.close()
	
	self.iniciar_parseador(self.source)

	self.parsear_pnj(self.source)
	self.parsear_id(self.source)	
	self.parsear_nombre(self.source)	
	self.parsear_descripcion(self.source)
	self.parsear_propiedades(self.source)
	self.parsear_atributos(self.source)
	self.parsear_idiomas(self.source)
	self.parsear_controlador(self.source)
	self.parsear_objetos(self.source)

	del self.source
	del self.descripcion

	
	
    
    def iniciar_parseador(self, fuente):
	"""Esta función borra todos los nodos de tipo Text de un
	elemento DOM"""
	
	for node in fuente.childNodes[:]:
	    if  not 'Element:' in str(node).split(): fuente.childNodes.remove(node)
        
    def parsear_pnj(self, fuente):
	"""Extrae la información del elemento pnj:
	    autor: el autor de la sala
	    version: la versión del tipo de sala"""

	self.autor = fuente.attributes["autor"].value
	self.version = fuente.attributes["version"].value
	try:
	    self.area = fuente.attributes["area"].value
	except: self.area = 'sin area'
	    
	    
    def parsear_id(self, fuente):
	"""Extrae el id del pnj"""
	
	self.id=fuente.childNodes[0].childNodes[0].data.encode('ISO-8859-1')
	
    def parsear_nombre(self, fuente):
	"""Extrae el nombre del pnj"""
	
	self.nombre=fuente.childNodes[1].childNodes[0].data.encode('ISO-8859-1')

	
    def parsear_descripcion(self, fuente):
	"""Extrae el texto y la dificultad asociada de los items
	de descripcion del pnj"""
	
	for node in fuente.childNodes[2].childNodes[:]:
	    if  not 'Element:' in str(node).split(): fuente.childNodes[2].childNodes.remove(node)
	    	    
	
	self.descripcion=fuente.childNodes[2]
	self.items={}

	for item in self.descripcion.childNodes[:]:
	    texto_item=""
	    for frase in item.childNodes[:]:

		frase.data=frase.data.encode('ISO-8859-1')

		texto_item=texto_item+frase.data
	    
	    if item._attrs == {}: dif_item = 0
	    else:
		dif_item=int(item._attrs.get('dificultad').value)
		
	    self.items.update({dif_item:texto_item})
	    
    def parsear_propiedades(self, fuente):	
		
	self.aura=int(fuente.childNodes[3].attributes["aura"].value)
	self.volumen=fuente.childNodes[3].attributes["volumen"].value
	self.experiencia=int(fuente.childNodes[3].attributes["experiencia"].value)
	self.nivel=int(fuente.childNodes[3].attributes["nivel"].value)
	self.vida=int(fuente.childNodes[3].attributes["vida"].value)
	try:
	    self.intocable=fuente.childNodes[3].attributes["intocable"].value.encode('ISO-8859-1')
	except:
	    self.intocable = 'no'
   
    def parsear_atributos(self, fuente):	
		
	self.fuerza=int(fuente.childNodes[4].attributes["fuerza"].value)
	self.destreza=fuente.childNodes[4].attributes["destreza"].value
	self.constitucion=int(fuente.childNodes[4].attributes["constitucion"].value)
	self.inteligencia=int(fuente.childNodes[4].attributes["inteligencia"].value)
	self.sabiduria=int(fuente.childNodes[4].attributes["sabiduria"].value)
	self.carisma=int(fuente.childNodes[4].attributes["carisma"].value)

    def parsear_idiomas(self, fuente):
	
	self.idiomas = {}
	
	self.oestron = int(fuente.childNodes[5].attributes["oestron"].value)
	self.idiomas.update({'oestron':self.oestron})
	try:
	    self.quenya = fuente.childNodes[5].attributes["quenya"].value
	except:
	    self.quenya = 0
	self.idiomas.update({'quenya':self.quenya})
	try:
	    self.orco=int(fuente.childNodes[5].attributes["orco"].value)
	except:
	    self.orco = 0
	self.idiomas.update({'orco':self.orco})
	try:
	    self.enano=int(fuente.childNodes[5].attributes["enano"].value)
	except:
	    self.enano = 0
	self.idiomas.update({'enano':self.enano})
	    


    def parsear_controlador(self, fuente):
	
	self.controlador = fuente.childNodes[6].attributes["tipo"].value.encode('ISO-8859-1')
	
    def parsear_objetos(self, doc_xml):
	"""Extrae toda la información de los objetos que hay en el pnj inicialmente."""
	
	nodo_objetos = doc_xml.childNodes[7]
	
	# Limpiamos todos los subnodos de tipo Text, al igual
	# que hacíamos en la función iniciar_parseador()
	for nodo in nodo_objetos.childNodes[:]:
	    if  'Element:' not in str(nodo).split():
		nodo_objetos.childNodes.remove(nodo)
		
	self.objetos = []
	    
	for nodo_objeto in nodo_objetos.childNodes[:]:
		
	    id_objeto = nodo_objeto._attrs.get('id').value.encode('ISO-8859-1')
	    try:
		cantidad_objeto = int(nodo_objeto._attrs.get('cantidad').value)
	    except:
		cantidad_objeto = 1
	    try:
		prob_objeto = int(nodo_objeto._attrs.get('probabilidad').value)
	    except:
		prob_objeto = 0
	    desc_objeto = nodo_objeto.childNodes[0].data.encode('ISO-8859-1')
		    
	    self.objetos.append({"id": id_objeto,
	    "cantidad": cantidad_objeto,
	    "probabilidad": prob_objeto,
	    "descripcion": desc_objeto})
		    

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

if (__name__ == '__main__'):
    parametro=raw_input('¿Qué fichero del directorio desc_pnjs quieres probar? ')
    pnj = Pnj(parametro)
    print '\n************ PNJ.PY **********\n'
    print 'Cargado pnj con id:',pnj.id,'y con nombre:',pnj.nombre
    print 'Version: '+str(pnj.version)+' Autor: '+str(pnj.autor)+' Área: '+str(pnj.area)+'\n'

    print 'Controlador de tipo ' + pnj.controlador
    print '\nDESCRIPCIONES:'
    for key in pnj.items.keys():
	    print 'dificultad '+str(key)+': '+pnj.items.get(key)+'\n'

    print 'PROPIEDADES:'
    print 'Volumen: '+str(pnj.volumen)+' Vida: '+str(pnj.vida)+' Aura: '+str(pnj.aura)+' Experiencia: '+str(pnj.experiencia)+' Nivel: '+str(pnj.nivel)
    print pnj.intocable,'es intocable...'
    
    print '\nATRIBUTOS:'
    print 'Fuerza: '+str(pnj.fuerza)+' Destreza: '+str(pnj.destreza)+' Constitucion: '+str(pnj.constitucion)+' Inteligencia: '+str(pnj.inteligencia)+' Sabiduría: '+str(pnj.sabiduria)+' Carisma: '+str(pnj.carisma)

    print '\nIDIOMAS: idioma; nivel'
    for key in pnj.idiomas.keys():
	print key,';',pnj.idiomas.get(key)

    print '\nOBJETOS:  objeto; descripcion cantidad probabilidad'
    for objeto in pnj.objetos:
	print objeto.get('id'),';', objeto.get('descripcion'), objeto.get('cantidad'), objeto.get('probabilidad')
    print ""


 
    
