
#include "LesReferences.h"
#include "PtTabRel.h"
#include "ReferenceAF.h"
#include "ReferenceNE.h"
#include "ReferencePtiAF.h"

//-------- une méthode permettant d'utiliser des tableaux de map de références -----
   // surcharge de l'operator d'ecriture
   ostream & operator << (ostream & sort, const map < string, Reference*, std::less <string> > & )
     { // tout d'abord un indicateur donnant le type
       if (ParaGlob::Francais()) {sort << " \n erreur (de developpement) a une fonction d'ecriture << d'une map de reference "
                                  << " voir LesReference.h "; }
       else  {sort << " \n error (for developper) for the writing method  << concerning a map of references  "
                                  << " see LesReference.h "; }
       Sortie(1);  return sort;      
     };
//----------- fin de la méthode permettant d'utiliser des tableaux de map de références -----

// --------------- variables statiques ---------
 MotCle LesReferences::motCle; // liste des mots clés

LesReferences::LesReferences () :  // par defaut
    t_mapDeRef(),ref(NULL),num_mail_presuivant(0),listeNomMail(NULL)
    { nbMaille =1;
      indic = 0;
    }; 
// DESTRUCTEUR :
LesReferences::~LesReferences ()
    { // effacement des grandeurs pointées par la liste de référence
      int taille = t_mapDeRef.Taille();
      for (int i=1;i<=taille;i++)
      	{ map < string, Reference*, std::less <string> >& mapDeRef = t_mapDeRef(i);
      	  map < string, Reference*, std::less <string> >::iterator il,ilfin = mapDeRef.end();
          for (il=mapDeRef.begin() ; il != ilfin; il++)
             if ((*il).second != NULL) {delete (*il).second;(*il).second=NULL;};
           mapDeRef.erase(mapDeRef.begin(),mapDeRef.end());
         };
    };
    
// def du numero de maillage courant, utilise avant la lecture
void LesReferences::NbMaille(int nb) { nbMaille = nb; };
// def du type de reference a lire, utilise avant la lecture
void LesReferences::Indic(string type) 
   { if (type == "noeud") indic = 1;
     else if (type == "element") indic =2;
     else if(type == "surface") indic = 3;
     else if(type == "arete")indic = 4;
     else if(type == "noeud_element")indic = 5;
     else if(type == "pt_integ_element")indic = 6;
     else if(type == "pt_integ_face_element")indic = 7;
     else if(type == "pt_integ_arete_element")indic = 8;
     else if(type == "rien_actuellement") indic = 0;
     else 
       { if (ParaGlob::Francais()) {cout << " \n **** erreur de type de reference, type donne = " << type;}
         else  {cout << " \n **** error of type of reference, type  = " << type;}
         cout << "LesReferences::Indic(string type)" << endl;
         Affiche();
         Sortie(1);
       };
    };    
    
// lecture des references
 void LesReferences::Lecture(UtilLecture & entreePrinc)
    { // on lit des references temps qu'il n'y a pas de pb
      if (indic < 0)
        { if (ParaGlob::Francais()) 
		         {cout << " \n erreur en lecture de reference, le type de reference n\'st pas defini " ;}
		    else {cout << " \n error in reading a reference, the reference type is not defined " ;};
          cout << "\n LesReferences::LectureLesReferences(etc ... " << endl;
          Affiche();
          Sortie(1);
         } 
      while ( LectureReference(entreePrinc))
      // la methode LectureReference cree une référence pointée par ref
         { // verification que l'on n'a pas deux references identiques
           if (Existe(ref->Nom(),ref->Nbmaille()))   
             { if (ParaGlob::Francais()) 
		              { cout <<" \n Erreur de lecture de reference, deux refs ont le meme nom \n";
                  cout <<" nom = " << ref->Nom() << " pour le meme maillage nb: " 
                       << ref->Nbmaille() << '\n';}
		             else { cout <<" \n Error in reading a reference, two refs have the same name  \n";
                      cout <<" name = " << ref->Nom() << " for the same mesh nb: "
                           << ref->Nbmaille() << '\n';}
               cout <<"LesReferences::LectureLesReferences(UtilLecture & entreePrinc)" 
                    << endl;
               entreePrinc.MessageBuffer("lecture des  references");                                    
               throw (UtilLecture::ErrNouvelleDonnee(-1));
               Sortie (1);
              }
           else
             {int num_mail = ref->Nbmaille();
              if (num_mail < 1 )
                // on vérifie que le numéro de maillage est licite
                { if (ParaGlob::Francais()) 
		              { cout << "\n erreur, on veut ajouter une reference sur le maillage numero nul ou negatif : " << num_mail << " ";}
						        else { cout << "\n error, we cannot add a reference on the mesh, number : " << num_mail << " ";}
                  ref->Affiche();
    	          cout << "\n LesReferences::LectureLesReferences(... ";
    	          Sortie(1);
                }
              else if (num_mail > t_mapDeRef.Taille())
                // maintenant on regarde si l'on a déjà enregistré dans ce maillage
                { t_mapDeRef.Change_taille(num_mail);
                 };       
              // puis on enregistre
              t_mapDeRef(num_mail)[ref->Nom()]=ref;
              // t_mapDeRef(nbMaille)[ref->Nom()]= ref;
             };
          }
     };
     
// ajout d'une référence déjà construite par ailleurs
void LesReferences::Ajout_reference(Reference * refi) 
  { int num_mail = refi->Nbmaille();
    if (num_mail < 1 )
      // on vérifie que le numéro de maillage est licite
      { if (ParaGlob::Francais()) 
		       { cout << "\n erreur, on veut ajouter une reference sur le maillage numero nul ou negatif : "
                << num_mail << " ";
         }
		      else
         { cout << "\n error, we cannot add a reference on the mesh, number : " << num_mail << " ";}
		      refi->Affiche();
    	   cout << "\n LesReferences::Ajout_reference(Reference * refi) ";
    	   Sortie(1);
      }
    else if (num_mail > t_mapDeRef.Taille())
      // maintenant on regarde si l'on a déjà enregistré dans ce maillage
     { t_mapDeRef.Change_taille(num_mail);
     };
    // supprime les doublons internes éventuels dans la référence
    refi->Supprime_doublons_internes();
    // puis on enregistre
    t_mapDeRef(num_mail)[refi->Nom()]=refi;
    return;
  };
    
