// 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-2021 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/>.

/************************************************************************
 *     DATE:        19/01/2007                                          *
 *                                                                $     *
 *     AUTEUR:      G RIO   (mailto:gerardrio56@free.fr)                *
 *                                                                $     *
 *     PROJET:      Herezh++                                            *
 *                                                                $     *
 ************************************************************************
 *     BUT:    gérer les mouvements solides.                            *
 *            + homothétie qui est une extension à l'objectif initial ! *
 *                                                                $     *
 *     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''     *
 *                                                                $     *
 ************************************************************************/

#ifndef MOUVEMENT_SOLIDE_H
#define MOUVEMENT_SOLIDE_H

#include "UtilLecture.h"
#include "Coordonnee.h"
#include "Tableau_T.h"
#include "Basiques.h" 

/**
* \author    Gérard Rio
* \version   1.0
* \date      19/01/2007
* \brief       gérer les mouvements solides avec homothétie qui est une extension à l'objectif initial
*
*/
class MvtSolide
{   // surcharge de l'operator de lecture
    // les informations sont typées
    friend istream & operator >> (istream &, MvtSolide &);
    // surcharge de l'operator d'ecriture typée
    friend ostream & operator << (ostream &, const MvtSolide &);
    
  public :
    // CONSTRUCTEURS :
    
    // par défaut
    MvtSolide();
    // de copie
	   MvtSolide (const MvtSolide& nd);
    // DESTRUCTEUR : 
	   ~MvtSolide ();
    
    
    // METHODES PUBLIQUES :
    
    // Affiche les donnees 
	   void Affiche () const ;
	
	   // Realise l'egalite
	   MvtSolide& operator= (const MvtSolide& d);
	   //Surcharge d'operateur logique
	   bool operator == ( const MvtSolide& a) const ;	 
    bool operator != ( const MvtSolide& a) const { return !(*this == a);};

    // lecture des mouvements solides 
    void Lecture_mouvements_solides(UtilLecture * entreePrinc);
    // mot clé d'existence de mouvement solide en lecture
    static string MotCleMvtSolide()  {return string("mouvement_solide_");};
     
    // 0) indique si oui ou non il y a un mouvement solide
    bool ExisteMvtSolide() const {return (tab_tcr.Taille() != 0); };
    // retour de la première rotation: en fait l'axe de rotation
    const Coordonnee& Premiere_rotation()const;
    // indique s'il existe seulement une seule rotation
    bool ExisteUneSeuleRotation()const;
    // récupération des centres de rotation noeud, éventuellement
    // 1) donne en retour la liste des identificateurs de centre de noeud
    const list <String_et_entier>& Liste_ident_centreNoeud()const {return lis_centre_noeud;};
    // 2) renseigne les centres en cours pour la prochaine applications des mouvements solides
    void RenseigneCentreNoeud(const list <Coordonnee> & lis_coor) {list_coor_centre_noeud = lis_coor;};
    // 3) application des mouvements solides aux points transmis et retour du point
    // transformé
    Coordonnee & AppliqueMvtSolide (Coordonnee & M) const ;
    // 3) idem que précédemment, mais avec un coefficient d'intensité
    //    dans le cas d'une translation, celle-ci est multiplié par le coef
    //    dans le cas d'un nouveau centre, sa position n'est pas affectée par le coef
    //    dans le cas d'une rotation, celle-ci est multiplié par le coef
    //    dans le cas d'une homothétie: celle-ci est multiplié par le coef
    Coordonnee & AppliqueMvtSolide (Coordonnee & M, const double& coef) const ;
    // affichage et definition interactive des commandes
    void Info_commande_MvtSolide(ostream & sort);
    
    // effacement du mouvement solide actuel
    void EffaceMvtSolide();
    
  private :  
    // VARIABLES PROTEGEES :
    Tableau <Coordonnee>  tab_tcr; // tableau des translations, centres et rotations
    Tableau <int> tab_indic; // indique les types de transformations effectuées
                         // =1  cas d'une translation normale
                         // =2  cas de la définition du centre de rotation
                         // =3  cas d'une rotation 
                         // =4 cas d'un centre de rotation donné par les coordonnées d'un noeud
                         // =5 cas d'une homothétie
     // cas où l'on utilise des positions de noeuds pour définir les centres de rotation
    list <String_et_entier> lis_centre_noeud; // doit avoir la dimension du nombre de fois où il y a 
                   // apparition de tab_indic = 4, le string contient le nom du maillage, et l'entier
                   // le numéro du noeud
    list <Coordonnee> list_coor_centre_noeud; // list de travail qui sert à récupérer la position des 
                  // noeuds              
    
    
    // METHODES PROTEGEES :

 };
 
#endif  
