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

"""Clase SalaEditable."""

import Sala
import logging

log = logging.getLogger("Editor")

class SalaEditable(Sala.Sala):
    """ Clase que hereda de la clase Sala proporcionandole a ésta métodos para
        añadir y borrar descripciones, Salidas, objetos y PNJ.
        También proporciona métodos para volcar todos los elementos y atributos
        de una sala en un fichero xml.
        IMPORTANTE
        Cada vez que cambie el formato de la clase sala hay que modificar ésta 
        añadiendo los atributos y elementos en la sección correspondiente 
        para que se guarden en los ficheros xml.
     """

    def __init__(self, id, version, autor, area, comentario, nombre, descripcion, salidas,
	         tipo, subtipo, volumen, luz, aura, combate, ocultabilidad, contadores,
		 etiquetas, objetos, encuentros, personajes, n_jugadores, fecha_fichero):

	assert(Sala.VERSION_DESC_SALA == '1.2')
	assert(Sala.VERSION_SALA == '1.2.4')

	super(SalaEditable, self).__init__(id, version, autor, area, comentario, nombre,
		                           descripcion, salidas, tipo, subtipo, volumen,
					   luz, aura, combate, ocultabilidad, contadores,
					   etiquetas, objetos, encuentros, personajes,
					   n_jugadores, fecha_fichero)

           
    def add_descripcion(self,dificultad,texto,personaje_mira):
        #añade una descripción a la sala y devuelve un puntero al objeto
        #que corresponde a la descripcion nueva
	temp={"dificultad": dificultad, "texto": texto, "personaje_mira": personaje_mira}
        self.descripcion.append(temp)
        temp2=self.descripcion.index(temp)
        return self.descripcion[temp2]
    
    def borrar_descripcion(self,des):
        self.descripcion.remove(des)
        
    def add_salida(self,direccion,dif,id,desc,tipo_cierre,datos_cierre,mensaje_cerrado,personaje_mira,personaje_cruza):
        #añade una salida a la sala y devuelve un puntero al objeto
        #que corresponde a la salida nueva
        #falta comprobar que no está repetida la Salida
               
        temp={"direccion": direccion,
	      "dificultad": dif,
              "id": id, 
              "descripcion": desc,
              "tipo_cierre": tipo_cierre,
              "datos_cierre": datos_cierre,
              "mensaje_cerrado": mensaje_cerrado,
	      "personaje_mira": personaje_mira,
	      "personaje_cruza": personaje_cruza
              }
        self.salidas.append(temp)
        temp2=self.salidas.index(temp)
        return self.salidas[temp2]
                             
    def borrar_salida(self,sal):
        self.salidas.remove(sal)
    
    def add_objeto(self,id,probabilidad,maximo,dificultad,cantidad,descripcion,personaje_mira):
    #problemas con las instancias
        temp = {"id": id,
                "probabilidad": probabilidad,
                "maximo": maximo,
                "dificultad": dificultad,
                "cantidad": cantidad,
                "descripcion": descripcion,
		"instancias": [],
		"personaje_mira": personaje_mira}
        self.objetos.append(temp)
        temp2=self.objetos.index(temp)
        return self.objetos[temp2]
    
    def borrar_objeto(self,obj):
        self.objetos.remove(obj)   
    
    def add_encuentro(self,id,max,prob,dif,desc,cantidad):
        #añade un encuentro a la sala y devuelve un puntero al objeto
        #que corresponde al encuentro nuevo
        #falta comprobar que no está repetido el encuentro
        temp={"id": id,
              "maximo": max,
              "probabilidad": prob,
              "dificultad": dif,
              "descripcion": desc,
	      "cantidad": cantidad}
        self._Sala__encuentros.append(temp)
        temp2=self._Sala__encuentros.index(temp)
        return self._Sala__encuentros[temp2]
    
    def borrar_encuentro(self,enc):
        self._Sala__encuentros.remove(enc)
    
    #---------------------------------------
    #Metodos para guardar en fichero la sala
    #---------------------------------------
    
    def guardar_cabecera(self,salida):
        salida=salida+"""<?xml version="1.0" encoding="ISO-8859-15" standalone="no" ?>\n""" 
        salida=salida+"""<!DOCTYPE saladeMine SYSTEM "mine_sala.dtd">\n"""   
        return salida
    
    def guardar_sala(self,salida):
        salida=salida+"""<sala version="""+'"'+ Sala.VERSION_DESC_SALA +'"'
        salida=salida+' autor="'+self.autor+'" area="'+ self.area 
        salida=salida+'" comentario="'+ self.comentario+'">\n'           
        return salida
    
    def guardar_id(self,salida):
        salida=salida+"<id>"+self.id+"</id>\n"
        return salida
    
    def guardar_nombre(self,salida):
        salida=salida+"<nombre>"+self.nombre+"</nombre>\n"
        return salida
    
    def guardar_descripcion(self,salida):
        salida=salida+"<descripcion>\n"
        
        for item in self.descripcion:
            salida=salida+"    <item"
	    if item["dificultad"] > 0:
		salida=salida + " dificultad='"+`item["dificultad"]`+"'"
	    salida=salida+">"+item["texto"]
	    if item["personaje_mira"] != None:
		salida=salida + "\n        " + str(item["personaje_mira"]) + "\n    "
	    salida=salida+"</item>\n"
        
        salida=salida+"</descripcion>\n"
        return salida
    
    def guardar_salidas(self,salida):
        salida=salida+"<salidas>\n"

        for sal in self.salidas:
            salida=salida+'    <'
            salida=salida+sal["direccion"]
            salida=salida+' id="'+sal["id"]+'"'
	    if sal["dificultad"] > 0:
                salida=salida+' dificultad='+"'"+`sal["dificultad"]`+"'"
	    if sal["tipo_cierre"] != "" and sal["tipo_cierre"] != "ninguno":
		salida=salida+' tipo_cierre='+'"'+sal["tipo_cierre"]+'"'
		salida=salida+' datos_cierre='+'"'+sal["datos_cierre"]+'"'
		salida=salida+' mensaje_cerrado='+'"'+sal["mensaje_cerrado"]+'"'
            salida=salida+">"
            salida=salida+sal["descripcion"]
	    if sal["personaje_mira"] != None:
		salida=salida + "\n        " + str(sal["personaje_mira"])
	    if sal["personaje_cruza"] != None:
		salida=salida + "\n        " + str(sal["personaje_cruza"])
	    if sal["personaje_mira"] != None or sal["personaje_cruza"] != None:
		salida=salida + "\n    "
	    salida=salida+"</"+sal["direccion"]+">\n"
    
        salida=salida+"</salidas>\n"
        return salida
    
    def guardar_propiedades(self,salida):
        salida=salida+"<propiedades"
	if self.tipo != "sin_tipo":
            salida=salida+" tipo='"+  self.tipo+"'"
	if self.subtipo != "sin_subtipo":
            salida=salida+" subtipo='"+  self.subtipo+"'"
        salida=salida+" volumen='" + `self.volumen` + "'"
        salida=salida+" luz='"+`self.luz`+ "'"
        salida=salida+" aura='"+`self.aura`+ "'"
        salida=salida+' combate="'+self.combate+'"'
        salida=salida+" ocultabilidad='"+`self.ocultabilidad`+"'"
	if len(self.contadores) == 0 and len(self.etiquetas) == 0:
	    salida = salida + "/>\n"
	else:
	    salida = salida + ">\n"
	    for nombre_contador in self.contadores:
		valor_contador = self.contadores[nombre_contador]
		salida = salida + "    <contador nombre='%s' valor='%d'>\n" % \
		                  (nombre_contador, valor_contador)
       	    for nombre_etiqueta in self.etiquetas:
		valor_etiqueta = self.etiquetas[nombre_etiqueta]
		salida = salida + "    <etiqueta nombre='%s' valor='%s'>\n" % \
		                  (nombre_etiqueta, valor_etiqueta)
	    salida = salida + "</propiedades>"
        return salida
    
    def guardar_objetos(self,salida):
        salida=salida+"<objetos>\n"
        
        for obj in self.objetos:
            salida = salida+"    <objeto"
            salida = salida+' id="'+obj["id"]+'"' 
	    if obj["dificultad"] != 0:
                salida = salida+' dificultad="'+`obj["dificultad"]`+'"' 
	    if obj["probabilidad"] != 0:
                salida = salida+' probabilidad="'+`obj["probabilidad"]`+'"'
	    if obj["maximo"] != obj["cantidad"]:
                salida = salida+' maximo="'+`obj["maximo"]`+'"'
	    if obj["cantidad"] != 1:
                salida = salida+' cantidad="'+`obj["cantidad"]`+'"'
            salida = salida+">"+obj["descripcion"]
	    if obj["personaje_mira"] != None:
		salida=salida + "\n        " + str(obj["personaje_mira"]) + "\n    "
	    salida = salida+"</objeto>\n"
        
        salida=salida+"</objetos>\n"
        return salida
    
    def guardar_encuentros(self,salida):
        salida=salida+"<encuentros>\n"
        
        for enc in self.encuentros:
            salida = salida+"    <encuentro"
            salida = salida+' id="'+enc["id"]+'"' 
	    if enc["dificultad"] != 0:
		salida = salida+' dificultad="'+`enc["dificultad"]`+'"' 
	    if enc["probabilidad"] != 0:
		salida = salida+' probabilidad="'+`enc["probabilidad"]`+'"'
	    if enc["maximo"] != enc["cantidad"]:
		salida = salida+' maximo="'+`enc["maximo"]`+'"'
	    if enc["cantidad"] != 1:
		salida = salida+' cantidad="'+`enc["cantidad"]`+'"'
            salida = salida+">"+enc["descripcion"]+"</encuentro>\n"
               
        salida=salida+"</encuentros>\n"
        return salida
     
    def guardar_cierre(self,salida):
        salida=salida+"</sala>\n"
        return salida
    
    def salvar(self):
        """Graba en un fichero de salas la sala con todo su contenido."""
        salida=""
        salida=self.guardar_cabecera(salida)
        salida=self.guardar_sala(salida)
        salida=self.guardar_id(salida)
        salida=self.guardar_nombre(salida)
        salida=self.guardar_descripcion(salida)
        salida=self.guardar_salidas(salida)
        salida=self.guardar_propiedades(salida)
        salida=self.guardar_objetos(salida)
        salida=self.guardar_encuentros(salida)
        salida=self.guardar_cierre(salida)
        
	path = os.path.join(Sala.DIR_DESC_SALAS, self.area, self.id + Sala.EXT_DESC_SALAS) 
        fichero = open(path, 'w')
        log.debug("fichero abierto: " + path)
        fichero.write(salida)     
        fichero.close()
        log.debug("fichero cerrado")