// affichage et definition interactive des commandes 
// nbMaxiNoeud: nombre maxi de noeud pour les exemples
void LesReferences::Info_commande_lesRef(int nbMaxiNoeud,int nbMaxiElem,UtilLecture * entreePrinc,int cas)
  { 
    // on dimensionne la taille de t_mapDeRef
	 if ( nbMaille > t_mapDeRef.Taille())
          // maintenant on regarde si l'on a déjà enregistré dans ce maillage
          { t_mapDeRef.Change_taille(nbMaille);
           };
  
  
  switch (cas)
    { case 1: 
       {// en fait on s'occupe ici uniquement des références de noeuds
        ref = new ReferenceNE("N_exemple_ref_NE", nbMaille,1);
        ref-> Info_commande_Ref(nbMaxiNoeud,entreePrinc,cas);
        t_mapDeRef(nbMaille)[ref->Nom()]= ref; 
        break;
        }
      case 2:
       {// cas de toutes les références
		      ref = new ReferenceNE(nbMaille,1); // cas d'une ref de noeuds
        ref-> Info_commande_Ref(nbMaxiNoeud,entreePrinc,cas);
        t_mapDeRef(nbMaille)[ref->Nom()]= ref; 
		      ref = new ReferenceNE(nbMaille,2); // cas d'une ref d'elements
        ref-> Info_commande_Ref(nbMaxiElem,entreePrinc,cas);
        t_mapDeRef(nbMaille)[ref->Nom()]= ref; 
		      ref = new ReferenceAF(nbMaille,3); // cas d'une ref de surfaces
        ref-> Info_commande_Ref(nbMaxiElem,entreePrinc,cas);
        t_mapDeRef(nbMaille)[ref->Nom()]= ref; 
		      ref = new ReferenceAF(nbMaille,4); // cas d'une ref d'arrete
        ref-> Info_commande_Ref(nbMaxiElem,entreePrinc,cas);
        t_mapDeRef(nbMaille)[ref->Nom()]= ref; 
		      ref = new ReferenceAF(nbMaille,5); // cas d'une ref de noeud associé à un élément
        ref-> Info_commande_Ref(nbMaxiElem,entreePrinc,cas);
        t_mapDeRef(nbMaille)[ref->Nom()]= ref; 
		      ref = new ReferenceAF(nbMaille,6); // cas d'une ref de point d'intégration associé à un élément
        ref-> Info_commande_Ref(nbMaxiElem,entreePrinc,cas);
        t_mapDeRef(nbMaille)[ref->Nom()]= ref;
        ref = new ReferencePtiAF(nbMaille,7); // cas d'une ref de point d'intégration associé à une face d'élément
        ref-> Info_commande_Ref(nbMaxiElem,entreePrinc,cas);
        t_mapDeRef(nbMaille)[ref->Nom()]= ref;
        ref = new ReferencePtiAF(nbMaille,8); // cas d'une ref de point d'intégration associé à une arete d'élément
        ref-> Info_commande_Ref(nbMaxiElem,entreePrinc,cas);
        t_mapDeRef(nbMaille)[ref->Nom()]= ref;

        break;
        }
	  default :
	    { if (ParaGlob::Francais()) {cout << "\nErreur : valeur incorrecte du cas =  " << cas << "\n";}
		   else {cout << "\nError : incorrect value for the case  =  " << cas << "\n";}
          cout << "LesReferences::Info_commande_lesRef..." ;
		  Sortie(1);
	     };
	  }              
   };
          
// affichage des informations contenu dans les references
// par défaut affiche toutes les infos
// si niveau = 1 : affiche que les noms des ref
void LesReferences::Affiche(int niveau) const
  {   int taille = t_mapDeRef.Taille();
      for (int i=1;i<=taille;i++)
      	{ map < string, Reference*, std::less <string> >& mapDeRef = t_mapDeRef(i);
          map < string, Reference*, std::less <string> >::const_iterator i_map;
          if (ParaGlob::Francais()) {cout << " \n ------- affichage des listes de references ------- \n ";}
          else {cout << " \n ------- display of the lists of references ------- \n ";}; 
            for (i_map=mapDeRef.begin() ; i_map != mapDeRef.end(); i_map++)
               if (!niveau)
                 (*i_map).second->Affiche();
               else cout << " " << (*i_map).first ;
          cout << endl;
      	};
  };
 
// affichage des informations contenu dans les references d'un certain type
// défini par indic :
// indic =  1 -> noeud, =2 -> element
// =3 -> surface associée à un élément , =4 -> arete associée à un élément
// =5 -> noeud associée à un élément
// =6 -> point d'intégration associée à un élément
// =7 -> de points d'intégrations relatifs à des surfaces d'éléments
// =8 -> de points d'intégrations relatifs à des arrete d'éléments
// =0 -> rien_actuellement
// par défaut affiche toutes les infos
// si niveau = 1 : affiche que les noms des ref
void LesReferences::Affiche(int indic, int niveau) const
  { int taille = t_mapDeRef.Taille();
    for (int i=1;i<=taille;i++)
     	{  map < string, Reference*, std::less <string> >& mapDeRef = t_mapDeRef(i);
         map < string, Reference*, std::less <string> >::const_iterator i_map;
         if (ParaGlob::Francais()) {cout << " \n ------- affichage references ------- \n ";}
         else {cout << " \n ------- display references ------- \n ";};
         for (i_map=mapDeRef.begin() ; i_map != mapDeRef.end(); i_map++)
           if ((*i_map).second->Indic() == indic)
             {if (niveau==1)
               cout << " " << (*i_map).first ;
              else (*i_map).second->Affiche();
             };
         cout << endl;
     	};
  };


// Affiche les donnees des références pour le maillage imail dans un fichier
// dont le nom est construit à partir du nom du maillage au format   ".lis"
void LesReferences::Affiche_dans_lis(const string& nom_maillage,int imail)
  { // tout d'abord on vérifie qu'il existe des références pour ce maillage
    // ce qui peut-être fait de manière très simple en testant t_mapDeRef.Taille()
	   // si l'élément de tableau n'existe pas, ce n'est pas la peine de continuer, il n'y a pas de ref
	   // s'il existe, il y a peut-être des ref ... donc on continue
	   if (imail > t_mapDeRef.Taille())
	      return;
    // ouverture du fichier pour les noeuds
    char namm[132];
    char*fileNoome  = namm;
    strcpy(fileNoome, nom_maillage.c_str());
    ofstream * sur_sort = new ofstream (strcat(fileNoome,".lis"));
    ofstream & sort = * sur_sort;
    if(!(sort.is_open()))
      //  le fichier ne peut être ouvert, message d'erreur
     {  if (ParaGlob::Francais()) 
	            {cout << "\n erreur en ouverture pour l'ecriture du fichier  " << fileNoome << "\n";}
		      else {cout << "\n error, when trying to open for writing, the file " << fileNoome << "\n";};
		      cout  << " Maillage::Affiche_dans_her_lis(.... " << endl;
        Sortie(1);
     };
    // écriture de l'entete  
    if (ParaGlob::Francais())
	        {sort << "\n ###########################################################################"
               << "\n # ecriture automatique d'un maillage au format .lis, par Herezh++         #"
               << "\n ###########################################################################";}
    else {sort << "\n ###########################################################################"
               << "\n # automatic writing by Herezh++, of a mesh with format .lis               #"
               << "\n ###########################################################################";};
    sort << "\n # version: " <<  ParaGlob::NbVersion() << "\n \n \n ";
    // ---  écriture des références de noeuds
    if (ParaGlob::Francais()) {sort << "\n #    -- reference de noeud ";}
	   else                      {sort << "\n #    -- reference of nodes ";};
    // on passe en revue les différentes références pour trouver la bonne 
    map < string, Reference*, std::less <string> >& mapDeRef = t_mapDeRef(imail);
    map < string, Reference*, std::less <string> >::const_iterator il,ilfin=mapDeRef.end();
    for (il=mapDeRef.begin();il!=ilfin;il++)
      if ((*il).second->Indic()==1)
        {// on a trouvé une référence de noeud pour le maillage considéré
         (*il).second->Affiche_dans_lis(sort); // affichage
        };
    // ---  écriture des références des éléments
    if (ParaGlob::Francais()) {sort << "\n #    -- reference des elements ";} 
	   else                      {sort << "\n #    -- reference of elements ";}; 
    // on passe en revue les différentes références pour trouver la bonne 
    for (il=mapDeRef.begin();il!=ilfin;il++)
      if ((*il).second->Indic()==2)
        {// on a trouvé une référence d'element pour le maillage considéré
         (*il).second->Affiche_dans_lis(sort); // affichage
          }
    // ---  écriture des références de pt d'integ, noeuds, faces et arretes 
    if (ParaGlob::Francais()) 
	        {sort << "\n #    -- references de pt d'integ, noeuds, faces et arretes associes a des elements ";} 
	   else {sort << "\n #    -- references of Gauss points, nodes, facets, segments, associated with elements ";}; 
    // on passe en revue les différentes références pour trouver la bonne 
    for (il=mapDeRef.begin();il!=ilfin;il++)
      if (((*il).second->Indic()==3)||((*il).second->Indic()==4) 
         ||((*il).second->Indic()==5)||((*il).second->Indic()==6)
         ||((*il).second->Indic()==7)||((*il).second->Indic()==8))
        {// on a trouvé une référence de pt d'integ, noeuds, faces et arretes pour le maillage considéré
         (*il).second->Affiche_dans_lis(sort); // affichage
        };
    // quelques lignes blanches à la fin du fichier
    sort << "\n \n \n";
    // fermeture du fichier
    delete sur_sort;
  };
    
  
   // initialise le questionnement de la récupération de référence et
    // retourne la première référence si elle existe sinon un pointeur nul
