/***************************************************************************
 applications.cpp  -  Librairie d'objets pour creer des applications
 -------------------
 begin                : ven aug 14 10:25:55 CEST 2000
 copyright            : (C) 2000 by Olivier Langella CNRS UPR9034
 email                : Olivier.Langella@pge.cnrs-gif.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 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include"applications.h"

Application::Application() {
#ifndef GZSTREAM_H
	_formatMatrice = 1;
#else
	_formatMatrice = 1; //5 format gnumeric
#endif
	_confirmeEcraseFichier = true;
}
void Application::affPubSortie() const {

	cout << endl << endl;
	cout << "Programmation: Olivier Langella" << endl;
	cout << "" << endl;
	cout << "e-mail: langella@moulon.inra.fr" << endl;
	cout << "" << endl;
	cout << endl << endl;
}

void Application::affPubEntree() const {

	cout << endl << endl;
	cout << "**************************************" << endl;
	//	cout << "*  Populations 1.1.00  CNRS UPR9034  *" << endl;
	cout << "*      langella@moulon.inra.fr      *" << endl;
	cout << "*  *" << endl;
	cout << "**************************************" << endl;
	cout << endl << endl;
}

void Application::lancement(int nbcommandes, char ** commandes) {

	if (nbcommandes > 1) {
		fLigneCommande(commandes, nbcommandes);
	} else {
		affPubEntree();

		while (menu_principal() != 0) {
		}

		affPubSortie();
	}
}

void Application::fLigneCommande(char ** commandes, int nbcommandes) {
	affPubEntree();

}

int Application::menu_principal() {
	int choix;
	cout << endl << endl;
	cout << "0) Quitter" << endl;

	/*	cout << endl << "choix: ";
	 cin >> choix;
	 */
	choix = DemandeChoix(0, 0);

	switch (choix) {
	case 0:
		return (0);
		break;
		//	case 1:
		//		return(1);
		//		break;
	default:
		return (0);
		break;
	}
}

int Application::menu_formatMatrice() {
	int choix;
	cout << endl << endl;
	cout << _("Matrix outputfile format:") << endl;
	cout << "1) " << _("ASCII, (excell or gnumeric compliant)") << endl;
	cout << "2) " << _("NtSys") << endl;
	cout << "3) " << _("Phylip") << endl;
	cout << "4) " << _("xgobi") << endl;
	cout << "5) " << _("Gnumeric spreadsheet") << endl;

	/*	cout << endl << "choix: ";
	 cin >> choix;
	 */
	choix = DemandeChoix(1, 5);

	switch (choix) {
	case 1:
		_formatMatrice = 1;
		return (1);
		break;
	case 2:
		_formatMatrice = 2;
		return (2);
		break;
	case 3:
		_formatMatrice = 4;
		return (3);
		break;
	case 4:
		_formatMatrice = 3;
		return (4);
		break;
	case 5:
		_formatMatrice = 5;
		return (5);
		break;
	default:
		return (0);
		break;
	}
}

bool Application::litMatriceLD(MatriceLD &mat) {
	bool ok(false);

	/*	if (*PPmat != NULL) {
	 delete *PPmat;
	 *PPmat = NULL;
	 }*/

	while (_fichier.is_open() == 0) {
		cout << _("Matrix filename ?") << endl;
		cin >> _nomFichier;

		_fichier.open(_nomFichier.c_str(), ios::in);
		_fichier.clear();
	}

	try {
		//	*PPmat = new MatriceLD();
		cout << _("Reading file...") << endl;

		//cerr << " Application::litMatriceLD(MatriceLD &mat)" << endl;
		//cerr << _fichier;
		//    char c;
		//   while ( _fichier.get(c))
		//	cerr << c;

		mat.iFichier(_fichier);
		_fichier.clear();
		_fichier.close();
		ok = true;
	} catch (MatriceLD::Anomalie pb) {
		_fichier.close();
#ifdef GZSTREAM_H
		igzstream gzfichier;
		gzfichier.open(_nomFichier.c_str(), ios::in);

		try {
			//cerr << " Application::litMatriceLD(MatriceLD &mat) gzfile" << endl;
			//    char c;
			//   while ( _fichier.get(c))
			//	cerr << c;
			mat.iGnumeric(gzfichier);
			ok = true;
			gzfichier.close();
			//cerr << " Application::litMatriceLD(MatriceLD &mat)" << endl;
			//mat.oExcel(cerr);
			return(ok);
		}
		catch (MatriceLD::Anomalie pb) {
			ok = false;
		}
		gzfichier.close();
#else
		ok = false;
#endif
		//	if (*PPmat != NULL) delete *PPmat;


		switch (pb.le_pb) {
		default:
			cout << _("This Matrix file format is not recognized...") << endl;
			break;
		}
	}

	return (ok);
}

bool Application::ecritMatriceLD(MatriceLD &mat, string nomFichier, int format) {
	bool ok(false);
	ofstream sortie;

	if (format == 0)
		format = _formatMatrice;

	/*	if (*PPmat != NULL) {
	 return (false);
	 }*/
	//cerr << format;
	//_sortie << ends;
	//_sortie.close();

	while (nomFichier == "") {
		cout << _("Matrix filename to write into ?") << endl;
		cin >> nomFichier;
	}

	sortie.open(nomFichier.c_str(), ios::out);

	//sortie << "coucou application::ecritMatriceLD";
	// cerr << "coucou pplication::ecritMatriceLD";
	//	_sortie << ends;
	//	_sortie.close();

	try {
		mat.ofFormat(sortie, format, nomFichier);
		//sortie << ends;
		sortie.close();
		ok = true;
	} catch (MatriceLD::Anomalie pb) {
		sortie.close();
		ok = false;

		switch (pb.le_pb) {
		default:
			cout << _("Error writing matrix") << " MatriceLD::Anomalie "
					<< pb.le_pb << endl;
			break;
		}
	}

	return (ok);
}

