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

"""Clase Fragmento."""


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

from utils import *
from bloquedialogo import *

class Fragmento(BloqueDialogo):
    """Secuencia de texto que se presenta al activar un tema de la conversación.
    
    Contiene los siguientes atributos:
    - _item: item en el que está contenido este fragmento
    - _sujeto: personaje del dialogo que dice el fragmento de texto
    - _texto: arbol xml con la estructura de texto del fragmento
    - _retardo: número proporcional al tiempo que tarda en mostrarse el fragmento.
    - _nombre: en los eventos, nombre del hito que se va a crear
    
    Invariantes:
    _item != None
    _sujeto != None
    _texto != None
    _retardo >= 0
    
    """
    
    # Número de caracteres leídos por segundo
    VELOCIDAD_LECTURA = 30 #Valor por defecto: 30
    
    def __init__(self, fragmento_xml, item):
        self._item = item
        fragmento_xml.normalize()
        self._clase = fragmento_xml.tagName.encode('ISO-8859-1')
        self._texto = fragmento_xml.cloneNode(1)
	if fragmento_xml.getAttribute("retardo"):
	    self._retardo = string.atoi(fragmento_xml.getAttribute("retardo")) * self.VELOCIDAD_LECTURA
	else:
            self._retardo = len(self.mensaje_formateado(None, "otros")) + self.VELOCIDAD_LECTURA
	if self._clase == "hito":
	    self._nombre = fragmento_xml.getAttribute("nombre")
	    self._retardo = 0
	if fragmento_xml.getAttribute("texto_unico"):
	    self._texto_unico = fragmento_xml.getAttribute("texto_unico")
        
    def mensaje_formateado(self, visita, oyente = "otros"):
        """Texto del fragmento, adaptado al oyente y a los hablantes del dialogo actual

        visita: estado de la conversacion. Se usa para transformar las macros contenidas en el fragmento.
        oyente(Personaje): personaje que escucha el fragmento de texto
        """
        mensaje = self._texto
	mensaje.normalize()        
        return self._mensaje_formateado(visita, mensaje, oyente)
    
    def _mensaje_formateado(self, visita, mensaje, oyente):
        """
        Requiere:
        - visita == None o len(visita.items()) > 0
        - visita.pj_activo.sexo != None
        """
	texto = ""
        if mensaje.tagName == "pj" and visita:
            texto = texto + visita.pj_activo.nombre
        elif mensaje.tagName == "pnj" and visita:
            texto = texto + visita.pnj.nombre
        else:
            for fragmento in mensaje.childNodes:
              try:
                if fragmento.nodeType == fragmento.TEXT_NODE:
                    texto = texto + fragmento.data.encode('ISO-8859-1')
                # Macro oyente: elimina fragmentos no destinados a este oyente
                elif fragmento.tagName == oyente:
                    fragmento.normalize()
                    texto = texto + self._mensaje_formateado(visita, fragmento, oyente)
                # Macro <pj/>: nombre del personaje activo (el que hace la pregunta)
                elif fragmento.tagName == "pj" and visita:
                    texto = texto + visita.pj_activo.nombre
                # Macro <pnj/>: nombre del personaje no jugador que lleva la conversacion
                elif fragmento.tagName == "pnj" and visita:
                    texto = texto + visita.pnj.nombre
                # Macro <oa/>: genero en funcion del sexo del personaje activo
                elif fragmento.tagName == "oa" and visita:
                    if visita.pj_activo.sexo == "femenino":
                        texto = texto + "a"
                    else:
                        texto = texto + "o"
                # Macro <a/>: añade "a" opcionalmente si el sexo del personaje activo es femenino
                elif fragmento.tagName == "a" and visita:
                    if visita.pj_activo.sexo == "femenino":
                        texto = texto + "a"
                # Macro <m/>: añade el texto opcionalmente si el sexo del personaje activo es masculino
                elif fragmento.tagName == "m" and visita:
                    if visita.pj_activo.sexo == "masculino":
                        texto = texto + fragmento.data.encode('ISO-8859-1')
                # Macro <f/>: añade el texto opcionalmente si el sexo del personaje activo es femenino
                elif fragmento.tagName == "f" and visita:
                    if visita.pj_activo.sexo == "femenino":
                        texto = texto + fragmento.data.encode('ISO-8859-1')
                # Macro <nombretema/>: nombre del ultimo tema solicitado
                elif fragmento.tagName == "nombretema" and visita:
                    texto = texto + visita._nombretema
                # Macro <tema/>: nombre del ultimo tema sobre el que se ha llegado a hablar
                elif fragmento.tagName == "tema" and visita:
                    antiguedad = 0
                    if fragmento.getAttribute("antiguedad"):
                        antiguedad = string.atoi(fragmento.getAttribute("antiguedad"))
                        if len(visita.items()) <= antiguedad:
                            antiguedad = len(visita.items()) - 1
                    texto = texto + visita.items()[antiguedad].tema().nombre()
                # Macro <contexto/>: nombre del ultimo contexto visitado
                elif fragmento.tagName == "contexto" and visita:
                    antiguedad = 0
                    if fragmento.getAttribute("antiguedad"):
                        antiguedad = string.atoi(fragmento.getAttribute("antiguedad"))
                        if len(visita.items()) <= antiguedad:
                            antiguedad = len(visita.items()) - 1
                    texto = texto + visita.items()[antiguedad].tema().contexto().nombre()
              except Exception:
                  texto = texto + "[...]"
	          escribir( "Ha saltado una excepcion en fragmento " + texto)
	          escribir_excepcion()
        return texto

    
    def item(self):
        return self._item
    
    def clase(self):
        return self._clase
    
    def texto_xml(self):
        return self._texto

    def retardo(self, velocidad = VELOCIDAD_LECTURA):
        """ Devuelve el número de segundos que se detiene la conversación mientras se muestra el fragmento. """
        return self._retardo / velocidad
    
    def __str__(self):
        return self.mensaje_formateado(None, "otros")
