#!/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
#
#
#Boa:MDIChild:frArbol


#GPT Me falta comentar casi todo y reescribir casi todo, pero por ahora funciona

"""Clase frArbol"""
from dircache import *
import os 
import Sala
from wxPython.wx import *
import logging

log = logging.getLogger("Editor")

def create(parent):
    return frArbol(parent)

[wxID_FRARBOL, wxID_FRARBOLPANEL1, wxID_FRARBOLTCNAVEGADOR, 
] = map(lambda _init_ctrls: wxNewId(), range(3))



class frArbol(wxMDIChildFrame):
    """ Arbol de navegación lógico para el Ambartan (el editor de Mine)"""
    
    
    def _init_utils(self):
        # generated method, don't edit
        pass

    def _init_ctrls(self, prnt):
        # generated method, don't edit
        wxMDIChildFrame.__init__(self, id=wxID_FRARBOL, name='frArbol',
              parent=prnt, pos=wxPoint(0, 0), size=wxSize(255, 588),
              style=wxDEFAULT_FRAME_STYLE, title='Arbol')
        self._init_utils()
        self.SetClientSize(wxSize(247, 561))
        EVT_SIZE(self, self.OnFrarbolSize)
        EVT_MAXIMIZE(self, self.OnFrarbolMaximize)

        self.panel1 = wxPanel(id=wxID_FRARBOLPANEL1, name='panel1', parent=self,
              pos=wxPoint(0, 0), size=wxSize(247, 561), style=wxTAB_TRAVERSAL)

        self.tCNavegador = wxTreeCtrl(id=wxID_FRARBOLTCNAVEGADOR,
              name='tCNavegador', parent=self.panel1, pos=wxPoint(0, 0),
              size=wxSize(248, 560), style=wxTR_HAS_BUTTONS,
              validator=wxDefaultValidator)
        EVT_TREE_ITEM_ACTIVATED(self.tCNavegador, wxID_FRARBOLTCNAVEGADOR,
              self.OnTcnavegadorTreeItemActivated)

    def __init__(self, parent):
        self._init_ctrls(parent)
        self.initNavegador()
        self.padre=parent
        
    def initNavegador(self):
        #creamos la lista de imágenes para usarla en el árbol
        isz = (16,16)
        il = wxImageList(isz[0], isz[1])
        self.fldridx     = il.Add(wxArtProvider_GetBitmap(wxART_FOLDER,      wxART_OTHER, isz))
        self.fldropenidx = il.Add(wxArtProvider_GetBitmap(wxART_FILE_OPEN,   wxART_OTHER, isz))
        self.fileidx     = il.Add(wxArtProvider_GetBitmap(wxART_REPORT_VIEW, wxART_OTHER, isz))
        self.tCNavegador.SetImageList(il)
        self.il = il
                        
        #rehacer entero añadiendo métodos para mayor claridad.
        #directorio=opendir('.')
        self.root = self.tCNavegador.AddRoot("Elementos")
        
        self.tCNavegador.SetItemImage(self.root, self.fldridx, wxTreeItemIcon_Normal)
        self.tCNavegador.SetItemImage(self.root, self.fldropenidx, wxTreeItemIcon_Expanded)
        self.tCNavegador.SetPyData(self.root, "raiz")
        #añadimos los directorios de zonas
        self.nodoSalas = self.tCNavegador.AppendItem(self.root, "Salas")
        self.tCNavegador.SetPyData(self.nodoSalas, "zona")
        self.tCNavegador.SetItemImage(self.nodoSalas, self.fldridx, wxTreeItemIcon_Normal)
        self.tCNavegador.SetItemImage(self.nodoSalas, self.fldropenidx, wxTreeItemIcon_Expanded)


        #añadimos los directorios de Objetos
        self.nodoObjetos = self.tCNavegador.AppendItem(self.root, "Objetos")
        self.tCNavegador.SetPyData(self.nodoObjetos, "zona")
        self.tCNavegador.SetItemImage(self.nodoObjetos, self.fldridx, wxTreeItemIcon_Normal)
        self.tCNavegador.SetItemImage(self.nodoObjetos, self.fldropenidx, wxTreeItemIcon_Expanded)
        #añadimos los directorios de PNJ
        self.nodoPNJ = self.tCNavegador.AppendItem(self.root, "PNJ")
        self.tCNavegador.SetPyData(self.nodoPNJ, "zona")
        self.tCNavegador.SetItemImage(self.nodoPNJ, self.fldridx, wxTreeItemIcon_Normal)
        self.tCNavegador.SetItemImage(self.nodoPNJ, self.fldropenidx, wxTreeItemIcon_Expanded)
        #dirSala=opendir('./desc_salas')
        dirSala=opendir(Sala.DIR_DESC_SALAS)
        for fi in dirSala:
	    fi = unicode(fi)
            fichero=Sala.DIR_DESC_SALAS+ '/'+fi
            #fichero=fi
            if os.path.isdir(fichero) and not(fi=='CVS'):               
                self.addDirectorio(fi) 
        log.debug("dirSala = " + str(dirSala))
        
        
    #añade un directorio de zona dado el nombre de la zona devolviendo el nodo
    #que se crea. Crea todos los nodos de sala que estén dentro del directorio
    #creo que habrá que sacarlo fuera de la clase, ya que en esta clase no se
    #gestiona fisicamente los directorios... o bien pasarlo para que esta clase
    #si gestione los directorios y ficheros
    def addDirectorio(self, nombreDir):
        #añade un directorio de zona dado el nombre de la zona devolviendo el nodo
        #que se crea
        #comprobar si ya existe el área y devolver una excepción *************
        nodoZona = self.addZona(nombreDir)
        #añadimos los nombres de las salas a cada zona    
        zonas=opendir(Sala.DIR_DESC_SALAS+ '/'+nombreDir)
        for zo in zonas:
            try:
		zo = unicode(zo)
                if zo.split('.')[1]=="xml": #vemos si tiene extensión
                    nombre=(zo.split('.')[0]).split('-')[1]
                    self.addSalaPorNodo(nodoZona,nombre)                  
                            
            except IndexError:
                #hemos tenido un error con el split, el fichero no
                #tenia extensión, lo ignoramos y no lo incluimos en el arbol
                pass
    
    #añade una zona al arbol devolviendo el nodo creado
    def addZona(self, nombreZona):
        NodeError = 'NodeError'
        ZonaError = 'ZonaError'
        try:
            self.getNodoPorNombre(nombreZona, self.nodoSalas)
        except NodeError:
            nodoZona = self.tCNavegador.AppendItem(self.nodoSalas, nombreZona)
            self.tCNavegador.SetPyData(nodoZona, "zona")
            self.tCNavegador.SetItemImage(nodoZona, self.fldridx, wxTreeItemIcon_Normal)
            self.tCNavegador.SetItemImage(nodoZona, self.fldropenidx, wxTreeItemIcon_Expanded)
        else:
            raise ZonaError, 'la zona de nombre ' + nombreZona + ' ya existe'        
        return nodoZona
        
    def removeSala(self,nombreZona, nombreSala):
        #Elimina una sala dado un nombre de zona y un nombre de sala, si la zona
        #no existe devuelve una excepcion.   
        NodeError = 'NodeError'
        ZonaError = 'ZonaError'
        try:
            nodoZona=self.getNodoPorNombre(nombreZona, self.nodoSalas)            
        except NodeError:            
            raise ZonaError, 'esa zona no existe'
        else:
            self.removeSalaPorNodo(nodoZona,nombreSala)     
            
    def addSala(self,nombreZona, nombreSala):  
        #añade una sala dado un nombre de zona y un nombre de sala, si la zona
        #no existe devuelve una excepcion.   
        NodeError = 'NodeError'
        ZonaError = 'ZonaError'
        try:
            nodoZona=self.getNodoPorNombre(nombreZona, self.nodoSalas)            
        except NodeError:            
            raise ZonaError, 'esa zona no existe'
        else:
            self.addSalaPorNodo(nodoZona,nombreSala)
    
    def removeSalaPorNodo(self, nodoZona, nombreSala):
        #Borra una sala de un nodo de zona si se conoce el nodo de la zona
        NodeError = 'NodeError'
        SalaError = 'SalaError'
        try:
            nodoSala = self.getNodoPorNombre(nombreSala, nodoZona)
            self.tCNavegador.Delete(nodoSala)
            #falta informar si es el último nodo de una zona para eliminarlo
            #Si es que se quiere eliminar las zonas sin contenidos...
            #no me gusta lo siguiente pq hay que eliminar tb el directorio...
            #¿pasar definitivamente todo lo de directorios y ficheros aqui?
            #if not self.tCNavegador.ItemHasChildren(nodoZona):
            #    self.tCNavegador.Delete(nodoZona)                
        except NodeError:
            raise SalaError, 'No existe ninguna sala de nombre ' + nombreSala +' en la zona ' 
            
    def addSalaPorNodo(self, nodoZona, nombreSala):
        #añade una sala a un nodo de zona si se conoce el nodo de la zona
        NodeError = 'NodeError'
        SalaError = 'SalaError'
        try:
            self.getNodoPorNombre(nombreSala, nodoZona)
            #Ya existe una sala con ese nombre en la zona
        except NodeError:
            nodoSala = self.tCNavegador.AppendItem(nodoZona, nombreSala)
            self.tCNavegador.SetItemImage(nodoSala, self.fileidx, wxTreeItemIcon_Normal)
            self.tCNavegador.SetItemImage(nodoSala, self.fileidx, wxTreeItemIcon_Selected)
            nombreZona=self.tCNavegador.GetItemText(nodoZona)
            self.tCNavegador.SetPyData(nodoSala, nombreZona + '-' + nombreSala)
        else:
            raise SalaError, 'Ya existe una sala con nombre: ' + nombreSala + ' en la zona'
        
    def getNodoPorNombre(self, nombre, padre):
        #recupera el nodo correspondiente a una etiqueta, dado el nodo del
        #padre del cual debemos buscar
        #el padre tiene que ser un nodo
        
        #no me gusta, tengo que mejorar este bucle...
        NodeError = 'NodeError'
        if self.tCNavegador.ItemHasChildren(padre) == True:
            iterador = 0
            (nodo,iterador)=self.tCNavegador.GetFirstChild(padre,iterador)
            nodo2=self.tCNavegador.GetLastChild(padre)
            textoNodo = self.tCNavegador.GetItemText(nodo)
            textoNodo2 = self.tCNavegador.GetItemText(nodo2)
            encontrado = False
            #buscamos el nodo
            while encontrado == False and textoNodo != textoNodo2:
                if textoNodo == nombre:
                    encontrado = True
                else:
                    (nodo,iterador)=self.tCNavegador.GetNextChild(padre,iterador)
                    textoNodo = self.tCNavegador.GetItemText(nodo)
            
            if textoNodo != nombre and encontrado == False:               
		raise NodeError, u'no existe ningún hijo de nombre ' + nombre
            else:
                return nodo
        else:
            raise NodeError, u'no existe ningún hijo de nombre ' + nombre
            
    def borrar(self):
        #falta comprobar cuando se borra desde el Arbol si se está mostrando las
        #salas que se borran
        ZonaError = 'ZonaError'
        
        nodo=self.tCNavegador.GetSelection()
        datos = self.tCNavegador.GetPyData(nodo)
        textoNodo = self.tCNavegador.GetItemText(nodo)
        
        if (datos == "zona"):
            #Borrar una zona
            caption = 'Borrar Zona'
            msg = '¿Desea borrar la zona ' + textoNodo + ' ?\n'
            msg = msg + 'Todas las salas de la zona también se borrarán'
            dlg = wxMessageDialog(self, msg, caption, wxYES_NO | wxICON_QUESTION  )
            try:
                respuesta=dlg.ShowModal()
                if respuesta==wxID_YES:
                    try:
                        #self.removeSala(datos.split('-')[0],datos.split('-')[1])
                        ficheros = opendir(os.path.join(Sala.DIR_DESC_SALAS,textoNodo))
                        #os.removedirs(os.path.join(Sala.DIR_DESC_SALAS,textoNodo))                                                
                        for fichero in ficheros:
			    fichero = unicode(fichero)
                            os.remove(os.path.join(Sala.DIR_DESC_SALAS,textoNodo,fichero))
                        os.rmdir(os.path.join(Sala.DIR_DESC_SALAS,textoNodo))
                        
                        #se borra el nodo de zona
                        self.tCNavegador.DeleteChildren(nodo)
                        self.tCNavegador.Delete(nodo)
                    except ZonaError:
                        #No debería darse cuando todo esté bien gestionado
                        pass
                else:
                    pass    
            finally:
                dlg.Destroy()        
        
        elif (datos == "raiz") or (datos == "Salas" ) or (datos == "Objetos" ) or (datos == "PNJ" ):
            msg = "No se pueden borrar esos nodos"
            dlg = wxMessageDialog(self, msg,
              'Atención', wxOK | wxICON_INFORMATION)
            try:
                dlg.ShowModal()
            finally:
                dlg.Destroy()
            
        else:    
            #borramos una Sala
            #GPT Falta comprobar que no se está mostrando esa sala en un dialogo           
            #mensaje preguntando
            caption = 'Borrar Sala'
            mensaje = '¿Desea borrar la sala ' + datos.split('-')[1] + ' ?'
            dlg = wxMessageDialog(self, mensaje,
                             caption, wxYES_NO | wxICON_QUESTION  )
            try:
                respuesta=dlg.ShowModal()
                if respuesta==wxID_YES:
                    try:
                        self.removeSala(datos.split('-')[0],datos.split('-')[1])
                        os.remove(os.path.join(Sala.DIR_DESC_SALAS,datos.split('-')[0],datos + Sala.EXT_DESC_SALAS ))
                    except ZonaError:
                        #No debería darse cuando todo esté bien gestionado
                        pass
                else:
                    pass    
            finally:
                dlg.Destroy()            
        
    
    def OnTcnavegadorTreeItemActivated(self, event):
        nodo=self.tCNavegador.GetSelection()
        datos = self.tCNavegador.GetPyData(nodo)
        if not (datos == "zona") and not (datos == "raiz") and not (datos == "Salas" ) and not (datos == "Objetos" ) and not (datos == "PNJ" ):
            self.padre.AbrirSala(datos)
        event.Skip()

    def OnFrarbolSize(self, event):
        #self.SetClientSize(wxSize(247, 561))
        event.Skip()

    def OnFrarbolMaximize(self, event):
        #self.restore()
        #event.Skip()
        wxBell()
        
    def cerrar(self):
        return True        
    

                    
