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

"""Clase Objeto."""


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


class Objeto:
    """Una habitacion o sala dentro del juego.
    
    Contiene los siguientes atributos:
     - nombre (string): identifica univocamente a la sala
     - 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_OBJETOS = 'desc_objetos'
    DIR_OBJETOS = 'objetos'



    def __init__(self, archivo):

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

	self.id = archivo	
	self.archivo=archivo+".xml"
	self.archivo=os.path.join(Objeto.DIR_DESC_OBJETOS, self.archivo)
	print self.archivo
	fuente = open(self.archivo)

	self.source = minidom.parse(fuente).documentElement
	fuente.close()
	
	self.iniciar_parseador(self.source)

	self.parsear_objeto(self.source)
	self.parsear_id(self.source)	
	self.parsear_nombre(self.source)	
	self.parsear_descripcion(self.source)
	self.parsear_propiedades(self.source)
	self.parsear_requisitos(self.source)
	self.parsear_efectos(self.source)

	del self.source
	del self.descripcion
	del self.reqs
	del self.efcts
	
	
    
    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_objeto(self, fuente):
	"""Extrae la información del elemento objeto:
	    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
	
    def parsear_id(self, fuente):
	"""Extrae el id del objeto"""
	
	self.id=fuente.childNodes[0].childNodes[0].data.encode('ISO-8859-1')
	
    def parsear_nombre(self, fuente):
	"""Extrae el nombre del objeto"""
	
	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 objeto"""
	
	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=float(fuente.childNodes[3].attributes["volumen"].value)
	self.peso=float(fuente.childNodes[3].attributes["peso"].value)
	self.consumible=fuente.childNodes[3].attributes["consumible"].value.encode('ISO-8859-1')
	self.cargas=int(fuente.childNodes[3].attributes["cargas"].value)
	self.valor=int(fuente.childNodes[3].attributes["valor"].value)
	self.estado=int(fuente.childNodes[3].attributes["estado"].value)
   

    def parsear_requisitos(self, fuente):

	for node in fuente.childNodes[4].childNodes[:]:
	    if  'Element:' not in str(node).split(): fuente.childNodes[4].childNodes.remove(node)

	self.reqs=fuente.childNodes[4]

	self.requisitos={}
	for node in self.reqs.childNodes[:]:
	    try:
		req_id=node._attrs.get('atributo').value.encode('ISO-8859-1')
	    except: print 'algo anda mal, este objeto no tiene requisito!!'
	    try:
		req_valor=int(node._attrs.get('valor').value)
	    except: req_valor=0
	    
	    self.requisitos.update({req_id:req_valor})

    def parsear_efectos(self, fuente):
	
	for node in fuente.childNodes[5].childNodes[:]:
	    if  'Element:' not in str(node).split(): fuente.childNodes[5].childNodes.remove(node)

	self.efcts=fuente.childNodes[5]

	self.efectos={}
	for node in self.efcts.childNodes[:]:
	    try:
		efecto_id=node._attrs.get('atributo').value.encode('ISO-8859-1')
	    except: print 'algo anda mal, este objeto no tiene atributo que modificar!!'
	    try:
		efecto_valor=node._attrs.get('valor').value
	    except: req_valor=0
	    
	    self.efectos.update({efecto_id:efecto_valor})
	    

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

if (__name__ == '__main__'):
    try:
	parametro = sys.argv[1]
    except:
        parametro=raw_input('¿Qué fichero del directorio desc_objetos quieres probar? ')
    objeto = Objeto(parametro)
    print '\n************ OBJETO.PY **********\n'
    print 'Cargado objeto con id:',objeto.id,'y con nombre:',objeto.nombre
    print 'Version: '+str(objeto.version)+' Autor: '+str(objeto.autor)+'\n'

    
    print 'DESCRIPCIONES:'
    for key in objeto.items.keys():
	    print 'dificultad '+str(key)+': '+objeto.items.get(key)+'\n'

    print '\nPROPIEDADES:'
    print 'Volumen: '+str(objeto.volumen)+' Peso: '+str(objeto.peso)+' Aura: '+str(objeto.aura)+' Consumible: '+str(objeto.consumible)+' Cargas: '+str(objeto.cargas)+' Valor: '+str(objeto.valor)+' Estado: '+str(objeto.estado)+'\n'


    print 'REQUISITOS DE USO: atributo; valor mínimo'
    for key in objeto.requisitos.keys():
	print key,';',objeto.requisitos.get(key)

    print '\nEFECTOS AL USARLO:  atributo; bonificación'
    for key in objeto.efectos.keys():
	print key,';', objeto.efectos.get(key)
    print ""


 
    
