#include "main.h"
using namespace std;


bool lecture (graphe &dj,string mon_fichier ) {


    ifstream File;

    File.open(mon_fichier.c_str());
    string tmp;

    if(File) {
        // On elimine la première ligne
        File >> tmp;

        // Recupéreration du nbSommets
        File >> tmp;

        /** Nous considérons que le fichier est bien formaté */
        cout << " Nombre de sommet : " << tmp << endl;
        while(tmp != "nb_arc") {
          dj.nbSommets = atoi(tmp.c_str());
          File >> tmp;
        }

        while(tmp != "graphe") {
          dj.nbArcs= atoi(tmp.c_str());
          File >> tmp;
        }

        File >> tmp;
        while(tmp != "FIN") {
          dj.Initial.push_back(atoi(tmp.c_str()));
          File >> tmp;
          dj.Val.push_back(atoi(tmp.c_str()));
          File >> tmp;
          dj.Term.push_back(atoi(tmp.c_str()));
          File >> tmp;
        }

    }
    return true ;
}

bool matrice ( graphe &dj )  {

    /** Initialisation des deux matrices */

    dj.matrixAdj = new int*[dj.nbSommets];
    dj.matrixVal = new int*[dj.nbSommets];

    for( int i = 0; i < dj.nbSommets; i++) {
       dj.matrixAdj[i] = new int[dj.nbSommets];
       dj.matrixVal[i] = new int[dj.nbSommets];
    }

    for (  int i = 0 ; i < dj.nbSommets ; i++ ){
        for (  int j = 0; j < dj.nbSommets ; j++ ){
            dj.matrixAdj[i][j]=0;
            dj.matrixVal[i][j]=-1;
        }
    }
    return true;
}

void printMatriceAdj (int ** mat,graphe dj){

    cout << " Affichage Matrice Adj " << endl;
  /*  for (  int j = 0; j < dj.nbSommets ; j++ ){
        cout << j << " | ";}
    cout << endl;
*/
    for (  int i = 0 ; i < dj.nbSommets ; i++ ){

        for (  int j = 0; j < dj.nbSommets ; j++ ){
            cout << mat[i][j] << " | ";
         }
        cout << endl;
    }
}

void printMatriceVal (int ** mat,graphe dj){

    cout << " Affichage Matrice Val " << endl;
 /*   for (  int j = 0; j < dj.nbSommets ; j++ ){
        cout << j << " | ";}
    cout << endl;
*/
    for (  int i = 0 ; i < dj.nbSommets ; i++ ){

        for (  int j = 0; j < dj.nbSommets ; j++ ){
            cout << mat[i][j] << " | ";
         }
        cout << endl;
    }
}

bool matriceAdj ( graphe & dj) {

    for (  int i = 0 ; i < dj.nbSommets ; i++ ){
        for (  int j = 0; j < dj.nbSommets ; j++ ){
            for (unsigned int k = 0; k < dj.Initial.size(); k++ ){
                if ( (dj.Initial[k] == i ) && ( dj.Term[k] == j ) ) {
                     dj.matrixAdj[i][j] =1;
                }
            }
        }
    }
    return true;
}

bool matriceVal ( graphe & dj) {

    for (  int i = 0 ; i < dj.nbSommets ; i++ ){
        for (  int j = 0; j < dj.nbArcs; j++ ){
            for (unsigned int k = 0; k < dj.Initial.size(); k++ ){
                if ( (dj.Initial[k] == i ) && ( dj.Term[k] == j )  ) {
                    dj.matrixVal[i][j] =dj.Val[k];
                }
            }
        }
    }
    return true;
}

bool djikstra (graphe & dj,int enter ) {

    dj.CC= new bool(dj.nbSommets);
    struct way *chemin;
    chemin = new way[dj.nbSommets];
    int actual=enter;
    int tmp;


    for (int i=0; i < dj.nbSommets; i++){
        if (i != enter ){
            dj.CC[i]=false;
            chemin[i].cout = -1;
            chemin[i].prec = -1;

        }else{
            dj.CC[i]=true;
            chemin[i].cout = enter;
            chemin[i].prec = enter;
        }
    }

        // Algorithme de calcul
    for (int i=0; i< dj.nbSommets; i++) {


        // Recherche du chemin court
        for (int j=0 ;j < dj.nbArcs; j++ ){


            if ( dj.Initial[j] == actual){
                tmp = chemin[actual].cout + dj.Val[j];
                if ( ( tmp < chemin[dj.Term[j]].cout ) || ( chemin[dj.Term[j]].cout  == -1 ) ){

                    chemin[dj.Term[j]].cout = tmp;
                    chemin[dj.Term[j]].prec = actual;
                }
            }

        }

        tmp = -1;
        // next sommet
        for (int j=0 ;j < dj.nbSommets; j++ ){
            if ( ( chemin[j].cout != -1 )  && ( ! dj.CC[j] )){
                if (( tmp == -1 ) || (tmp > chemin[j].cout ) ){
                    tmp = chemin[j].cout;
                    actual=j;
                }
            }

        }
        dj.CC[actual]=true;

    }
    for (int j=0 ;j < dj.nbSommets; j++ ){
        cout << " Meilleurs chemin : " << j << " = " << chemin[j].cout << endl;
    }
    return true;
}

int main(int argc, char*argv[]){
string mon_fichier;

/** Le point d'entrer est par defaut le premier noeud recuperer dans la lecture du fichier */



int tab[]={1,2,3,4};

for (unsigned int i= 0; i<4; i++){
    cout << tab[i] << endl;
}

cout << endl;
for (unsigned int i=3; 0< i; i--){
    tab[i]=tab[i-1];
}
for (unsigned int i= 0; i<4; i++){
    cout << tab[i] << endl;
}


return 0;
    graphe dj;


    if ( ! lecture (dj, mon_fichier) ) return EXIT_FAILURE ; // TODO : verif a rajouter


    if ( ! matrice (dj) ) return EXIT_FAILURE ;

    int enter = dj.Initial[0];
       // calcule de la matrice d'adjacense
    matriceAdj( dj);
        // calcule de la matrice des valeurs
    matriceVal(dj);

    // affichage
    printMatriceAdj( dj.matrixAdj,dj );
    printMatriceVal( dj.matrixVal,dj );

    cout << " Calcule de l'algorithme' " << endl;

    djikstra(dj,enter);

    cout << "FINI " << endl;
    return 0;
}

