/*
  .__       .           .
  [__) _  _.|_  _ ._. _.|_  _
  |  \(/,(_.[ )(/,[  (_.[ )(/,...
     _     _
    | |__ (_) __ _ _ __ __ _ _ __ ___  _ __ ___   ___
    | '_ \| |/ _` | '__/ _` | '_ ` _ \| '_ ` _ \ / _ \
    | |_) | | (_| | | | (_| | | | | | | | | | | |  __/
    |_.__/|_|\__, |_|  \__,_|_| |_| |_|_| |_| |_|\___|
             |___/

AUTEURS	: Aymeric & Ramazan
GROUPE	: RT (5)
DATE	: 21/03/2003
FICHIER	: main.cpp

*/


#include <iostream.h>
#include <fstream.h>
#include "liste.h"
#include "arbre.h"
#include "bigramme.h"
#include <time.h>
#include <stdlib.h>

#define nomdefaut1 "/ETD/IUP1/public/TP_RECHERCHE/data.model"
#define nomdefaut2 "/ETD/IUP1/public/TP_RECHERCHE/data.test"

// cette fonctionne retourne la taille du fichier passe en parametre
int tailleFichier(char * nom)
{
	int m1,m2;
	float p;

	// ouverture du stream du fichier
	ifstream f(nom);

	// si le fichier ne peut etre lu on retourne -1
	if (!f)
	{
		cout << "\nLe fichier (" << nom << ") ne peut etre lu !\n";
		return (-1);
	}

	int taillefichier=0;

	// on parcourt chaque ligne du fichier jusqu'a End Of File
	while (!f.eof())
	{
		f >> m1 >> m2 >> p;
		taillefichier++;
	}

	f.close();

	// on retourne la taille trouvee
	return (taillefichier);
}


// cette fonction permet de convertir un temps donne en seconde en heure, minute et seconde
void afficheDuree(int temps)
{
	int h,m,s;

	// calcule du nombre d'heures
	h=temps / 3600;
	temps=temps%3600;

	// on calcule le nombre de minutes
	m=temps/60;

	// on calcule le nombre de secondes
	s=temps%60;

	// on affiche le resultat
	if (h > 0) cout << h << " h ";
	if (m > 0) cout << m << " mn ";
	if ((m > 0) && (s > 0)) cout << s << " s";
	else if ((h == 0) && (m == 0) && (s <= 1)) cout << s << " seconde";
	else if ((h == 0) && (m == 0) && (s > 1)) cout << s << " secondes";
	else cout << s << " s";
}