const Reference* LesReferences::Init_et_Premiere()
  { num_mail_presuivant=0;
    Reference * refret = NULL;
    int t_taille = t_mapDeRef.Taille();
    if ( t_taille == 0) 
        return NULL;
    // sinon on boucle sur les éléments du tableaux  
	   // et on cherche la première ref valide qui existe
	   for (int i=1;i<=t_taille;i++)
      { iref = t_mapDeRef(i).begin();
    	   if (iref != t_mapDeRef(i).end())
    		   { num_mail_presuivant=i;
    	      refret = (*iref).second;
    	      break;
    		   };
      };
    // retour 
    return refret;
  };
       
    // retourne la référence suivante ou, s'il n'y en n'a plus, retourne
    // un pointeur nul
const Reference* LesReferences::Reference_suivante()
 { Reference * refret = NULL;
   if (num_mail_presuivant != 0)
 	  {iref++;
 	   if (iref != t_mapDeRef(num_mail_presuivant).end())
 	 	   { return (*iref).second;
       }
 	   // donc arrivé ici cela veut dire qu'on est sur une fin	
 	   else 
	      { // sinon on boucle sur les éléments du tableaux qui restent 
	        // et on cherche la première ref valide qui existe 
	        int t_taille = t_mapDeRef.Taille();
         for (int i=num_mail_presuivant+1;i<=t_taille;i++)
          { iref = t_mapDeRef(i).begin();
    	       if (iref != t_mapDeRef(i).end())
    		        { num_mail_presuivant=i;
    	           refret = (*iref).second;
    	           break;
    		        };
         };
       };
    };
   // retour 
   return refret;
 }; 	 
 	 
// test si la reference existe reellement
// retourne false si n'existe pas , true sinon
bool LesReferences::Existe(const string & st1,int num_mail) const 
  { // tout d'abord on regarde si le tableau de map n'est pas vide
    if (t_mapDeRef.Taille() == 0)
      return false; 
    // sinon on peut continuer
    bool existe=true;
    if (num_mail > t_mapDeRef.Taille())  
     { existe = false;
     }
    else if (t_mapDeRef(num_mail).find(st1) == t_mapDeRef(num_mail).end())  
     { existe = false;
     };
    // sinon c'est ok
    return existe;
  };
         
// idem mais avec un nom de maillage          
bool LesReferences::Existe(const string & st1,const string* nom_mail) const 
{ // tout d'abord on regarde si le tableau de map n'est pas vide
  if (t_mapDeRef.Taille() == 0)
      return false; 
  // sinon on peut continuer
  // on regarde si le nom de maillage est licite 
  if (nom_mail == NULL)
   { // acceptable que si l'on a un seul maillage
     #ifdef MISE_AU_POINT
     if (listeNomMail != NULL)
 		   if (listeNomMail->size() != 1)
		     if (ParaGlob::NiveauImpression() >2)
         { if (ParaGlob::Francais())
				            {cout << "\n warning: la reference demandee= " << st1 << " , n'a pas de nom de maillage associe"
                      << " alors qu'il y a plusieurs maillage defini !! : on considere que c'est une ref du premier maillage";}
				       else {cout << "\n warning: the wanted reference  " << st1 << " , has no associated mesh "
                      << " but several meshes exist !! : we consider that it is a ref for the first mesh ";}
				       if (ParaGlob::NiveauImpression() >5)		 
               { if (ParaGlob::Francais()) {cout << "\n nom_de_maillages= ";}
					            else {cout << "\n names of the meshes = ";}
					            map < string,  int , std::less <string> >::const_iterator ili,ilifin=listeNomMail->end();
                 for (ili = listeNomMail->begin();ili != ilifin; ili++)
                    cout << (*ili).first << ", " ;    
                 cout  << "\n  LesReferences::Existe(const string & st1,const string* nom_mail) ";
					          };
				     } 
//              Sortie(1);
     #endif
      // on ramène le cas du premier maillage qui doit exister
      return Existe(st1,1);     
   }
  else 
   {           
    #ifdef MISE_AU_POINT
      // on regarde si le nom de maillage existe dans la liste
      if (listeNomMail->find(*nom_mail) == listeNomMail->end())
       { if (ParaGlob::Francais()) {cout << "\nErreur : le nom de maillage :  " << *nom_mail << " n'existe pas \n";}
         else {cout << "\nError : the name of the mesh  :  " << *nom_mail << " does not exist  \n";}
		       if (ParaGlob::NiveauImpression() >5)
		       cout << "LesReferences::Existe(const string & st1,const string& nom_mail) \n";
		       Sortie(1);
		     }
    #endif
      return Existe(st1,(*(listeNomMail->find(*nom_mail))).second);
   };
};

// retourne la reference correspondant a une cle
const Reference& LesReferences::Trouve(const string & st1,int num_mail) const 
{ if (num_mail > t_mapDeRef.Taille())
	  { if (ParaGlob::Francais()) 
	      {cout << " \n pb la reference de nom " << st1 << " pour le maillage nb= "<< num_mail << " n'existe pas \n";}
		   else {cout << "\nError : the reference with the name " << st1 << " for the mesh nb= " << num_mail << " does not exist  \n";}
		   if (ParaGlob::NiveauImpression() >5)
         { cout << " \n LesReferences::Trouve(const string & st1,int num_mail) " << endl;};
       Sortie (1);
   }
  else if (t_mapDeRef(num_mail).find(st1) == t_mapDeRef(num_mail).end())
	  { if (ParaGlob::Francais()) 
	      {cout << " \n pb la reference de nom " << st1 << " pour le maillage nb= "<< num_mail << " n'existe pas \n";}
		   else {cout << "\nError : the reference with the name " << st1 << " for the mesh nb= " << num_mail << " does not exist  \n";}
		   if (ParaGlob::NiveauImpression() >5)
         { cout << " \n LesReferences::Trouve(const string & st1,int num_mail) " << endl;};
       Sortie (1);
   };
  // sinon c'est ok
  return *(t_mapDeRef(num_mail)[st1]);
};
  