# Funciones públicas

def nueva_xml(id):
    """Crea una sala editable nueva a partir de un fichero XML de descripción de sala.

    No se crean los objetos y encuentros contenidos inicialmente en la sala.
    
    Requiere:
      id != None
      id corresponde con un fichero existente
    """

    (id, version, autor, area, comentario, nombre, descripcion, salidas,
	tipo, subtipo, volumen, luz, aura, combate, ocultabilidad, contadores,
	etiquetas, objetos, encuentros, fecha_fichero) = \
		Sala._parsear_fichero(id, crear_contenidos = False)

    personajes = {}
    n_jugadores = 0

    sala = SalaEditable(id, version, autor, area, comentario, nombre, descripcion,
	                salidas, tipo, subtipo, volumen, luz, aura, combate,
			ocultabilidad, contadores, etiquetas, objetos, encuentros,
			personajes, n_jugadores, fecha_fichero)

    return sala
 
            
def nueva_vacia():
    """Crea una sala editable nueva, con un id por defecto y todos los atributos vacíos."""

    id = "nueva_area-nueva_sala"
    version = VERSION_SALA
    autor = ""
    area = "nueva_area"
    comentario = ""
    nombre = ""
    descripcion = []
    salidas = []
    tipo = "sin_tipo"
    subtipo = "sin_subtipo"
    volumen = 1
    luz = 50
    aura = 50
    combate = "si"
    ocultabilidad = 50
    contadores = {}
    etiquetas = {}
    objetos = []
    encuentros=[]
    personajes = {}
    n_jugadores = 0	
    fecha_fichero = 0

    sala = SalaEditable(id, version, autor, area, comentario, nombre, descripcion,
	                salidas, tipo, subtipo, volumen, luz, aura, combate, ocultabilidad,
			contadores, etiquetas, objetos, encuentros, personajes, n_jugadores,
			fecha_fichero)

    return sala