bool Application::DemandeOuiNon(char laquestion[]) const {
	string rep;

	cout << laquestion << endl;
	cin >> rep;
	//	cout << endl;
	if (rep == "")
		rep.assign("N");

	switch (rep[0]) {
	case 'Y':
		return (true);
		break;
	case 'y':
		return (true);
		break;
	case 'o':
		return (true);
		break;
	case 'O':
		return (true);
		break;
	default:
		return (false);
		break;
	}
}

string Application::DemandeString(char laquestion[]) const {
	string rep("");

	while (rep == "") {
		cout << endl << laquestion << endl;
		cin >> rep;
	}
	return (rep);
}

string Application::DemandeFichier(const string & laquestion) {
	string rep("");
	bool ok(false);

	while ((rep == "") || (ok == false)) {
		ok = false;
		cout << endl << laquestion << endl;
		cin >> rep;
		if ((rep != "") && (_confirmeEcraseFichier) && (fFichierExiste(
				rep.c_str()))) {
			cout << _("The file ") << rep << _(" already exist.") << endl;
			if (DemandeOuiNon(_("Choose Y if you to overwrite it: ")))
				ok = true;
		} else
			ok = true;
	}

	return (rep);
}

float Application::DemandeReel(char laquestion[], float inf, float sup) const {
	float reel(-9999);
	string rep;

	while ((reel < inf) || (reel > sup)) {
		cout << endl << laquestion << endl;
		cin >> rep;
		reel = atof(rep.c_str());
	}
	return (reel);
}

int Application::DemandeEntier(const string & laquestion, int inf, int sup) const {
	int entier(-999);
	string rep;

	while ((entier < inf) || (entier > sup)) {
		cout << endl << laquestion << endl;
		cin >> rep;
		entier = atoi(rep.c_str());
	}
	return (entier);
}

int Application::DemandeEntier(char laquestion[], int inf, int sup, int defaut) const {
	int entier(-999);
	char car;
	string mot;
	if ((defaut < inf) || (defaut > sup))
		cerr << "DemandeEntier defaut ERROR" << endl;

	while ((entier < inf) || (entier > sup)) {
		cout << endl << laquestion << endl;
		cin.get(car);
		cin.get(car);
		//	rep[0] = rep[0]+50;
		//		cout << rep;
		if (car == '\n')
			entier = defaut;
		else {
			cin >> mot;
			mot = car + mot;
			entier = atoi(mot.c_str());
		}
	}
	return (entier);
}

int Application::DemandeChoix(int inf, int sup) const {

	return (DemandeEntier(_("Your choice: "), inf, sup));
}

bool Application::litJeuMatriceLD(JeuMatriceLD &jeumat) {
	bool ok(false);

	/*	if (*PPmat != NULL) {
	 delete *PPmat;
	 *PPmat = NULL;
	 }*/

	while (_fichier.is_open() == 0) {
		cout << _("Filename of the set of matrix ?") << endl;
		cin >> _nomFichier;

		_fichier.open(_nomFichier.c_str(), ios::in);
		_fichier.clear();
	}

	try {
		//	*PPmat = new MatriceLD();
		cout << _("Reading file...") << endl;
		jeumat.iFlux(_fichier);
		_fichier.clear();
		_fichier.close();
		ok = true;
	} catch (MatriceLD::Anomalie pb) {
		_fichier.close();
		ok = false;
		//	if (*PPmat != NULL) delete *PPmat;

		switch (pb.le_pb) {
		default:
			cout << _("This file format is not recognized...") << endl;
			break;
		}
	}

	return (ok);
}

bool Application::ecritJeuMatriceLD(const JeuMatriceLD &jeumat,
		string nomFichier, int format) {
	bool ok(false);
	//string nomFichier;

	if (format == 0)
		format = _formatMatrice;

	/*	if (*PPmat != NULL) {
	 return (false);
	 }*/
	//cerr << format;
	_sortie << ends;
	_sortie.close();

	while (_sortie.is_open() == 0) {
		while (nomFichier == "") {
			cout << _("Name of the file to write the set of matrix ?") << endl;
			cin >> nomFichier;
		}
		_sortie.open(_nomFichier.c_str(), ios::out);
	}

	try {
		nomFichier = _nomFichier;
		jeumat.oFlux(_sortie, format);
		_sortie << ends;
		_sortie.close();
		ok = true;
	} catch (MatriceLD::Anomalie pb) {
		_sortie.close();
		ok = false;

		switch (pb.le_pb) {
		default:
			cout << _("Writing error...") << endl;
			break;
		}
	}

	return (ok);
}
/** test si nomfichier existe */
bool Application::fFichierExiste(const string & nomfichier) {
	_fichier.open(nomfichier.c_str(), ios::in);

	if (_fichier.is_open() == 0) {
		_fichier.clear();
		return (false);
	}
	_fichier.close();
	return (true);
}