// idem mais avec un nom de maillage          
const Reference& LesReferences::Trouve(const string & st1,const string* nom_mail) const 
   { // on regarde si le nom de maillage est licite 
     if (nom_mail == NULL)
      { // acceptable que si l'on a un seul maillage
        #ifdef MISE_AU_POINT
		      if (listeNomMail->size() != 1)
		        if (ParaGlob::NiveauImpression() >2)
            { if (ParaGlob::Francais())
                 {cout << "\n warning: la reference demandee= " << st1 << " , n'a pas de nom de maillage associe"
                       << " alors qu'il y a plusieurs maillage defini !! : on considere que c'est une ref du premier maillage";}
              else {cout << "\n warning: the wanted reference  " << st1 << " , has no associated mesh "
                         << " but several meshes exist !! : we consider that it is a ref for the first mesh ";}
              if (ParaGlob::NiveauImpression() >5)
               { if (ParaGlob::Francais()) {cout << "\n nom_de_maillages= ";}
					            else {cout << "\n names of the meshes = ";}
					            map < string,  int , std::less <string> >::const_iterator ili,ilifin=listeNomMail->end();
                 for (ili = listeNomMail->begin();ili != ilifin; ili++)
                    cout << (*ili).first << ", " ;    
                 cout  << "\n  LesReferences::Trouve(const string & st1,const string& nom_mail) ";
					          };
//              Sortie(1);
            };
        #endif
        // on ramène le cas du premier maillage qui doit exister
        return Trouve(st1,1);     
        }
      else 
       {           
        #ifdef MISE_AU_POINT
        // on regarde si le nom de maillage existe dans la liste
        if (listeNomMail->find(*nom_mail) == listeNomMail->end())
         { if (ParaGlob::Francais()) {cout << "\nErreur : le nom de maillage :  " << *nom_mail << " n'existe pas \n";}
			        else {cout << "\nError : the name of the mesh  :  " << *nom_mail << " does not exist  \n";}
		         if (ParaGlob::NiveauImpression() >5)
			          cout << "LesReferences::Trouve(const string & st1,const string& nom_mail) \n";
		         Sortie(1);
         };
        #endif
        return Trouve(st1,(*(listeNomMail->find(*nom_mail))).second);
       };
    };
            
// mise à jour des références de noeud, dans le cas où les numéros de noeuds ont changés
//1) cas où l'on supprime éventuellement des noeuds de la référence,	qui ne sont plus référencé  
// nv_tab est tel que : nv_tab(i) est le nouveau numéro qui avait auparavant le numéro "i"
// non_referencer(i) : = true signifie qu'il ne faut plus tenir compte de ce noeud
//                     = false indique qu'il continue d'être actif
void LesReferences::Mise_a_jour_ref_noeud(Tableau <int >& nv_tab,int num_mail,Tableau <bool>& non_referencer)
{ bool fr = ParaGlob::Francais(); // pour simplifier
  // on vérifie le numéro de maillage
  if ((num_mail < 0) || (num_mail > t_mapDeRef.Taille()))
  	{ if (fr) {cout << "\n **** bizarre on demande de changer la numerotation de noeuds de reference pour le"
  	                << " maillage numero: " << num_mail << " qui soit n'existe pas ou soit n'a pas de reference !! ";}
	    else    {cout << "\n **** strange, we try to change the numerotation of nodes belonging to a reference  of a  "
  	                << " mesh number : " << num_mail << " which does not exist or does not contain any reference !! ";};
  	};
  // on balaie la map
  map < string, Reference*, std::less <string> >& mapDeRef = t_mapDeRef(num_mail); 
  map < string, Reference*, std::less <string> >::iterator il,ilfin = mapDeRef.end();
//  list <Reference*>::const_iterator il,ilfin=listeDeRef.end();
  int nb_noeud = nv_tab.Taille();
  for (il=mapDeRef.begin() ; il != ilfin; il++)
   { if ((*il).second->Indic() == 1)
       { // cas où il s'agit d'une référence de noeud
         ReferenceNE* refe = ((ReferenceNE*) (*il).second); // on récupère la référence
         int nb_el = refe->Taille();
				     // premier passage on change les numéros
				     int nb_noeud_supprime = 0; // nombre de noeuds supprimés  
         for (int i=1; i<= nb_el; i++)
           { int num_ancien = refe->Numero(i);
					        // on vérifie que le noeud continue d'être valide
					        if (non_referencer(num_ancien))
					         { if (ParaGlob::NiveauImpression() > 3)
						           {if (fr) {cout << "\n suppression du noeud " << num_ancien << " dans la reference " 
									                       << refe->Nom() << " maillage:" << num_mail ;}
                  else    {cout << "\n erasure of the node " << num_ancien << " in the reference " 
									                       << refe->Nom() << " mesh :" << num_mail ;};
						           };
						          // on commence par mettre -100 dans le tableau de num et ensuite on retassera le tableau à la fin 
						          refe->Change_num_dans_ref(i,-100);
						          nb_noeud_supprime++;			
						        }
					        else // sinon il faut le garder
						        { // on vérifie que le numéro de la référence est licite (normalement il doit l'être)
                if ((num_ancien > 0) && (num_ancien <= nb_noeud))
      	    		     {refe->Change_num_dans_ref(i,nv_tab(num_ancien));}
      	    	    else
      	    		     {if (fr) {cout << "\n erreur dans la mise a jour d'une reference , le numero " 
      	    		                    << num_ancien << " de la liste "
									                        << " n'appartient pas a l'intervalle des noeuds disponibles [1," << nb_noeud << "] ";}
      	    		      else    {cout << "\n error during the update of a reference, the number  " 
      	    		                    << num_ancien << " in the list "
									                        << " does not belong to the range of existing nodes [1," << nb_noeud << "] ";};
// debug							 cout << " \n non_referencer(num_ancien) " << non_referencer(num_ancien) << endl;		
      	    		      refe->Affiche();
      	    		      Sortie(1);
      	    		     };
						        };
           };
				     // second passage dans le cas où l'on a supprimé des noeuds
				     if (nb_noeud_supprime)	
           {// a) on fait un décalage dans le tableau initial 
					       int indice_new = 1;
            for (int i=1; i<= nb_el; i++)
             { if (refe->Numero(i) != -100)
					           {refe->Change_num_dans_ref(indice_new,refe->Numero(i));
                 indice_new++;
                }
             };
					       // b) on retasse le tableau 
					       Tableau<int> tab_inter = refe->Tab_num();
					       tab_inter.Change_taille(nb_el-nb_noeud_supprime);
					       refe->Change_tab_num(tab_inter); 
					      };
         // on supprime les doublons éventuels
         refe->Supprime_doublons_internes();
       };
   };
};

