// 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 "Frontiere_initiale_geomview.h"

#include <iomanip>
#include "CharUtil.h"

    // CONSTRUCTEURS :
// par defaut
Frontiere_initiale_geomview::Frontiere_initiale_geomview () :
   Frontiere_initiale()
     {}; 
     
     // constructeur de copie 
Frontiere_initiale_geomview::Frontiere_initiale_geomview (const Frontiere_initiale_geomview& ord) :
    Frontiere_initiale(ord)
      {};
               
    // DESTRUCTEUR :
Frontiere_initiale_geomview::~Frontiere_initiale_geomview () 
     {};  
    
    // METHODES PUBLIQUES :
// execution de l'ordre
// tab_mail : donne les numéros de maillage concerné
// incre : numéro d'incrément qui en cours
// type_incre : indique si c'est le premier le dernier ou l'incrément courant a visualiser ou pas
// animation : indique si l'on est en animation ou pas
// unseul_incre : indique si oui ou non il y a un seul increment à visualiser
void Frontiere_initiale_geomview::ExeOrdre(ParaGlob * paraGlob,const Tableau <int>& tab_mail,LesMaillages * lesMail,bool ,LesReferences*
                      ,LesLoisDeComp* ,DiversStockage*,Charge*,LesCondLim*
//                      ,LesContacts*,Resultats*,ostream & sort,EnumTypeIncre type_incre,int incre
                      ,LesContacts*,Resultats*,UtilLecture & entreePrinc,OrdreVisu::EnumTypeIncre ,int incre
//                      ,bool animation)
                      ,bool,const map < string, const double * , std::less <string> >&
                      ,const List_io < TypeQuelconque >& listeVecGlob)
 {ostream &sort = entreePrinc.Sort_princ_geomview();
  // visualisation du maillage pointé si actif
  if ((actif)&&(incre==0))
  {
   // on boucle sur les maillages
   int nbmail = tab_mail.Taille();
   for (int im=1;im<=nbmail;im++)
    { int numMail=tab_mail(im);
      if ((surface)||(filaire)||(numero))
       {// écriture d'une entete
         sort << "\n # ===================================================="
              << "\n # |      dessin des frontieres du maillage initiale  |"
              << "\n # ====================================================";
        // création des frontières d'éléments      
        lesMail->CreeElemFront();  
        }     
      
      
      if (surface) // cas d'une visualisation par face
       { 
         // quelques commentaires pour indiquer les faces            
         sort << "\n # ----------------------------------------------------------------------"
              << "\n # dessin des facettes des elements de la frontiere du maillage initiale";
         // définition de la géométrie
         sort << "\n ( (geometry facettes-frontiere-maillage0  {OFF";
         // on récupère  tableau des list des elements frontiere
         Tableau <LaLIST <Front>*>& tab_list_front = lesMail->ListFrontiere(); 
         // on définit le nombre de facette à visualiser
         // === début du comptage
         // un compteur qui globalise le nombre de facette a dessiner
         int nbfacette=0;
         int nbtab_list_front = tab_list_front.Taille();
         // récup de la liste des éléments frontières
         LaLIST<Front>::iterator il,ilfin=tab_list_front(numMail)->end();
            for (il=tab_list_front(numMail)->begin();il!=ilfin;il++) // boucle sur les éléments frontière
             { const ElemGeomC0& elgeom = (*il).Eleme()->ElementGeometrique(); 
               // le tableau des triangles linéaire
               const Tableau<Tableau<Tableau<int> > >&  tabtria = elgeom.Trian_lin();
               // le nombre de face à visualiser           
               int nb_FA = tabtria.Taille();
               // dans le cas où il n'y a pas de facette la boucle suivante ne démarre pas
               for (int k=1;k<= nb_FA;k++)
                { // nombre de triangle de la face
                  nbfacette += tabtria(k).Taille();
                  }
              }
         // === fin du comptage de facette
         // def de l'entité maillage initial
         sort << "\n     # ecriture de l'entete "
              << "\n     # nombre de sommet, de faces, d'arrete = 0";
         int nbmaxinoeud = lesMail->Nombre_noeud(numMail);
         // on ecrit le nombre de sommet, de faces et d'arrete=0
         sort <<"\n        " << nbmaxinoeud << " " << nbfacette << " 0 ";
         // création des points
         sort << "\n     # ecriture des coordonnees des sommets  ";
         // on balaie tous les noeuds du maillage
         for (int numNoeud=1; numNoeud<= nbmaxinoeud;numNoeud++) 
               { // recup du noeud
                 Noeud & noe = lesMail->Noeud_LesMaille(numMail,numNoeud);
                 // ecriture des coordonnee à 0 
                 sort <<"\n                        "
                      << setw (16);  noe.Coord0().Affiche(sort,16);
                 // si l'on n'est pas en dimension 3 on complete avec des zeros
                 if (paraGlob->Dimension () == 2)
                   { sort << setw (16) << 0 <<" ";
                    }
                 else if (paraGlob->Dimension () == 1)
                    { sort << setw (16) << 0  <<" " << setw (16) << 0  <<" ";
                    }
                 sort <<  "  ";
                 }
         // création des faces
         sort << "\n     # ecriture de la connection des faces et de la couleur de chaque face";
         // récup de la liste des éléments frontières
         for (il=tab_list_front(numMail)->begin();il!=ilfin;il++) // boucle sur les éléments frontière
             { const ElemGeomC0& elgeom = (*il).Eleme()->ElementGeometrique();  // l'élément géométrique de la frontière
               Tableau<Noeud *>& tab_noeud = (*il).Eleme()->TabNoeud(); // ses noeuds
               // le tableau des triangles linéaire
               const Tableau<Tableau<Tableau<int> > >&  tabtria = elgeom.Trian_lin();
               // le nombre de face à visualiser           
               int nb_FA = tabtria.Taille();
               // dans le cas où il n'y a pas de facette la boucle suivante ne démarre pas
               for (int k=1;k<= nb_FA;k++)
                { // nombre de triangle de la face
                  int nbtriangle = tabtria(k).Taille();
                  for (int ikt=1;ikt<=nbtriangle;ikt++,nbfacette++)
                   { 
                     #ifdef MISE_AU_POINT
                     // vérification du nombre de noeud du triangle
                      if (tabtria(k)(ikt).Taille() != 3)
                        { cout << "\n erreur, les facettes n'ont pas 3 noeuds,"
                               << " nbnoeud = " << tabtria(k)(ikt).Taille()
                               << " \n Frontiere_initiale_geomview::ExeOrdre(... " ;
                          Sortie(1);     
                         }
                     #endif
                     // la connection
                     sort << "\n 3 "; // le nombre de sommet de la face
                     for (int no = 1; no<=3; no++)
                         sort << (tab_noeud(tabtria(k)(ikt)(no))->Num_noeud() - 1) << " "; 
                     // la couleur
                     sort << Rcoulf << " " << Gcoulf << " " << Bcoulf<< " ";
                    }
                 }
               } // -- fin de la boucle sur les éléments frontières
         // fin pour les faces 
         // fin: on ferme la géométrie 
         sort << "\n    } )";
         sort << "\n # fin du dessin des facettes des elements de la frontiere du maillage initial"
              << "\n # --------------------------------------------------------------------------\n";
        }      
/*    if (filaire)
       { 
         // quelques commentaires pour indiquer les arrêtes            
         sort << "\n # ---------------------------------------------------------------------"
              << "\n # dessin des arretes des elements de la frontiere du maillage initiale";
         // définition de la géométrie
         sort << "\n ( (geometry arretes-frontiere-maillage0  {SKEL";
         // def d'un compteur du nombre d'arrete dessiné
         int nbarr = 0;
             // on balaie tous les éléments du maillage
         int nbmaxiElement = lesMail->Nombre_element(numMail);
         for (int numElem=1; numElem<= nbmaxiElement;numElem++) 
           { // recup de l'élément
             Element & elem = lesMail->Element_LesMaille(numMail,numElem);
             // connection des noeuds des arêtes par rapport a ceux de l'element
             Tableau<Tableau<int> > const & nomS =  elem.ElementGeometrique().NonS();
             nbarr += nomS.Taille(); // incrémentation du nombre d'arrêtes
            }
         // === fin du comptage
         // def de l'entité maillage initial
         sort << "\n     # ecriture de l'entete "
              << "\n     # nombre de sommet,  d'arrete ";
         int nbmaxinoeud = lesMail->Nombre_noeud(numMail);
         // on ecrit le nombre de sommet et d'arrete
         sort <<"\n        " << nbmaxinoeud << " " << nbarr << "  ";
         // création des points
         sort << "\n     # ecriture des coordonnees des sommets  ";
         // on balaie tous les noeuds du maillage
         for (int numNoeud=1; numNoeud<= nbmaxinoeud;numNoeud++) 
               { // recup du noeud
                 Noeud & noe = lesMail->Noeud_LesMaille(numMail,numNoeud);
                 // ecriture des coordonnee à 0 
                 sort <<"\n                        "
                      << setw (16);  noe.Coord0().Affiche(sort,16);
                 // si l'on n'est pas en dimension 3 on complete avec des zeros
                 if (paraGlob->Dimension () == 2)
                   { sort << setw (16) << 0 <<" ";
                    }
                 else if (paraGlob->Dimension () == 1)
                    { sort << setw (16) << 0  <<" " << setw (16) << 0  <<" ";
                    }
                 sort <<  "  ";
                 }
         // création des arrêtes
         sort << "\n     # ecriture de la connection des arrêtes et de la couleur de chaque arrete";
             // on balaie tous les éléments du maillage
         for (int numElem=1; numElem<= nbmaxiElement;numElem++) 
           { // recup de l'élément
             Element & elem = lesMail->Element_LesMaille(numMail,numElem);
             Tableau<Noeud *>& tab_noeud = elem.Tab_noeud (); // ses noeuds
             // connection des noeuds des arêtes par rapport a ceux de l'element
             Tableau<Tableau<int> > const & nomS =  elem.ElementGeometrique().NonS();
             int nb_ar = nomS.Taille(); // nombre d'arrêtes
             for (int k=1;k<= nb_ar;k++,nbarr++)
              { Tableau<int>const & tabn = nomS(k); 
                int nb_no = tabn.Taille(); // le nb de noeud de l'arrête
                sort << "\n                   " << nb_no << " "; //début de l'arrête 
                for (int no = 1; no<=nb_no; no++)
                  sort << (tab_noeud(tabn(no))->Num_noeud() - 1) << "  "; 
                // la couleur
                sort << Rcoull << " " << Gcoull << " " << Bcoull<< " ";
              }
            }  
         // fin pour les arrêtes
         // fin: on ferme la géométrie 
         sort << "\n    } )";
         sort << "\n # fin du dessin des arretes des elements de la frontiere du maillage initial"
              << "\n # -------------------------------------------------------------------------\n";
       }                         
      if (numero) // cas d'une des numéros
       { cout << "\n **** erreur sortie des numeros de la frontiere du maillage iniaitle pas encore implante ****"
              << "\n Frontiere_initiale_geomview::ExeOrdre(..." << endl;
       }*/
    };//-- fin de la boucle sur les maillages
   // et on vide le buffer de sortie
   sort << endl;
   }; 
 };
       
// lecture des paramètres de l'ordre dans un flux
void Frontiere_initiale_geomview::Lecture_parametres_OrdreVisu(UtilLecture & )
 { 
  };

// écriture des paramètres de l'ordre dans un flux
void Frontiere_initiale_geomview::Ecriture_parametres_OrdreVisu(UtilLecture & )
 { // récup du flot 
   cout << "\n pour l'instant pas de sauvegarde des parametres de frontiere pour le format geomview";
  };