/***************************************************************************
                          arbreplus.cpp  -  description
                             -------------------
    begin                : Mon Jun 4 2001
    copyright            : (C) 2001 by Olivier Langella
    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 "arbreplus.h"

namespace biolib {
namespace arbres {

ArbrePlGroupes::ArbrePlGroupes(const ArbrePlus * Parbre): _Parbre(Parbre) {
}
ArbrePlGroupes::~ArbrePlGroupes(){	
//	while (size() > 0) delete back();
}

ArbrePlus::ArbrePlus(): _tabGroupes(this), _couleur_neutre(0,0,0){
}
ArbrePlus::~ArbrePlus(){
}


void ArbrePlGroupes::push_back_groupe(const string & nom, const string & couleur) {
//	push_back(new ArbreVectUINT());
	ArbreVectUINT nouveau;

	push_back(nouveau);

	_tabNom.push_back(nom);
	_tabCouleur.push_back(Couleur(couleur));

}

int ArbrePlGroupes::RechercheGroupeOTU(unsigned int id) const {

	unsigned int i;

	for (i=0 ; i < size(); i++) {
		if (operator[](i).Existe(id)) return(i);
	}
	return (-1);
}


void ArbrePlus::define_outgroup(const ChaineCar & outgroup){
	unsigned int nbmots,i;
	int pos(-1);
	string mot;
	
	if (outgroup == "") return;
	nbmots = outgroup.GetNbMots();
	_Vind_outgroup.resize(0);
	for (i = 0; i < nbmots; i++) {
		outgroup.GetMot(i+1, mot);
		pos = PositionInd(mot.c_str());
		if (pos == -1) {
			cerr << "Erreur TreePlotter::define_outgroup" << endl;
			cerr << mot << _(" was  not found") << endl ;
			return;
		}
//cerr << "TreePlotter::define_outgroup pos" << pos << endl;
		_Vind_outgroup.push_back(_tabPind[pos]->get_id());
	}

	//Recherche du noeud contenant une branche avec _Vind_outgroup
	// => charger les "vecteurs d'individus" de l'arbre
//cerr << "TreePlotter::define_outgroup" << endl;
	_Vind_outgroup.f_tri();
	f_load_vect_id_ind();
//cerr << RechercheNoeud(_Vind_outgroup) << endl;
	set_Pracine(RechercheNoeud(_Vind_outgroup));
//cerr << "TreePlotter::define_outgroup fin"<< endl;
}

void ArbrePlus::ajouter_groupe(const ChaineCar & groupe, const string & couleur, const string & nom){
	unsigned int nbmots,i;
	signed int pos(-1);
	ChaineCar mot;
//cerr << "ArbrePlus::ajouter_groupe " << groupe << endl;
//	Couleur bidon("");

//	if (lacouleur == "") lacouleur.assign(bidon.get_couleur_diff());

	_tabGroupes.push_back_groupe(nom, couleur);
//cerr << "TreePlotter::define_outgroup groupes " << groupe << endl;
	
	if (groupe == "") return;
	nbmots = groupe.GetNbMots();
	_tabGroupes.back().resize(0);
	for (i = 0; i < nbmots; i++) {
		groupe.GetMot(i+1, mot);
		pos = (int) mot;
		if (((mot.EstUnChiffre()) && (pos > 0) && ((unsigned int) pos < _tabPind.size())) || (mot == "0")){
//cerr << "ArbrePlus::ajouter_groupe [" << mot << endl;
			if ((mot == "0") && (_tabPind.size() == 1)) _tabGroupes.back().push_back(0);
			else _tabGroupes.back().push_back(pos);
		}
		else {
			pos = PositionInd(mot.c_str());
//cerr << "TreePlotter::define_outgroup pos" << pos << endl;
			if (pos == -1) {
				cerr << "Erreur" << endl;
				cerr << mot << _(" was  not found") << endl ;
			}
			else if ((unsigned int) pos < _tabPind.size())	_tabGroupes.back().push_back(_tabPind[pos]->get_id());
		}
	}

	//Recherche du noeud contenant une branche avec _Vind_outgroup
	// => charger les "vecteurs d'individus" de l'arbre
//cerr << "TreePlotter::define_outgroup" << endl;
	_tabGroupes.back().f_tri();
}

const Couleur & ArbrePlus::get_couleur_otu (unsigned int id) const {
	int numgroupe(_tabGroupes.RechercheGroupeOTU(id));

	if (numgroupe == -1) return(get_couleur_neutre());
	else return(_tabGroupes.get_couleur((unsigned int)numgroupe));
}

void ArbrePlus::iPhylipDefGroupe(const string & ligne) {
 //définition d'un groupe (lecture de fichier Phylip
	//#G nom couleur 'groupe'
	Titre tabArguments;
cerr << "ArbrePlus::iPhylipDefGroupe(const string & ligne)" << ligne << endl;
	tabArguments.GetArguments(ligne);
cerr << tabArguments[1] << endl;
cerr << tabArguments[2] << endl;
cerr << tabArguments[3] << endl;
	
  if (tabArguments.size() == 4) ajouter_groupe(tabArguments[3], tabArguments[2], tabArguments[1]);
	else if (tabArguments.size() == 3) ajouter_groupe(tabArguments[2], tabArguments[1], "");

}

void ArbrePlus::oPhylipEcritGroupes(ostream & fichier) const {
	//ecrit les groupes au format phylip traffiqué Olivier:
	// #G Couleur 'pop1 pop2 ...popn'
	// dans le fichier
  unsigned int i,j;
	if (_tabGroupes.size() == 0) return;

	if (_titre.size() == 0) fichier << "[";
	else fichier << "\\";

	for (i = 0; i < _tabGroupes.size(); i++) {
		fichier << "#G '" << _tabGroupes.get_nom(i) << "' '" << _tabGroupes.get_couleur(i).get_nom() << "' '";
		
		for (j=0; j < _tabGroupes[i].size(); j++) {
			fichier << _tabGroupes[i][j];
		
			if (j != (_tabGroupes[i].size()-1)) fichier << " ";	
		}
		fichier << "'";
		if (i != (_tabGroupes.size()-1)) fichier << "\\";
	}
	if (_titre.size() == 0) fichier << "]" << endl;
}

} //namespace biolib {
} //namespace arbres {

