/*
 *  mach.cpp
 *  States Machines
 */

#include "mach.h"


/// Classe transition
Transition::Transition(char caractere, Etat * etat) {
	m_lettre = caractere;
	p_etat = etat;
}
void Transition::set(char caractere, Etat * etat) {
	m_lettre = caractere;
	p_etat = etat;
}
Etat * Transition::etat() {
	return p_etat;
}
char Transition::lettre() {
	return m_lettre;
}



/// Classe Etat
Etat::Etat() {
	m_initial = false;
	m_final = false;
}
Etat::Etat(bool initial, bool final) {
	m_initial = initial;
	m_final = final;
}
void Etat::setInitial(bool s) {
	m_initial = s;
};
void Etat::setFinal(bool s) {
	m_final = s;
};
bool Etat::estInitial() {
	return m_initial;
}
bool Etat::estFinal() {	
	return m_final;
}

void Etat::creerTransition(char caractere, Etat * etat) {
	m_transition.push_back(new Transition(caractere, etat));
}

void Etat::supprTransition(int n) {
	m_transition.erase(m_transition.begin()+(n));
}

vector<Etat*> * Etat::transition(char complettre) {
	vector<Etat*> * t_e =new vector<Etat*>;
	
	foreach_transition {
		if((*it)->lettre() == complettre) { 
			t_e->push_back((*it)->etat());
		}
	}
	return t_e;
}
int Etat::ID() {
	return m_id;
}
void Etat::setID(int n) {
	m_id = n;
}



/// CLasse Automate
Automate::Automate() {
	
}

Automate::Automate(string fname) {
	string mot;
	int nombre, s1, s2;
	char letter;
	vector<int> initials, finals;
	
	ifstream fichier(fname.c_str(), ios::in);
	fichier >> mot; fichier >> nombre;
	for (int i=0; i<nombre; i++) {
		m_etat.push_back(new Etat);
		m_etat.at(i)->setID(i);
	}
	fichier >> mot;
	do {
		fichier >> nombre; fichier >> mot;
		initials.push_back(nombre);
	} while (mot == "and");
	do {
		fichier >> nombre; fichier >> mot;
		finals.push_back(nombre);
	} while (mot == "and");
	fichier >> m_alphabet; fichier >> mot;
	while (mot == "#") {
		fichier >> s1; fichier >> letter; fichier >> s2;
		m_etat.at(s1)->creerTransition(letter, m_etat.at(s2));
		fichier >> mot;
	}
	for (int i=0; i<initials.size(); i++)
		m_etat.at(initials.at(i))->setInitial(1);
	for (int i=0; i<finals.size(); i++)
		m_etat.at(finals.at(i))->setFinal(1);
	m_poubelle = false;
}

//*
void Automate::afficher() {
	cout << endl;
	int e; char l;
	vector<Etat*> * p_e;
	
	cout << "  E ";
	for (int i=0; i<m_alphabet; i++)
		cout << (char)('a'+i) << " ";
	foreach_etat {
		cout << endl;
		if ((*it)->estInitial()== true) cout << ">";
		else cout<< " ";
		if ((*it)->estFinal()== true) cout << "<";
		else cout << " ";
		if ((*it)->ID() != -1) cout <<(*it)->ID() << " ";
		else cout << "P ";
		for(int i=0; i<m_alphabet; i++) {
			p_e = (*it)->transition((char)'a'+i);
			if (p_e->size() > 0) {
				for(int j=0; j < p_e->size();j++) {
					if (p_e->at(j)->ID()== -1) cout << "p";
					else cout << p_e->at(j)->ID();
					if (j < p_e->size()-1 && p_e->size()>1)
						cout << ",";
					else cout << " ";
				}
			}
			else cout << ". ";
		}
	}
	cout << endl;
}
//*/

void Automate::completer() {
	bool poubelle = false;
	foreach_etat {
		for (int i=0; i<m_alphabet ;i++) {
			if ((*it)->transition('a'+i)->size() == 0) {
				if (m_poubelle == false) poubelle = true;
			}
		}
	}
	if (poubelle == true) {
		m_etat.push_back(new Etat);
		for(int i=0; i< m_alphabet; i++) 
			m_etat.at(m_etat.size()-1)->creerTransition('a'+i, m_etat.at(m_etat.size()-1));
		m_etat.at(m_etat.size()-1)->setID(-1);
		m_poubelle = true;
	}
	foreach_etat {
		for (int i=0; i<m_alphabet ;i++) {
			if ((*it)->transition('a'+i)->size() == 0) {
				
				(*it)->creerTransition((char)'a'+i, m_etat.at(m_etat.size()-1));
			}
		}
	}
}