// fonction principale du programme
// on passera en parametre le path et nom du fichier source (data.model)
// en 2eme argument on peut passer le nom du fichier data.test
int main(int argc, char **argv)
{
	// si on a aucun argument ou plus de 2, on retourne une erreure
	if ((argc < 2) || (argc > 4))
	{
		cout << "BIGRAMME TP1 version 21.03.03\n";
		cout << "Syntaxe : " << argv[0] << " [-o] [fichier_model [fichier_test]]\n";
		cout << "\t     -o \t\tprend les 2 fichiers par defaut (ceux donnes dans le TP)\n";
		cout << "\tfichier_model \t\tcorrespond au path et nom complet du fichier data.model\n";
		cout << "\tfichier_test \t\tcorrespond au path et nom complet du fichier data.test\n";
		cout << "\nCe programme recherche la probabilite d'un bigramme dans un fichier model (fichier_model).\n";
		cout << "La recherche de la probabilite d'un bigramme peut se faire a partir d'un fichier source (fichier_test).\n";
		return(-1);
	}

	int m1,m2,choix=1,taille=0,i=0;
	float p;
	bool m5=false;
	char *nomfichier1,*nomfichier2;
	time_t debut,milieu,fin;

	cout << "\n\n  .__       .           .   \n";
	cout << "  [__) _  _.|_  _ ._. _.|_  _ \n";
	cout << "  |  \\(/,(_.[ )(/,[  (_.[ )(/,...\n";
	cout << "     _     _                                          \n";
	cout << "    | |__ (_) __ _ _ __ __ _ _ __ ___  _ __ ___   ___ \n";
	cout << "    | '_ \\| |/ _` | '__/ _` | '_ ` _ \\| '_ ` _ \\ / _ \\\n";
	cout << "    | |_) | | (_| | | | (_| | | | | | | | | | | |  __/\n";
	cout << "    |_.__/|_|\\__, |_|  \\__,_|_| |_| |_|_| |_| |_|\\___|\n";
	cout << "             |___/                                    \n";
	cout << "\n";
	cout << "\t\t\t\tVersion 21.03.03";

	// affichage du menu
	// il faut choisir la methode 5 si l'on veut chercher chaque bigramme contenu dans le fichier2
	// sinon on pourra rechercher 1 seul bigramme rentre au clavier
	do
	{
		if ((choix < 1) || (choix > 5)) cout << "\nVous devez rentrer un nombre entre 1 et 5 !\n";
		cout << "\n\nMethodes proposees :\n";
		cout << "\t1. Recherche sequentielle dans une liste chainee\n";
		cout << "\t2. Recherche sequentielle dans un tableau trie\n";
		cout << "\t3. Recherche dichotomique dans un tableau trie\n";
		cout << "\t4. Recherche par Arbre Binaire de Recherche non equilibres\n";
		cout << "\t5. Rechercher a partir du 2eme fichier\n";
		cout << "\nQuelle methode voulez-vous employer ? ";
		cin >> choix;
	}
	// on verifie ce que rentre l'utilisateur
	while ((choix < 1) || (choix > 5));

	// si on choisit une des 4 premieres methodes
	// on rentre a la main le bigramme recherche
	if (choix != 5)
	{
		cout << "\nRecherche du bigramme ...";
		cout << "\n\tRentrez m1 : ";
		cin >> m1;
		cout << "\tRentrez m2 : ";
		cin >> m2;
	}
	// sinon on prend comme 2eme fichier celui rentre en parametre ou le fichier par defaut (option -o)
	else
	{
		if (strcmp(argv[1],"-o") != 0)
		{
			if (argv[2] == NULL)
			{
				cout << "\t=> Aucun 2eme fichier specifie !\n";
				cout << "\n\nSyntaxe : " << argv[0] << " [-o] [fichier_model [fichier_test]]\n";
				return(-1);
			}
			nomfichier2=argv[2];
		}
		else
			nomfichier2=nomdefaut2;

		do
		{
			cout << "Choisissez une methode (de 1 a 4) : ";
			cin >> choix;
		}
		// on verifie ce que rentre l'utilisateur
		while ((choix < 1) || (choix > 4));

		m5=true;
	}

	if (strcmp(argv[1],"-o") == 0) nomfichier1=nomdefaut1;
	else nomfichier1=argv[1];

	cout << "\nTraitement de la demande en cours ...\n";

	// la variable debut va contenir le nombre de secondes ecoulees depuis le 01/01/1970 au debut de l'execution
	debut=time(0);

	// si la methode demande l'utilisation d'un tableau, on va determiner la taille du fichier
	if ((choix == 2) || (choix == 3))
	{
		taille=tailleFichier(nomfichier1);
		if (taille == -1)
		{
			cout << "Erreur => taillefichier()\n";
			return(-1);
		}
	}

	// on declare B comme bigramme
	// cela va permettre aussi de stocker data.model dans l'objet adequate graces aux parametres
	Bigramme B(nomfichier1,choix,taille);

	// milieu contient le nombre de secondes ecoulees depuis le 01/01/1970 au milieu de l'execution
	milieu=time(0);

	// on enclenche la recherche
	cout << "\nRecherche en cours ...\n";

	// si on utilise le 2eme fichier, on lit son contenu
	if (m5)
	{
		ifstream f(nomfichier2);
		f >> m1;
		f >> m2;

		// on parcourt le fichier2, et a chaque bigramme trouve on lance la recherche
		while (!f.eof())
		{
			p=B.recherche_Bigramme(m1,m2,choix,m5);
			if (p!=0) i++;
			m1 = m2;
			f >> m2;
		}
	}
	else
		p=B.recherche_Bigramme(m1,m2,choix,m5);

	// fin contient le nombre de secondes ecoulees depuis le 01/01/1970 a la fin de l'execution
	fin=time(0);

	// affiche les donnees finales relatives au traitement
	if (m5) cout << endl << i << " bigrammes trouves !";
	cout << "\nTemps de la recherche : ";
	afficheDuree(fin - milieu);
	cout << "\nTemps du traitement : ";
	afficheDuree(fin - debut);

	// on affiche la memoire necessaire pour stocker le modele
	cout << "\nMemoire allouee : ";
	B.memoire(choix);

	cout << "\nNombre d'operations fondamentales : " << B.retourneFonda();

	cout << "\n";
	return(0);
}

