
// This file is part of the Herezh++ application.
//
// The finite element software Herezh++ is dedicated to the field
// of mechanics for large transformations of solid structures.
// It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600)
// INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) <https://www.irdl.fr/>.
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL  : gerardrio56@free.fr
//
// 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 3 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, see <https://www.gnu.org/licenses/>.
//
// For more information, please consult: <https://herezh.irdl.fr/>.

#include "LectBlocMot.h"


BlocDdlLim< BlocGen>  LectBlocmot::Lecture
               (UtilLecture & entreePrinc,LesReferences& lesRef,string message,
                            Tableau<string>& tabMot,Tableau<string>& TsousMot)
  { MotCle motCle(TsousMot); // ref aux mots cle
    // tout d'abord lecture de la reference
    list <string> lili;
    string elem,nom; string* nom_mail=NULL;string nom_du_maillage("");
 //   try
     { // on regarde tout d'abord si il y a un nom de maillage, qui doit être le premier nom      
      *(entreePrinc.entree) >> nom;
      if (nom == "nom_mail=")
        { // cas où il y a un nom de maillage
          *(entreePrinc.entree) >> nom_du_maillage; // lecture du nom
          nom_mail = &nom_du_maillage;
          // puis on prépare la suite en lisant la référence
          *(entreePrinc.entree) >> nom;
         }
       if ((nom.length() == 0) || (nom[0] == ' '))
         // cas d'une chaine vide d'interet
         { // il n'y a pas de reference
           // on retourne un bloc vide
           BlocDdlLim< BlocGen> blocMot1(nom_mail,BlocGen(0,0));
           return blocMot1;     
         }                     
       // on regarde si cela correspond bien a une reference existante
       if (!lesRef.Existe(nom,nom_mail))
            { cout << "\n erreur, la ref  " << nom ;
              if (nom_mail != NULL) cout << " du maillage " << *nom_mail;
              cout << " ne correspond a aucun element"
                   << " de la liste de reference lue !! \n";
             cout << " LectBlocmot::Lecture( etc ..."
                   << endl;
              entreePrinc.MessageBuffer(message);  
              throw (UtilLecture::ErrNouvelleDonnee(-1));
              Sortie (1);     
            }
       // stockage
       lili.push_back(nom);
       entreePrinc.NouvelleDonnee();
    }
 /*  catch (UtilLecture::ErrNouvelleDonnee erreur)
    { // il n'y a pas de reference
      // on retourne un bloc vide
      BlocGen blocMot2(0,0);
      return blocMot2;     
    } */         
 //   try
     { // cas ou l'on a lue une reference
       // lecture de la liste de mot  permettant un controle de la sortie
       int il = 0; // nombre de string lu
       bool fin = false;
       // les deux cas qui font sortir de la boucle sont l'apparition
       // d'un mot cle (ou sous mot cle) ou une erreur en lecture d'un string
       // apres une bonne lecture sur la meme ligne
       bool aumoinsune = true;
       bool prem = true; // ne sert que pour le cas ou il n'y a pas de mot
       while ( !fin & aumoinsune)
        { aumoinsune = false;
          // lecture sur une ligne
          while (!entreePrinc.entree->rdstate()) // lecture tant qu'il n'y a pas d'erreur
             {*(entreePrinc.entree) >> elem; // lecture d'un string
              if ((entreePrinc.entree->rdstate() == 0) ||
                  (entreePrinc.entree->eof())) 
             // pour mémoire ici on a 
           /*       enum io_state
                    {  badbit   = 1<<0, // -> 1 dans rdstate()
                       eofbit   = 1<<1, // -> 2 
                       failbit  = 1<<2, // -> 4 
                       goodbit  = 0     // -> O 
                     };*/
                 { // verification que le nom est acceptable
                  if(!ExisteString (tabMot,elem))
                    { cout << "\n erreur, le mot lue " << elem 
                           << " ne correspond a aucun element acceptable \n";
                      if (ParaGlob::NiveauImpression() > 0)
                         { cout << "\n liste des mots acceptables: "
                                << tabMot << endl ;
                         };
                      if (ParaGlob::NiveauImpression() > 3)
                        cout << " LectBlocmot::Lecture( etc ..."
                             << endl;
                     entreePrinc.MessageBuffer(message);  
                     throw (UtilLecture::ErrNouvelleDonnee(-1));
                     Sortie (1);     
                    }
                  il++;
                  aumoinsune = true;
                  prem = false;
                  lili.push_back(elem);
                  }
              }
          if ((aumoinsune) || prem )                      
            { entreePrinc.NouvelleDonnee();  // lecture d'une nouvelle ligne
              if (motCle.SimotCle(entreePrinc.tablcar)) 
                // c'est un mot cle
                fin = true;
             }
          else
              // remise correcte du flot pour une prochaine lecture
              entreePrinc.FlotDebutDonnee();
         }
      // enregistrement
      if (il == 0 )
        { // cas d'une liste sans mot specifie
          BlocDdlLim< BlocGen> blocMot3(nom_mail,BlocGen(1,0));
       //   blocMot3.Nom(1) = nom;
          blocMot3.Change_nom(1, nom);
          return blocMot3;
         }
      else
        { list <string>::iterator i; // def d'un iterator adoc
          BlocDdlLim< BlocGen> blocMot4(nom_mail,BlocGen((int)lili.size(),0));          
          int j;
          for (i=lili.begin(),j=1 ; i != lili.end(); i++,j++)
           //   blocMot4.Nom(j) = *i;
             blocMot4.Change_nom(j, *i);
          return blocMot4; 
        }                 
     }
/*   catch (UtilLecture::ErrNouvelleDonnee erreur)
    { entreePrinc.ErreurLecture(erreur,"** lecture d\'une liste de mot **");
      entreePrinc.MessageBuffer(message);  
      throw (UtilLecture::ErrNouvelleDonnee(-1));
      Sortie (1);
    }*/
   // retour de rien pour la compilation
   // mais en fait on ne passe jamais ici
   BlocDdlLim< BlocGen> blocMot5(nom_mail,BlocGen(0,0));
   return blocMot5;
};
  