// mise à jour des références de noeud, dans le cas où les numéros de noeuds ont changés
//2) cas où on considère tous les noeuds 
// nv_tab est tel que : nv_tab(i) est le nouveau numéro qui avait auparavant le numéro "i"
void LesReferences::Mise_a_jour_ref_noeud(Tableau <int >& nv_tab,int num_mail)
{ bool fr = ParaGlob::Francais(); // pour simplifier
  // on vérifie le numéro de maillage
  if ((num_mail < 0) || (num_mail > t_mapDeRef.Taille()))
  	{ if (fr) {cout << "\n **** bizarre on demande de changer la numerotation de noeuds de reference pour le"
  	                << " maillage numero: " << num_mail << " qui soit n'existe pas ou soit n'a pas de reference !! ";}
	  else    {cout << "\n **** strange, we try to change the numerotation of nodes belonging to a reference  of a  "
  	                << " mesh number : " << num_mail << " which does not exist or does not contain any reference !! ";};
  	};
  // on balaie la map
  map < string, Reference*, std::less <string> >& mapDeRef = t_mapDeRef(num_mail); 
  map < string, Reference*, std::less <string> >::iterator il,ilfin = mapDeRef.end();
//  list <Reference*>::const_iterator il,ilfin=listeDeRef.end();
  int nb_noeud = nv_tab.Taille();
  for (il=mapDeRef.begin() ; il != ilfin; il++)
   { if ((*il).second->Indic() == 1)
   	  { // cas où il s'agit d'une référence de noeud
   	    ReferenceNE* refe = ((ReferenceNE*) (*il).second); // on récupère la référence
   	    int nb_el = refe->Taille();
   	    for (int i=1; i<= nb_el; i++)
   	      { int num_ancien = refe->Numero(i);
			         // on vérifie que le numéro de la référence est licite (normalement il doit l'être)
			         if ((num_ancien > 0) && (num_ancien <= nb_noeud))
   	    		   {refe->Change_num_dans_ref(i,nv_tab(num_ancien));}
            else
   	    		   {if (fr) {cout << "\n erreur dans la mise a jour d'une reference , le numero " 
   	    		                  << num_ancien << " de la liste "
						         << " n'appartient pas a l'intervalle des noeuds disponibles [1," << nb_noeud << "] ";}
   	    		    else    {cout << "\n error during the update of a reference, the number  " 
   	    		                  << num_ancien << " in the list "
						         << " does not belong to the range of existing nodes [1," << nb_noeud << "] ";};
   	    		    refe->Affiche();
   	    		    Sortie(1);     
             };
   	    	 };
        // on supprime les doublons éventuels
        refe->Supprime_doublons_internes();
   	  };
   };
};
    
            

    // mise à jour des références d'élément, dans le cas où les numéros d'élément ont changés
