/***************************************************************************
 vecteurs.h  -  Librairie d'objets permettant
 de manipuler des vecteurs
 -------------------
 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.                                   *
 *                                                                         *
 ***************************************************************************/

// Objets permettant de manipuler des vecteurs
// Olivier Langella le 12/5/99
// langella@pge.cnrs-gif.fr

#ifndef VECTEUR_H
#define VECTEUR_H

//#define __ENABLE_WSTRING

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <vector>
#include <string>
#include <iomanip>

using namespace std;

namespace biolib {
namespace vecteurs {

class VecteurLD: public vector<long double> {
};

template<class T> class Vecteur: public vector<T> {
public:

	unsigned long getNbOccurence(const T& element) const {
		unsigned long i;
		unsigned long res(0);

		for (i = 0; i < vector<T>::size(); i++) {
			if (vector<T>::operator[](i) == element)
				res++;
			//				if (this->operator[](i) == element) res++;
		}

		return (res);
	}

	bool Existe(const T& element) const {
		unsigned long i;
		bool res(false);

		for (i = 0; i < vector<T>::size(); i++) {
			if (vector<T>::operator[](i) == element) {
				res = true;
				break;
			}
		}

		return (res);
	}

	signed long Position(const T& element) const {
		unsigned long i;
		signed long res(-1);

		//	long taille(vector<T>::size());

		for (i = 0; i < vector<T>::size(); i++) {
			if (vector<T>::operator[](i) == element) {
				res = i;
				break;
			}
		}
		return (res);
	}

	void Suppr(unsigned long pos) {
		erase(vector<T>::begin() + pos);
	}

};

class ChaineCar: public string {
public:
	ChaineCar() {
		assign("");
	}

	ChaineCar(long i) {
		AjEntier(i);
	}

	ChaineCar(const char * tag) {
		assign(tag);
	}

	ChaineCar(const string& chaine) {
		assign(chaine);
	}

	~ChaineCar() {
	}

	void assigner(const string& chaine, signed long deb, signed long fin);

	operator double() const {
		return (atof(c_str()));
	}

	operator int() const {
		return (atoi(c_str()));
	}

	operator unsigned int() const {
		return (atoi(c_str()));
	}

	void GetLigneFlot(istream& entree);

	long GetNbMots() const; //retourne le nombre de mots contenus 
	void GetMot(unsigned int numero, string &mot) const;
	// dans la chaine (s�parateur= ' ' ou '/t')
	unsigned long GetNbMots(const string & separateur) const; //retourne le nombre de mots contenus
	void
	GetMot(unsigned int numero, string &mot, const string & separateur) const;

	const char * GetStr() {
		return (c_str());
	}
	;

	ChaineCar& AjEntier(long i); //conversion automatique en base 10 et concat�nation
	//	ChaineCar& operator+= (char car) {return (string::operator+=(car));};
	bool EstUnChiffre() const;

	void fmajus();
	void fsupprchiffres();
	void fsupprgauche();
	void fsupprdroite();
	void fnettoie(const string &);
	/** remplacer les occurences de "couper" par "coller" */
	void Remplacer(const string & couper, const string & coller);
	int Position(const string & motif) const;

	//	const ChaineCar& operator= (const string &rval) {*this = (ChaineCar) rval; return (*this);};

	//	const ChaineCar& operator= (const char * chaine) ;
};

class Titre: public vector<ChaineCar*> {

public:
	~Titre();
	Titre() {
	}

	//	Titre(const Titre& rval);
	Titre(char ** commandes, int nbcommandes);

	//d�pr�ci�:
	const ChaineCar& get_titre(long i) const {
		return (*(vector<ChaineCar*>::operator[](i)));
	}

	ChaineCar& GetTitre(long i) const;
	void GetArguments(const string &);
	ChaineCar& operator[](unsigned long i) const {
		if (i >= size())
			throw Anomalie(1);
		return (GetTitre(i));
	}

	ChaineCar& back() {
		return (*(vector<ChaineCar*>::back()));
	}

	long Position(const ChaineCar& chaine) const;

	void push_back(const char * pcar) {
		vector<ChaineCar*>::push_back(new ChaineCar(pcar));
	}
	;
	void push_back(const string & chaine) {
		vector<ChaineCar*>::push_back(new ChaineCar(chaine.c_str()));
	}

	void pop_back() {
		delete vector<ChaineCar*>::back();
		vector<ChaineCar*>::pop_back();
	}

	void resize(long nouvtaille);

	//	void Suppr (unsigned long pos) {if (pos >= size()) throw Anomalie(1); delete (operator[](pos)); erase(begin()+pos);};
	void Suppr(unsigned long pos);

	const Titre& operator=(const Titre &rval);
	bool operator==(const Titre &rval);
	Titre operator+(const Titre &rval) const;

	//string & affiche() const;

public:

	struct Anomalie {
		Anomalie(int i) :
			le_pb(i) {
		}

		// 1-> titre inexistant
		int le_pb;
	};
};

void GetLigneFlot(istream& entree, string & ligne);

} //namespace biolib {
} //namespace vecteurs {

#endif

