#include "declaration.h"

void Automate::determinisation(vector <Etat> tab_etats_basiques)
{
    cout << "***Determinisation de l'automate***"<<endl;
    Etat_composite etat_poubelle(0);

    Etat_composite etat_compo_1er;
    etat_compo_1er.initial=true;  //premier etat composite regroupe les etats basiques initiaux
    for(int i=0;i<tab_etats_basiques.size() ; i++)       //parcours de tous les états basiques pour trouver les initiaux
    {
        if(tab_etats_basiques[i].initial)                //l'état parcouru est un initial
        {                //ajout d'un etat simple initial
            etat_compo_1er.tab_etats_simples.push_back(tab_etats_basiques[i]); //dans un vector représentant un etat composite
        }
    }
    int entier_etat_compo_1er=0;
    for(int i=0; i<etat_compo_1er.tab_etats_simples.size();i++)
    {
       entier_etat_compo_1er+=etat_compo_1er.tab_etats_simples[i].numero*pow(10,etat_compo_1er.tab_etats_simples.size()-1-i);
    }
    etat_compo_1er.numero=entier_etat_compo_1er;
    tab_etats_composites.push_back(etat_compo_1er);                 //Etat initial (premier etat composite) trouvé!
    cout << "1er tour"<<endl;

//traitement d'une ligne (un etat composite)
    int cpt_tab_etats_compo=0;
    int incr_tab_etats_composites=0;
    do
    {
// parcours tous les etats de transition possibles (a,b,c,d,e,f)
        for (char cpt_lettre='a' ; cpt_lettre<=alphabet_max ; cpt_lettre++)
        {
            Etat_composite etat_compo_finaux;
            vector <Etat> tab_etats_avec_doublons;
            system("cls");
            cout << endl << endl << "***** LETTRE : " <<cpt_lettre<<" *****"<<endl;
// parcours des etats simples de la lettre i
            for(int cpt_etat_simple_depart=0 ; cpt_etat_simple_depart<tab_etats_composites[cpt_tab_etats_compo].tab_etats_simples.size() ; cpt_etat_simple_depart++)
            {
                cout <<endl<< "Etat Simple Depart = "<<tab_etats_composites[cpt_tab_etats_compo].tab_etats_simples[cpt_etat_simple_depart].numero<<endl;
// parcours les etats d'arrivee de l'etat simple avec la transition i
                for(int cpt_parcours_lettres=0 ; cpt_parcours_lettres < tab_etats_composites[cpt_tab_etats_compo].tab_etats_simples[cpt_etat_simple_depart].tab_transitions.size() ; cpt_parcours_lettres++)
                {
// si la transition existe
                    if(cpt_lettre==tab_etats_composites[cpt_tab_etats_compo].tab_etats_simples[cpt_etat_simple_depart].tab_transitions[cpt_parcours_lettres].lettre)
                    {
                        for(int cpt_parcours_etat_simple_final=0 ; cpt_parcours_etat_simple_final < tab_etats_composites[cpt_tab_etats_compo].tab_etats_simples[cpt_etat_simple_depart].tab_transitions[cpt_parcours_lettres].tabPointeur.size() ; cpt_parcours_etat_simple_final ++)
                        {
                            tab_etats_avec_doublons.push_back(tab_etats_basiques[tab_etats_composites[cpt_tab_etats_compo].tab_etats_simples[cpt_etat_simple_depart].tab_transitions[cpt_parcours_lettres].tabPointeur[cpt_parcours_etat_simple_final].ptr_sur_etat->numero-1]);
                        }
                    }
// si la transition n'existe pas
                    else
                    {}
                }
            }

// parcours du tab_avec_doublons pour enlever les doublons d'états
            for(int n=0 ; n < tab_etats_avec_doublons.size() ; n++)
            {
                for(int p=0 ; p<tab_etats_avec_doublons.size() ; p++)
                {
                    if(tab_etats_avec_doublons[p].numero==tab_etats_avec_doublons[n].numero && n!=p)
                    {
                        tab_etats_avec_doublons.erase(tab_etats_avec_doublons.begin()+p);
                    }
                }
            }
// recopie du tableau d'etats sans doublons dans un etat composite
//***tab_etat_avec_doublons n'a en realité plus de doublons!!!!
            for(int q=0 ; q<tab_etats_avec_doublons.size() ; q++)
            {
                etat_compo_finaux.tab_etats_simples.push_back(tab_etats_avec_doublons[q]);
            }
            cout << endl;
// classement par ordre croissant des Etats
            etat_compo_finaux.tab_etats_simples.size();
            for(int j=0;j<etat_compo_finaux.tab_etats_simples.size();j++)               // *** TriABulles by MiniKrob ^^***
            {
                for(int i=0;i<etat_compo_finaux.tab_etats_simples.size()-1;i++)
                {
                    if(etat_compo_finaux.tab_etats_simples[i].numero > etat_compo_finaux.tab_etats_simples[i+1].numero)
                    {
                        int tmp=etat_compo_finaux.tab_etats_simples[i].numero;
                        etat_compo_finaux.tab_etats_simples[i].numero=etat_compo_finaux.tab_etats_simples[i+1].numero;
                        etat_compo_finaux.tab_etats_simples[i+1].numero=tmp;
                    }
                }
            }

// conversion en entier pour comparer si le nouvel etat composite final n'existe pas deja dans tab_etats_composites
            bool identique=false;
            int parcours_tab_etats_composites=0;


            if(etat_compo_finaux.tab_etats_simples.size()!=0)
            {
                int entier_tab_etat_composites=0;
                int entier_etat_compo_finaux=0;
                do
                {
                    entier_etat_compo_finaux=0;
                    entier_tab_etat_composites=0;
                    //conversion des etats simples du tab_etat_composite
                    for(int i=0 ; i<tab_etats_composites[parcours_tab_etats_composites].tab_etats_simples.size() ; i++)
                    {
                        entier_tab_etat_composites+=tab_etats_composites[parcours_tab_etats_composites].tab_etats_simples[i].numero*pow(10,tab_etats_composites[parcours_tab_etats_composites].tab_etats_simples.size()-1-i);
                    }

                    //conversion des etats simples de l'etat_compo_finaux
                    for(int i=0 ; i<etat_compo_finaux.tab_etats_simples.size() ; i++)
                    {
                        entier_etat_compo_finaux+=etat_compo_finaux.tab_etats_simples[i].numero*pow(10,etat_compo_finaux.tab_etats_simples.size()-1-i);
                    }
                    cout << endl;

                    if(entier_etat_compo_finaux==entier_tab_etat_composites)
                    {
                        identique=true;//cout<<entier_etat_compo_finaux<<"=="<<entier_tab_etat_composites<<endl;
                    }
                    else
                    {
                        identique=false;//cout<<entier_etat_compo_finaux<<"!="<<entier_tab_etat_composites<<endl;
                    }

                    parcours_tab_etats_composites++;
                }while(identique==false && parcours_tab_etats_composites<tab_etats_composites.size());
                etat_compo_finaux.numero=entier_etat_compo_finaux; //donne un numero
                tab_etats_composites[cpt_tab_etats_compo].tab_etats_composites_destination.push_back(etat_compo_finaux); //devient un etat de destination de etat composite precedent
                if(identique==false)
                {
                    tab_etats_composites.push_back(etat_compo_finaux);          //dans le grand tableau
                    incr_tab_etats_composites ++;
                    //L'etat composite "<<etat_compo_finaux.numero << " a ete ajoute"
                }
                else
                {
                   //L'etat existe deja, on ne l'ajoute pas
                }
            }
            else //etat poubelle
            {
                //Pas de transition avec cette lettre
                tab_etats_composites[cpt_tab_etats_compo].tab_etats_composites_destination.push_back(etat_poubelle);
            }
            cout << cpt_tab_etats_compo<<"eme tour"<<endl;


//AFFICHAGE
                    for(int i=0;i<tab_etats_composites.size();i++)
                    {
                    cout <<endl<< tab_etats_composites[i].numero;
                    for(int j=0 ; j<tab_etats_composites[i].tab_etats_composites_destination.size();j++)
                    {

                    cout <<  "\t"<<  tab_etats_composites[i].tab_etats_composites_destination[j].numero;
                    }
                    }
                    cout<< endl;
                    system("pause");
// AFFICHAGE






        }
        cpt_tab_etats_compo++;
        system("cls");
//fin de traitement d'une ligne (un etat composite) : fin lorsqu'on a plus de nouvel etat composite
    }while(incr_tab_etats_composites+1 != cpt_tab_etats_compo);

// assignation des etats composites finaux
    cout << "Assignation des etats composites finaux"<<endl;//assignation des etats composites finaux
    cout<<endl<<"Les etats ";
    for(int i=0; i<tab_etats_composites.size();i++)
    {
        for(int j=0; j<tab_etats_composites[i].tab_etats_simples.size() ; j++)
        {
            if(tab_etats_composites[i].tab_etats_simples[j].final==true)
            {
                tab_etats_composites[i].final=true;
                cout<< tab_etats_composites[i].numero;
                cout <<" ; ";
            }
        }
    }
    cout << " sont finaux"<<endl;

    system("pause");
}