//1) cas où l'on supprime éventuellement des éléments de la référence,	qui ne sont plus référencé  
// nv_tab est tel que : nv_tab(i) est le nouveau numéro qui avait auparavant le numéro "i"
// non_referencer(i) : = true signifie qu'il ne faut plus tenir compte de cet élément
//                     = false indique qu'il continue d'être actif
void LesReferences::Mise_a_jour_ref_element(Tableau <int >& nv_tab,int num_mail,Tableau <bool>& non_referencer)
{ bool fr = ParaGlob::Francais(); // pour simplifier
  // on vérifie le numéro de maillage
  if ((num_mail < 0) || (num_mail > t_mapDeRef.Taille()))
  	{ if (fr) {cout << "\n **** bizarre on demande de changer la numerotation d'element de reference pour le"
  	                << " maillage numero: " << num_mail << " qui soit n'existe pas ou soit n'a pas de reference !! ";}
	  else    {cout << "\n **** strange, we try to change the numerotation of elements belonging to a reference  of a  "
  	                << " mesh number : " << num_mail << " which does not exist or does not contain any reference !! ";};
  	};
  // on balaie la map
  map < string, Reference*, std::less <string> >& mapDeRef = t_mapDeRef(num_mail); 
  map < string, Reference*, std::less <string> >::iterator il,ilfin = mapDeRef.end();


//      	{  int i = num_mail;
//          map < string, Reference*, std::less <string> >& mapDeRef = t_mapDeRef(i);
//          map < string, Reference*, std::less <string> >::const_iterator i_map;
//          if (ParaGlob::Francais()) {cout << " \n ------- affichage des listes de references ------- \n ";}
//          else {cout << " \n ------- display of the lists of references ------- \n ";}; 
//            for (i_map=mapDeRef.begin() ; i_map != mapDeRef.end(); i_map++)
//               (*i_map).second->Affiche();
//          cout << endl;
//      	};



//  list <Reference*>::const_iterator il,ilfin=listeDeRef.end();
  int nb_element = nv_tab.Taille();
  for (il=mapDeRef.begin() ; il != mapDeRef.end(); il++)
    { switch((*il).second->Indic())
      {case 2:   // cas où il s'agit d'une référence d'élément
        { ReferenceNE* refe = ((ReferenceNE*) (*il).second); // on récupère la référence
    	    int nb_el = refe->Taille();
         // premier passage on change les numéros
         int nb_element_supprime = 0; // nombre de elements supprimés
    	    for (int i=1; i<= nb_el; i++)
    	      { int num_ancien = refe->Numero(i);
				         // on vérifie que l'élement continue d'être valide
				         if (non_referencer(num_ancien))
				          { if (ParaGlob::NiveauImpression() > 3)
					            {if (fr) {cout << "\n suppression de l'element " << num_ancien << " dans la reference " 
								                        << refe->Nom() << " maillage:" << num_mail << endl;}
					             else    {cout << "\n erasure of the element " << num_ancien << " in the reference "
								                        << refe->Nom() << " mesh :" << num_mail << endl;};
					            };
					           // on commence par mettre -100 dans le tableau de num et ensuite on retassera le tableau à la fin 
					           refe->Change_num_dans_ref(i,-100);
					           nb_element_supprime++;
              }
				         else // sinon il faut le garder
              { // on vérifie que le numéro de la référence est licite (normalement il doit l'être)
                if ((num_ancien > 0) && (num_ancien <= nb_element))
      	    		     {refe->Change_num_dans_ref(i,nv_tab(num_ancien));}
      	    	    else
      	    		     {if (fr) {cout << "\n erreur dans la mise a jour d'une reference , le numero " 
      	    		                    << num_ancien << " de la liste "
									                        << " n'appartient pas a l'intervalle des elements disponibles [1," << nb_element << "] ";}
      	    		      else    {cout << "\n error during the update of a reference, the number  " 
      	    		                    << num_ancien << " in the list "
									                        << " does not belong to the range of existing elements [1," << nb_element << "] ";};
// debug							 cout << " \n non_referencer(num_ancien) " << non_referencer(num_ancien) << endl;		
      	    		      refe->Affiche();
                   Sortie(1);
                  };
              };
           };
         // second passage dans le cas où l'on a supprimé des elements
         if (nb_element_supprime)
      	   { // a) on fait un décalage dans le tableau initial 
				        int indice_new = 1;
				        for (int i=1; i<= nb_el; i++)
      	      { if (refe->Numero(i) != -100)
					            {refe->Change_num_dans_ref(indice_new,refe->Numero(i));
						            indice_new++;
                 };
             };
				        // b) on retasse le tableau 
				        Tableau<int> tab_inter = refe->Tab_num();
				        tab_inter.Change_taille(nb_el-nb_element_supprime);
				        refe->Change_tab_num(tab_inter);
          };
         // on supprime les doublons éventuels
         refe->Supprime_doublons_internes();
         break;
        }
       case 3: case 4: case 6:   // cas où il s'agit d'une face ou arête ou ptint d'élément
        {ReferenceAF* refe = ((ReferenceAF*) (*il).second); // on récupère la référence
         // on récupère les deux tableaux de la référence
		       const Tableau<int>& tab_elem = refe->Tab_Elem(); // le tableau des numeros d'éléments
		       //puis le tableau des numeros de faces, ou d'arêtes, ou de noeud d'element, ou de points d'integ
         const Tableau<int>& tab_entite = refe->Tab_FA();
         // on va travailler avec ces tableaux et ensuite on recréra une nouvelle référence avec de nouveaux tableaux
         int nb_el = tab_elem.Taille();
         // premier passage on change les numéros
         int nb_element_supprime = 0; // nombre de elements supprimés
      	  for (int i=1; i<= nb_el; i++)
      	   { int num_ancien = refe->NumeroElem(i);
				        // on vérifie que le element continue d'être valide
				        if (non_referencer(num_ancien))
				         { if (ParaGlob::NiveauImpression() > 3)
					           {if (fr) {cout << "\n suppression de l'element " << num_ancien << " dans la reference " 
								                       << refe->Nom() << " maillage:" << num_mail ;}
                 else    {cout << "\n erasure of the element " << num_ancien << " in the reference "
								                       << refe->Nom() << " mesh :" << num_mail ;};
					           };
					          // on commence par mettre -100 dans le tableau de num et ensuite on retassera le tableau à la fin 
					          tab_elem(i) = -100;
					          nb_element_supprime++;
             }
            else // sinon il faut le garder
             { // on vérifie que le numéro de la référence est licite (normalement il doit l'être)
               if ((num_ancien > 0) && (num_ancien <= nb_element))
                 {tab_elem(i) = nv_tab(num_ancien);}
 //     	    	{refe->Change_num_dans_ref(i,nv_tab(num_ancien));}
               else
      	    		    {if (fr) {cout << "\n erreur dans la mise a jour d'une reference , le numero " 
      	    		                   << num_ancien << " de la liste "
									                       << " n'appartient pas a l'intervalle des elements disponibles [1," << nb_element << "] ";}
      	    		     else    {cout << "\n error during the update of a reference, the number  "
      	    		                   << num_ancien << " in the list "
                                << " does not belong to the range of existing elements [1," << nb_element << "] ";};
// debug							 cout << " \n non_referencer(num_ancien) " << non_referencer(num_ancien) << endl;		
      	    		     refe->Affiche();
                  Sortie(1);
                 };
             };
          };
         // on crée deux nouveaux tableaux
		       Tableau<int> tab_elem_new(nb_el-nb_element_supprime); // le nouveau tableau des numeros d'éléments
		       //puis le tableau des numeros de faces, ou d'arêtes, ou de noeud d'element, ou de points d'integ
		       Tableau<int> tab_entite_new(nb_el-nb_element_supprime);
         // on va travailler avec ces tableaux et ensuite on mettra à jour la référence
         // second passage dans le cas où l'on a supprimé des elements
         if (nb_element_supprime)
      	   {// on recopie les grandeurs correctes
				       int indice_new = 1;
				       for (int i=1; i<= nb_el; i++)
      	      { if (tab_elem(i) != -100)
                {tab_elem_new(indice_new)=tab_elem(i);
                 tab_entite_new(indice_new) = tab_entite(i);
                 indice_new++;
                };
             };
           // on change les deux tableaux dans la référence
           refe->Change_tab_num(tab_elem_new,tab_entite_new);
           // on supprime les doublons éventuels
           refe->Supprime_doublons_internes();
          }
         else // sinon on ne fait que supprimer les doublons éventuels
          {refe->Supprime_doublons_internes();};
         break;
        }

       case 7: case 8:    // cas où il s'agit de pti d'une face ou arête  d'élément
        {ReferencePtiAF* refe = ((ReferencePtiAF*) (*il).second); // on récupère la référence
         // on récupère les trois tableaux de la référence
         const Tableau<int>& tab_elem = refe->Tab_Elem(); // le tableau des numeros d'éléments
         //puis le tableau des numeros de faces, ou d'arêtes
         const Tableau<int>& tab_entite = refe->Tab_FA();
         // puis le tableau des pti
         const Tableau<int>& tab_entite_pti = refe->Tab_Pti();

         // on va travailler avec ces tableaux et ensuite on recréra une nouvelle référence avec de nouveaux tableaux
         int nb_el = tab_elem.Taille();
         // premier passage on change les numéros
         int nb_element_supprime = 0; // nombre de elements supprimés
         for (int i=1; i<= nb_el; i++)
          { int num_ancien = refe->NumeroElem(i);
            // on vérifie que le element continue d'être valide
            if (non_referencer(num_ancien))
             { if (ParaGlob::NiveauImpression() > 3)
                {if (fr) {cout << "\n suppression de l'element " << num_ancien << " dans la reference "
                               << refe->Nom() << " maillage:" << num_mail ;}
                 else    {cout << "\n erasure of the element " << num_ancien << " in the reference "
                               << refe->Nom() << " mesh :" << num_mail ;};
                };
               // on commence par mettre -100 dans le tableau de num et ensuite on retassera le tableau à la fin
               tab_elem(i) = -100;
               nb_element_supprime++;
             }
            else // sinon il faut le garder
             { // on vérifie que le numéro de la référence est licite (normalement il doit l'être)
               if ((num_ancien > 0) && (num_ancien <= nb_element))
                 {tab_elem(i) = nv_tab(num_ancien);}
                       else
                         {if (fr) {cout << "\n erreur dans la mise a jour d'une reference , le numero "
                                        << num_ancien << " de la liste "
                                        << " n'appartient pas a l'intervalle des elements disponibles [1," << nb_element << "] ";}
                          else    {cout << "\n error during the update of a reference, the number  "
                                        << num_ancien << " in the list "
                                        << " does not belong to the range of existing elements [1," << nb_element << "] ";};
        // debug        cout << " \n non_referencer(num_ancien) " << non_referencer(num_ancien) << endl;
                          refe->Affiche();
                          Sortie(1);
                         };
                     };
                  };
                 // on crée 3 nouveaux tableaux
                 Tableau<int> tab_elem_new(nb_el-nb_element_supprime); // le nouveau tableau des numeros d'éléments
                 //puis le tableau des numeros de faces, ou d'arêtes,
                 Tableau<int> tab_entite_new(nb_el-nb_element_supprime);
                 //puis le tableau de points d'integ
                 Tableau<int> tab_entite_pti_new(nb_el-nb_element_supprime);
                 // on va travailler avec ces tableaux et ensuite on mettra à jour la référence
                 // second passage dans le cas où l'on a supprimé des elements
                 if (nb_element_supprime)
                  {// on recopie les grandeurs correctes
                   int indice_new = 1;
                   for (int i=1; i<= nb_el; i++)
                     { if (tab_elem(i) != -100)
                        {tab_elem_new(indice_new)=tab_elem(i);
                         tab_entite_new(indice_new) = tab_entite(i);
                         tab_entite_pti_new(indice_new) = tab_entite_pti(i);
                         indice_new++;
                        };
                     };
                   // on change les deux tableaux dans la référence
                   refe->Change_tab_num(tab_elem_new,tab_entite_new,tab_entite_pti_new);
                   // on supprime les doublons éventuels
                   refe->Supprime_doublons_internes();
                  }
                 else // sinon on ne fait que supprimer les doublons éventuels
                  {refe->Supprime_doublons_internes();};
                 break;
                }


      };
    };
};


