text: # -*-coding:Utf-8 -*
  
  # Copyright (c) 2010-2017 LE GOFF Vincent
  # All rights reserved.
  # 
  # Redistribution and use in source and binary forms, with or without
  # modification, are permitted provided that the following conditions are met:
  # 
  # * Redistributions of source code must retain the above copyright notice, this
  #   list of conditions and the following disclaimer.
  # * Redistributions in binary form must reproduce the above copyright notice,
  #   this list of conditions and the following disclaimer in the documentation
  #   and/or other materials provided with the distribution.
  # * Neither the name of the copyright holder nor the names of its contributors
  #   may be used to endorse or promote products derived from this software
  #   without specific prior written permission.
  # 
  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
  # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  # pereIBILITY OF SUCH DAMAGE.
  
  
  """Ce fichier définit le contexte-éditeur 'edt_sorties'."""
  
  from primaires.interpreteur.editeur import Editeur
  from primaires.interpreteur.editeur.env_objet import EnveloppeObjet
  from primaires.salle.sorties import NOMS_SORTIES
  from .edt_sortie import EdtSortie
  
  class EdtSorties(Editeur):
      
      """Contexte-éditeur d'édition des sorties.
      
      """
      
      def __init__(self, pere, objet=None, attribut=None):
          """Constructeur de l'éditeur"""
          Editeur.__init__(self, pere, objet, attribut)
          self.ajouter_option("r", self.opt_renommer_sortie)
          self.ajouter_option("s", self.opt_changer_sortie)
          self.ajouter_option("d", self.opt_suppr_sortie)
      
      def accueil(self):
          """Message d'accueil du contexte"""
          salle = self.objet
          msg = "| |tit|" + "Edition des sorties de {}".format(salle).ljust(76)
          msg += "|ff||\n" + self.opts.separateur + "\n"
          msg += self.aide_courte
          msg += "Sorties courantes :\n"
          
          # Parcours des sorties
          sorties = salle.sorties
          liste_sorties = ""
          for nom in NOMS_SORTIES.keys():
              direction = "\n  |ent|" + nom.ljust(10) + "|ff| :"
              sortie = sorties[nom]
              if sortie:
                  destination = ""
                  if sortie.nom != nom:
                      destination = " vers " + sortie.nom_complet + ""
                      destination += " (|vr|" + str(sortie.salle_dest) + "|ff|)"
                  else:
                      destination = " vers |vr|" + str(sortie.salle_dest) + "|ff|"
                  reciproque = sortie.correspondante and (", réciproque : " \
                          "|cy|" + sortie.correspondante + "|ff|") or " "
                  liste_sorties += direction
                  liste_sorties += destination
                  liste_sorties += reciproque
          if not liste_sorties:
              liste_sorties += "\n Aucune sortie pour l'instant."
          msg += liste_sorties
          
          return msg
      
      def opt_renommer_sortie(self, arguments):
          """Renomme une sortie en un autre nom
          La syntaxe pour renommer une sortie est :
              /r ancien_nom / nouveau nom (/ article)
          
          """
          salle = self.objet
          sorties = salle.sorties
          try:
              ancien_nom, nouveau_nom, article = arguments.split(" / ")
          except ValueError:
              try:
                  ancien_nom, nouveau_nom = arguments.split(" / ")
                  article = ""
              except ValueError:
                  self.pere << "|err|La syntaxe est invalide pour cette " \
                          "option.|ff|"
                  return
          
          try:
              ancien_nom = sorties.get_nom_long(ancien_nom)
          except KeyError:
              self.pere << "|err|La direction '{}' est " \
                      "inconnue.|ff|".format(ancien_nom)
          else:
              nouveau_nom = nouveau_nom.lower()
              sortie = sorties[ancien_nom]
              if sortie is None:
                  self.pere << "|err|Cette sortie n'existe pas.|ff|"
                  return
              
              try:
                  t_val = sorties.get_sortie_par_nom_ou_direction(nouveau_nom)
                  if t_val is None or t_val.direction != ancien_nom:
                      self.pere << "|err|Ce nom de sortie est déjà utilisé.|ff|"
                      return
              except KeyError:
                  pass
              
              sortie.nom = nouveau_nom
              sortie.deduire_article()
              if article:
                  sortie.article = article
              self.actualiser()
      
      def opt_changer_sortie(self, arguments):
          """Modifie une sortie comme setexit
          Le fonctionnement est le même, cette option permet de lier un sortie
          à une salle.
          Syntaxe : /s nom / id_salle
              
          """
          salle = self.objet
          sorties = salle.sorties
          try:
              nom, id_salle = arguments.split(" / ")
          except ValueError:
              self.pere << "|err|La syntaxe est invalide pour cette " \
                      "option.|ff|"
              return
          try:
              nom = sorties.get_nom_long(nom)
          except KeyError:
              self.pere << "|err|La direction '{}' n'existe pas.|ff|".format(nom)
              return
          try:
              d_salle = type(self).importeur.salle[id_salle]
          except KeyError:
              self.pere << \
                  "|err|L'identifiant '{}' n'est pas valide.|ff|".format(id_salle)
              return
          
          dir_opposee = sorties.get_nom_oppose(nom)
          if sorties.sortie_existe(nom):
              self.pere << \
                  "|err|Cette direction a déjà été définie dans la salle " \
                  "courante.|ff|"
              return
          if d_salle.sorties.sortie_existe(dir_opposee):
              self.pere << \
                  "|err|La direction opposée a déjà été définie dans {}.|ff|". \
                  format(d_salle.ident)
              return
          if salle is d_salle:
              self.pere << \
                  "|err|La salle de destination est la même que la salle " \
                  "d'origine.|ff|"
              return
          
          sorties.ajouter_sortie(nom, nom,
                  salle_dest=d_salle, corresp=dir_opposee)
          d_salle.sorties.ajouter_sortie(dir_opposee, dir_opposee,
                  salle_dest=salle, corresp=nom)
          self.actualiser()
      
      def opt_suppr_sortie(self, arguments):
          """Supprime une sortie
          Syntaxe : /d nom
          
          """
          salle = self.objet
          sorties = salle.sorties
          nom = arguments
          
          try:
              d_salle = sorties[nom].salle_dest
          except (KeyError, AttributeError):
              self.pere << "|err|La sortie spécifiée n'existe pas.|ff|"
          else:
              dir_opposee = salle.sorties.get_nom_oppose(nom)
              
              d_salle.sorties.supprimer_sortie(dir_opposee)
              salle.sorties.supprimer_sortie(nom)
              self.actualiser()
      
      def interpreter(self, msg):
          """Interprétation de la présentation"""
          salle = self.objet
          sorties = salle.sorties
          
          try:
              sortie = sorties[msg]
              if not sortie:
                  raise AttributeError
          except (KeyError, AttributeError):
              self.pere << "|err|La sortie spécifiée n'existe pas.|ff|"
          else:
              enveloppe = EnveloppeObjet(EdtSortie, sortie, None)
              enveloppe.parent = self
              enveloppe.aide_courte = \
                  "Entrez |ent|/|ff| pour revenir à la fenêtre parente.\n" \
                  "Options :\n" \
                  " - |cmd|/r <nouveau nom> (/ <préfixe>)|ff| : renomme la " \
                  "sortie\n" \
                  " - |cmd|/s <identifiant d'une salle>|ff| : fait pointer la " \
                  "sortie vers la salle\n" \
                  "   spécifiée\n" \
                  " - |cmd|/dq|ff| : détruit la sortie réciproque (permet de " \
                  "créer des sorties à sens\n   unique)\n" \
                  " - |cmd|/c|ff| : bascule l'état caché de la sortie\n" \
                  " - |cmd|/p (<clef>)|ff| : ajoute ou supprime une porte à " \
                  "la sortie ; vous pouvez\n" \
                  "   préciser l'identifiant d'un objet de type clef"
              if sortie.direction in ("bas", "haut"):
                  enveloppe.aide_courte += \
                      "\n - |cmd|/e <difficulté à escalader entre 1 et 10|ff|"
              contexte = enveloppe.construire(self.pere)
              self.migrer_contexte(contexte)
  