#include <iostream>
#include <fstream>
#include "struct.h"
#include "menu.h"
using namespace std;


int main()
{
    /****DECLARATIONS****/
    Tab_Mat mat;
    Tab_Mat dij;
    int current;
    int pt_start = 0;
    bool done[mat.nombre_som];
    char * c [] = {"Charger un graphe","Lancer l'algorithme", "Quitter" } ;
    Menu * menu = new Menu("Menu principal", 3, c, "CLQ") ;
    int b=1;
    Algo algo_exec;

    /****MISE A ZERO****/

    for(int i = 0; i < mat.nombre_som; i++)
    {
        done[i] = false;
    }
    for(int i = 0; i < 50; i++)
    {
        for(int i2 = 0; i2 < 50; i2++)
        {
            mat.Tab_Mat[i][i2] = -1;
            dij.Tab_Mat[i][i2] = -1;
            algo_exec.Next[i].liste[i2] = -1;
        }
        algo_exec.longueur[i] = -1;
        algo_exec.Next[i].nb = 0;
    }

    while (b=1)
 {
     system("cls");
  menu->Affiche() ;
  int r = menu->Reponse() ;
  char chn [255] ;
  char * index ;
  char rep [3] ;
  char fichier[12] ;
  FILE * f;
  int  sommet;
  int selection;
  switch (r)
    {

      case 0 :{

        /****OUVRIR FICHIER****/

        do
        {//saisie pour choix fichier
            cout << "Quel est le fichier que vous voulez ouvir ?" << endl;
            cout << "1 : Graphe 01 | 2 : Graphe 04 | 3 : Graphe 09| 4 : Graphe 12" << endl;

            cin >> selection;
        }while(selection < 0 || selection > 4);

        char* selection_fichier;
        if(selection == 1)
            selection_fichier = "graphe.txt";
        else if(selection == 2)
            selection_fichier = "graphe2.txt";
        else if(selection == 3 || selection == 4)
            cout << "Les valeurs négatives ne peuvent être traitees par l'algorithme de dijkstra" << endl;
        //parseur et ouverture du graphe
        ifstream fichier(selection_fichier, ios::in);

        if(fichier)
        {
            int pt_start, arrivee, valeur;
            fichier >> mat.nombre_som;
            for (int i=0; i < mat.nombre_som ; i++)
            {
                mat.Tab_Mat[i][i] = 0;
            }

            do
            {
                fichier >> pt_start;
                if(pt_start != -1)
                {
                    fichier >> arrivee >> valeur;
                    mat.Tab_Mat[pt_start][arrivee] = valeur;
                }
            }while(pt_start != -1);

            fichier.close();
        }
      }
        case 1 :{
            /****LANCER ALGO****/


        system("cls");
        //choix du sommet de départ
        cout << "Sommet de debut ?" << endl << endl;
        cin >> selection;
        pt_start = selection;
        current = pt_start;
        algo_exec.longueur[pt_start] = 0;
        algo_exec.Next[pt_start].nb = 0;
        algo_exec.Next[pt_start].liste[0] = 0;
        system("cls");
        //affichage des "legendes"
         cout << "    ";
        for(int i = 0; i < mat.nombre_som; i++)
        cout << i << "      ";
        cout << endl;
        int minus;


        do
        {
            cout << endl;
            cout << current << "  ";
            for(int i = 0; i < mat.nombre_som; i++)
            {   //si l'arc existe
                if(mat.Tab_Mat[current][i] != -1)
                {
                    if(algo_exec.longueur[i] == -1 || (algo_exec.longueur[i] != -1 && algo_exec.longueur[current] + mat.Tab_Mat[current][i] < algo_exec.longueur[i]))
                    {   //on ajoute la distance et on MAJ le chemin
                        algo_exec.longueur[i] = algo_exec.longueur[current] + mat.Tab_Mat[current][i];
                        for(int i2 = 0; i2 < algo_exec.Next[i].nb; i2++)
                            algo_exec.Next[i].liste[i2] = -1;

                        if(current == pt_start)
                        {
                            algo_exec.Next[i].nb = 0;
                            algo_exec.Next[i].liste[0] = pt_start;
                        }
                        else
                        {
                            algo_exec.Next[i].nb = algo_exec.Next[current].nb + 1;
                            for(int i_nb = 0; i_nb <= algo_exec.Next[current].nb; i_nb++)
                            {
                                algo_exec.Next[i].liste[i_nb] = algo_exec.Next[current].liste[i_nb];
                            }
                            algo_exec.Next[i].liste[algo_exec.Next[i].nb] = current;
                        }
                    }
                    if(algo_exec.longueur[i] < 10)
                    cout << "  " << algo_exec.longueur[i] << "," << algo_exec.Next[i].liste[algo_exec.Next[i].nb] << " |";
                    else
                    cout << " " << algo_exec.longueur[i] << "," << algo_exec.Next[i].liste[algo_exec.Next[i].nb] << " |";
                }
                else if(algo_exec.longueur[i] != -1)
                {
                    if(algo_exec.longueur[i] < 10)
                    cout << "  " << algo_exec.longueur[i] << "," << algo_exec.Next[i].liste[algo_exec.Next[i].nb] << " |";
                    else
                    cout << " " << algo_exec.longueur[i] << "," << algo_exec.Next[i].liste[algo_exec.Next[i].nb] << " |";
                }
                else
                    cout << " ##,# |";
            }
            cout << endl;
            done[current] = true;
            minus = -1;
            //dernière ligne de l'algo au niveau du tableau
            for(int i = 0; i < mat.nombre_som; i++)
            {
                if(algo_exec.longueur[i] != -1)
                {
                    if(done[i] == false)
                    {
                        if(minus == -1)
                            minus = i;
                        else if(algo_exec.longueur[i] < algo_exec.longueur[minus])
                            minus = i;
                    }
                }
            }
            current = minus;
        }while(minus != -1);
        cout << endl;
        cout << "\t\tResultats : longueur" << endl;
        for(int i = 0; i < mat.nombre_som; i++)
        {
            if(i == pt_start)
                cout <<"\t\t"<< pt_start << " : " << pt_start << endl;

            else
            {
                cout <<"\t\t";
                for(int i_nb = 0; i_nb <= algo_exec.Next[i].nb; i_nb++)
                {
                    cout << algo_exec.Next[i].liste[i_nb] << " ";
                    cout << "- ";
                }
                cout << i << " : " << algo_exec.longueur[i] << endl;
            }
        }
        }
        system("pause");
        break;
        case 2 :
        return 0;
    }
    }
}
