// FICHIER : Lecture_reference.cc

// 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 <errno.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#include "Lect_reference.h"


Tableau<Reference> Lect_reference (char* nom_fichier)
// LECTURE DES REFERENCES DU MAILLAGE ET STOCKAGE DE TOUTES LES
// REFERENCES DANS UN TABLEAU
{
	
	
	FILE* fichier;
	char ligne[80];
	
	
	// *** Ouverture du fichier de donnees ***
	
	if ( (fichier=fopen(nom_fichier,"r"))==NULL )
	{
		cout << "ERREUR D'OUVERTURE DU FICHIER :"; 
		cout << nom_fichier << "\n";
		exit(1);
	};
	
	
	// *** Calcul du nombre de reference ***
	// ( et sauvegarde de l'indicateur de position des lignes
	// du fichier ou sont definies des references )
	
	unsigned long int position=0; //indicateur de position dans le fichier lu
	Liste<long int> liste_posit; 	// liste contenant des positions correspondant
									// a la definition d'une reference
	// num_ligne est le numero de la derniere ligne lue (utile pour
	// les messages d'erreur)
	int num_ligne=0;					
	
	// Parcours de l'ensemble du fichier et stockage dans liste_posit_ref
	// des indicateurs de position
	while ( feof(fichier)==0 )
	{
		position=ftell(fichier);// sauvegarde dans position de la position
								// courante dans le fichier
		num_ligne=num_ligne+1;
		if ( (fgets(ligne,80,fichier)==NULL) && (feof(fichier)==0) )
		{
			cout << "ERREUR DE LECTURE DU FICHIER :"; 
			cout << nom_fichier << "\n";
			cout << "Numero de la derniere ligne lue correctement :";
			cout << (num_ligne-1) << "\n";
			exit(1);
		};
		if ( (strstr(ligne,"N_R")!=NULL) || (strstr(ligne,"E_R")!=NULL) ||
			(strstr(ligne,"F_R")!=NULL) || (strstr(ligne,"A_R")!=NULL) )
		// presence d'un nom de reference
			liste_posit.Ajout(position);
		ligne[0]='\0';
	};
	
	if ( liste_posit.Nombre()==0 )
	{
		cout << "ERREUR DE LECTURE DU FICHIER : "; 
		cout << nom_fichier << "\n";
		cout << "Aucune reference n'a ete trouve !\n";
	};
	
	
	// *** Lecture des noms et des numeros des references ***
	// *** Stockage des informations dans tab_ref ***
	
	rewind(fichier);
	
	Tableau<Reference> tab_ref(liste_posit.Nombre());
	
	// Positionnement sur le premier element de liste_posit
	liste_posit.Debut();
	
	// Placement de l'indicateur de position sur une ligne 
	// definissant une reference et lecture des donnees de la 
	// reference
	errno=0;
	for (int i=1;i<=liste_posit.Nombre();i++)
	{
		char nom_ref[10];
		int numero=0;
		Liste<int> liste_num; // liste des numeros d'une reference
		fseek(fichier,liste_posit.Element(),SEEK_SET);
		fscanf(fichier,"%10s",nom_ref); // lecture du nom de la reference
		if ( feof(fichier)!=0 )
		{
			cout << "ERREUR DE LECTURE DU FICHIER :";
			cout << nom_fichier << "\n";
			cout << "Fin du fichier atteinte avant la lecture";
			cout << " totale des donnees !\n";
			exit(1);
		};
		if ( errno!=0 )
		{
			cout << "ERREUR DE LECTURE DU FICHIER : ";
			cout << nom_fichier << "\n";
			if ( i>1 )
			{
				cout << "Nom de la derniere reference lue correctement : ";
				cout << tab_ref(i-1).Nom() << "\n";
				exit(1);
			}
			else
			{
				cout << "Probleme de lecture de la premiere reference\n";
				exit(1);
			};
		};
		while ( fscanf(fichier,"%d", &numero)==1 )
		// lecture des numeros d'une reference et stockage dans liste_num
			liste_num.Ajout(numero);
		if ( liste_num.Nombre()==0 )
		{	
			cout << "ERREUR DE LECTURE DU FICHIER : ";
			cout << nom_fichier << "\n";
			cout << "La reference de nom " << nom_ref << " est vide \n";
		};
		Tableau<int> tab_num(liste_num.Nombre());
		liste_num.Debut();
		for (int j=1;j<=liste_num.Nombre();j++)
		// stockage a partir de la liste des numeros liste_num de l'ensemble
		// des numeros d'une reference dans le tableau tab_num
		{
			tab_num(j)=liste_num.Element();
			liste_num.Suivant();
		};
		Reference ref(tab_num,nom_ref);
		tab_ref(i)=ref; // sauvegarde de l'ensemble des donnees d'une reference dans tab_ref
		liste_posit.Suivant();
	};
	
	
	// *** Fermeture du fichier de donnees ***
			
	if ( fclose(fichier)==-1 )
	{
		cout << " ERREUR DE FERMETURE DU FICHIER "; 
		cout << nom_fichier << "\n";
		exit(1);
	};
	
	
	// *** Renvoie du tableau de reference ***
	
	return tab_ref;

};