// suppression d'une référence
void LesReferences::SupprimeReference(const string & st1,int num_mail)
  { bool fr = ParaGlob::Francais(); // pour simplifier
    // tout d'abord on cherche la référence
    if (num_mail > t_mapDeRef.Taille())  
     { if (fr) {cout << " \n pb1 la reference de nom " << st1 << " pour le maillage nb= "<< num_mail
                     << " n\'existe pas !! , on ne peut pas la supprimer " << endl;}
       else    {cout << " \n pb1 the reference with name " << st1 << " for the mesh number= "<< num_mail
                     << " does not exist !! , we cannot erase it  " << endl;};
       if (ParaGlob::NiveauImpression() >= 5) 
           cout << "\n LesReferences::SupprimeReference(...";
       Sortie (1);
     };
    map < string, Reference*, std::less <string> >::iterator il = t_mapDeRef(num_mail).find(st1);
    if (il == t_mapDeRef(num_mail).end())  
     { if (fr) {cout << " \n pb2 la reference de nom " << st1 << " pour le maillage nb= "<< num_mail
                     << " n\'existe pas !! , on ne peut pas la supprimer " << endl;}
       else    {cout << " \n pb2 the reference with name " << st1 << " for the mesh number= "<< num_mail
                     << " does not exist !! , we cannot erase it  " << endl;};
       if (ParaGlob::NiveauImpression() >= 5) 
           cout << "\n LesReferences::SupprimeReference(...";
       Sortie (1);
     }
    else // sinon c'est ok
     { // on commence par effacer la référence
       if ((*il).second != NULL) {delete (*il).second;(*il).second=NULL;};
       // puis on le suprime du tableau de map
       t_mapDeRef(num_mail).erase(il);
     };
  };

    // suppression de tous les référence d'un maillage donné
    // si avec_diminution_num_maillage = true: 
    // tous les numéros de maillage, > num_mail,  associé aux maillages qui restent
    // sont diminués de un, pour tenir compte de la disparition du maillage et donc
    // d'une nouvelle numérotation des maillages
    // si avec_diminution_num_maillage = false, le conteneur des ref de maillage num_mail
    // est vidé, mais il continu à exister: on considère qu'il y a toujours un maillage num_mail potentiel
void LesReferences::Supprime_tour_lesRef_un_maillage(int num_mail, bool avec_diminution_num_maillage)
{// bien que nbMaille ne serve pas a priori sans être initialisé
 // , pour éviter qu'il soit inchoérent, on le modifie éventuellement
 if (nbMaille > num_mail)
   {nbMaille = 1; // par défaut
    indic = 1; // toujours par défaut
   };
 // on met à jour la t_mapDeRef
 map < string, Reference*, std::less <string> >::iterator il,ilfin;
 map < string, Reference*, std::less <string> >& mapDeRef = t_mapDeRef(num_mail);
 // vérif
 int tai=t_mapDeRef.Taille();
 if (num_mail <1)
  { cout << "\n erreur, impossible de supprimer les ref du maillage "<<num_mail;
    cout << "\n LesReferences::Supprime_tour_lesRef_un_maillage(.." << endl;
    Sortie(1);
   };

 if (num_mail > tai) // pas de référence enregistrées pour ce maillage
   // on ne fait rien et on revient
    return;
 // on supprime les ref
 ilfin = mapDeRef.end();
 for (il = mapDeRef.begin();il != ilfin; il++)
   delete (*il).second;
 // suppression ou non du conteneur
 if (avec_diminution_num_maillage)
   { // on retasse le tableau
     for (int i=num_mail;i<=tai-1;i++)
       {t_mapDeRef(i)=t_mapDeRef(i+1);
        // on change les numéros de maillages
        map < string, Reference*, std::less <string> >& mapDeRef = t_mapDeRef(i );
        ilfin = mapDeRef.end();
        for (il = mapDeRef.begin();il != ilfin; il++)
          (*il).second->Change_Nbmaille(i);
       };
    // le fait de changer de taille supprime l'élément tai
    t_mapDeRef.Change_taille(tai-1);
    nbMaille--; // on diminue le nombre de maillage en service pour les ref
  };
};

       
//----- lecture écriture de base info -----
//   lecture base info
// = 1 : on récupère tout
// = 2 : on récupère uniquement les données variables (supposées comme telles)
void LesReferences::Lecture_base_info(ifstream& entr,const int cas)
 {bool fr = ParaGlob::Francais(); // pour simplifier
  // pour l'instant nous n'avons que des références fixes
  if (cas == 1)
   {if (fr) {cout << " == lecture des references \n";}
    else    {cout << " == reading of the references \n";};
    // on commence par effacer les références existantes
    int taille = t_mapDeRef.Taille();
    for (int i=1;i<=taille;i++)
      	{ map < string, Reference*, std::less <string> >& mapDeRef = t_mapDeRef(i);
      	  map < string, Reference*, std::less <string> >::iterator il,ilfin = mapDeRef.end();
          for (il=mapDeRef.begin() ; il != ilfin; il++)
             if ((*il).second != NULL) {delete (*il).second;(*il).second=NULL;};
          mapDeRef.erase(mapDeRef.begin(),mapDeRef.end());
         };
    // on lit et dimensionne le tableau
    string toto;int t_taille; 
    entr >> toto >> t_taille ; 
    t_mapDeRef.Change_taille(t_taille);
    for (int i=1;i<=t_taille;i++)
      	{ map < string, Reference*, std::less <string> >& mapDeRef = t_mapDeRef(i);
      	  int nb_ref=0;
      	  entr >> toto >> nb_ref;
          // on boucle sur le nombre de référence à lire
          int indic;
          for (int i=1;i<= nb_ref; i++)
            { // lecture du type de référence
              entr >> toto >> indic;
              // création d'une référence ad hoc
      	      int nbMaille = -10;
        	  switch (indic)
        	  {// le numéro de maillage est mis en négatif pour indiquer qu'il est faux
        	   // il est ensuite lue à la bonne valeur par la référence
        		 case 1 : ref = new ReferenceNE(nbMaille,indic); break;
        		 case 2 : ref = new ReferenceNE(nbMaille,indic); break;
        		 case 3 : ref = new ReferenceAF(nbMaille,indic); break;
        		 case 4 : ref = new ReferenceAF(nbMaille,indic); break;
        		 case 5 : ref = new ReferenceAF(nbMaille,indic); break;
        		 case 6 : ref = new ReferenceAF(nbMaille,indic); break;
           case 7 : ref = new ReferencePtiAF(nbMaille,indic); break;
           case 8 : ref = new ReferencePtiAF(nbMaille,indic); break;
        		 default :
        			if (fr) {cout << "\nErreur : valeur incorrecte du type de reference indic =  " << indic << "\n";}
					else    {cout << "\nError : incorrect value of the type of reference indic =  " << indic << "\n";};
					cout << "LesReferences::Lecture_base_info(..." ;
        			Sortie(1);
        	   };
      	     // lecture de la référence en question
      	     ref->Lecture_base_info(entr,cas);
      	     // intégration dans la map
      	     mapDeRef[ref->Nom()]=ref;
            };
      	};
   };
 };
            	

        
//   écriture base info   
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
void LesReferences::Ecriture_base_info(ofstream& sort,const int cas)
 {bool fr = ParaGlob::Francais(); // pour simplifier
  // pour l'instant nous n'avons que des références fixes
  if (cas == 1)
   {int t_taille = t_mapDeRef.Taille();
    if (fr) {sort << "\n ****taille_tableau_references= " << t_taille << " ";}
    else    {sort << "\n ****size_tab_references= " << t_taille << " ";};
    for (int i=1;i<=t_taille;i++)
      	{ map < string, Reference*, std::less <string> >& mapDeRef = t_mapDeRef(i);
      	  map < string, Reference*, std::less <string> >::iterator il,ilfin=mapDeRef.end();
           if (fr) {sort << "\n ****les_references_du_maillage"<<i<<"_nombre= " << mapDeRef.size() <<"\n";}
           else    {sort << "\n ****the_references_of_mesh"<<i<<"_number= " << mapDeRef.size() <<"\n";}
           for (il=mapDeRef.begin() ; il != ilfin; il++)
            { // on écrit le type de référence
              Reference& refi=*((*il).second); 
              if (fr) {sort << "\n type_de_reference= " << refi.Indic() << " ";}
              else    {sort << "\n type_of_reference= " << refi.Indic() << " ";};
              // puis écriture de la référence
              refi.Ecriture_base_info(sort,cas);
            };
      	};
   };
 };
 

 
//------------------------------------ protegees ----------------------

/* */

// lecture d'une liste de reference
// création d'une référence pointée par ref
bool LesReferences::LectureReference(UtilLecture & entreePrinc)
 { bool fr = ParaGlob::Francais(); // pour simplifier
   // tout d'abord il faut vérifier qu'il y a effectivement une référence à lire
   // c'est à dire que l'on ne se trouve pas au niveau d'un mot cle sinon arret 
   if  (motCle.SimotCle(entreePrinc.tablcar))
     return false;
   // maintenant cas d'une référence à lire  
   // deux cas : soit indic a déjà une valeur qui indique le type de référence à lire auquel cas 
   // on cré une référence du type a doc
   // sinon on regarde l'identificateur de la référence et suivant la première lettre on choisit
   // le type de référence à créer
   int oldIndic = indic; // pour se rappeler l'ancienne valeur
   if (indic == 0)
       // cas où le type est a définir : on regarde le premier caratère
        { char premCar = entreePrinc.tablcar[0];
           if (premCar == 'N')
             indic = 1;
           else if  (premCar == 'E')  
             indic = 2;
           else if  (premCar == 'F')  
             indic = 3;
           else if  (premCar == 'A')  
             indic = 4;
           else if  (premCar == 'P')  
             indic = 5;
           else if  (premCar == 'G')  
             indic = 6;
           else if  (premCar == 'P')
             indic = 7;
           else if  (premCar == 'L')
             indic = 8;
           else
             { // erreur, ce n'est pas un type de référence connu
                if (fr)
					              {cout << "\n erreur dans la definition du type de reference, le premier caractere de l'identificateur  doit etre "
                         <<  " une des lettres suivantes : N ou E ou F ou A , alors que la valeur lue est : " << premCar << "\n";}
                else {cout << "\n error in the definition of a reference type, the first character must be "
                         <<  " one of the following character : N or E or F or A , but the read character is : " << premCar << "\n";}
                entreePrinc.MessageBuffer("LectureReference") ;
                Affiche();
                throw (UtilLecture::ErrNouvelleDonnee(-1));
                Sortie(1);        
             };
        };
      // maintenant on définit la référence adoc
	  switch (indic)
	   {
		   case 1 : ref = new ReferenceNE(nbMaille,indic); break;
		   case 2 : ref = new ReferenceNE(nbMaille,indic); break;
		   case 3 : ref = new ReferenceAF(nbMaille,indic); break;
		   case 4 : ref = new ReferenceAF(nbMaille,indic); break;
		   case 5 : ref = new ReferenceAF(nbMaille,indic); break;
		   case 6 : ref = new ReferenceAF(nbMaille,indic); break;
     case 7 : ref = new ReferencePtiAF(nbMaille,indic); break;
     case 8 : ref = new ReferencePtiAF(nbMaille,indic); break;
		   default :
		   	if (fr) {cout << "\nErreur : valeur incorrecte du type de référence indic =  " << indic << "\n";}
		   	else    {cout << "\nError : incorrect value of the type of reference indic =  " << indic << "\n";};
		   	entreePrinc.MessageBuffer("LectureReference") ;
		   	Affiche();
		   	throw (UtilLecture::ErrNouvelleDonnee(-1));
		   	Sortie(1);
    };
	  // remise à la valeur précédente d'indic
	  indic = oldIndic;  
         
    // lecture des données propres à la référence et retour
    bool retour= (ref->LectureReference(entreePrinc));
    // on supprime les doublons éventuels
    ref->Supprime_doublons_internes();
    return retour;
 };


// retourne la reference correspondant a une cle
Reference& LesReferences::Trouve_interne(const string & st1,int num_mail) const
{ if (num_mail > t_mapDeRef.Taille())  
	  { if (ParaGlob::Francais()) 
	      {cout << " \n pb la reference de nom " << st1 << " pour le maillage nb= "<< num_mail << " n'existe pas \n";}
		      else {cout << "\nError : the reference with the name " << st1 << " for the mesh nb= " << num_mail << " does not exist  \n";}
		   if (ParaGlob::NiveauImpression() >5)
         { cout << " \n LesReferences::Trouve(const string & st1,int num_mail) " << endl;};
     Sortie (1);
   }
  else if (t_mapDeRef(num_mail).find(st1) == t_mapDeRef(num_mail).end())  
	  { if (ParaGlob::Francais()) 
	      {cout << " \n pb la reference de nom " << st1 << " pour le maillage nb= "<< num_mail << " n'existe pas \n";}
		   else {cout << "\nError : the reference with the name " << st1 << " for the mesh nb= " << num_mail << " does not exist  \n";}
		   if (ParaGlob::NiveauImpression() >5)
         { cout << " \n LesReferences::Trouve(const string & st1,int num_mail) " << endl;};
     Sortie (1);
   };
  // sinon c'est ok
  return *(t_mapDeRef(num_mail)[st1]);
};
  
// idem mais avec un nom de maillage          
Reference& LesReferences::Trouve_interne(const string & st1,const string* nom_mail) const
{ // on regarde si le nom de maillage est licite 
  if (nom_mail == NULL)
    {   // acceptable que si l'on a un seul maillage
      #ifdef MISE_AU_POINT
		      if (listeNomMail->size() != 1)
		       if (ParaGlob::NiveauImpression() >2)
            { if (ParaGlob::Francais())
				               {cout << "\n warning: la reference demandee= " << st1 << " , n'a pas de nom de maillage associe"
                         << " alors qu'il y a plusieurs maillage defini !! : on considere que c'est une ref du premier maillage";}
				          else {cout << "\n warning: the wanted reference  " << st1 << " , has no associated mesh "
                         << " but several meshes exist !! : we consider that it is a ref for the first mesh ";}
				          if (ParaGlob::NiveauImpression() >5)		 
                   { if (ParaGlob::Francais()) {cout << "\n nom_de_maillages= ";}
					                else {cout << "\n names of the meshes = ";}
                     map < string,  int , std::less <string> >::const_iterator ili,ilifin=listeNomMail->end();
                     for (ili = listeNomMail->begin();ili != ilifin; ili++)
                        cout << (*ili).first << ", " ;    
                     cout  << "\n  LesReferences::Trouve_interne(const string & st1,const string& nom_mail) ";
                   };
//            Sortie(1);
            };
      #endif
        // on ramène le cas du premier maillage qui doit exister
        return Trouve_interne(st1,1);
    }
  else 
    {           
      #ifdef MISE_AU_POINT
        // on regarde si le nom de maillage existe dans la liste
        if (listeNomMail->find(*nom_mail) == listeNomMail->end())
         { if (ParaGlob::Francais()) {cout << "\nErreur : le nom de maillage :  " << *nom_mail << " n'existe pas \n";}
			        else {cout << "\nError : the name of the mesh  :  " << *nom_mail << " does not exist  \n";}
		         if (ParaGlob::NiveauImpression() >5)
			          cout << "LesReferences::Trouve_interne(const string & st1,const string& nom_mail) \n";
		         Sortie(1);
		       }
      #endif
        return Trouve_interne(st1,(*(listeNomMail->find(*nom_mail))).second);
    };
};

