#include <iostream>
#include <fstream>
#include "struct.h"
#include <string.h>

//TP ORDONNANCEMENT REALISE PAR NICOLAS HUBERT ET ANTONIN LAPICHE PROMO2012 GROUPE C

using namespace std;



int main()
{

    int selection;
    char* selection_fichier;


    Tache tab_tache[15];
    Arc tab_arc[50];

    do
    {
        system("cls");
        cout << "Quel fichier de contraintes charger ?" << endl;
        cout << "1-C01" << endl;
        cout << "2-C02" << endl;
        cout << "3-C03" << endl;

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

    if(selection == 1)
    {
        selection_fichier = "c01.txt";
    }
    else if(selection == 2)
    {
        selection_fichier = "c02.txt";
    }
    else if(selection == 3)
    {
        selection_fichier = "c03.txt";
    }

    ifstream fichier(selection_fichier, ios::in);
    int taille=0;
    if(fichier)
    {
        int duree_f;
        char tache_f, contrainte_f;
        fichier >> taille;
        int cpt=0;

        do
        {
            fichier >> tache_f;
            if(tache_f!= '#')
            {
                fichier >> duree_f;

                tab_tache[cpt].task=tache_f;
                tab_tache[cpt].duree=duree_f;

                int cpt2=0;
                fichier >> contrainte_f;
                while((contrainte_f) != '*' )
                {
                    tab_tache[cpt].contraintes[cpt2]=contrainte_f;
                    cpt2++;
                    fichier >> contrainte_f;
                };
                tab_tache[cpt].nb_contraintes=cpt2;

            }
            cpt++;
        }while(tache_f != '#');

        fichier.close();
    }

    for (int lol=0; lol < taille ; lol++)
    {
        cout << "Tache:" <<tab_tache[lol].task << " "<< "Duree:" <<tab_tache[lol].duree << " " << "Contraintes:" ;

        if(tab_tache[lol].nb_contraintes == 0)
        {
            cout << "Aucune";
        }
        else
        {
            for (int lol2=0; lol2 < tab_tache[lol].nb_contraintes; lol2++)
            {
                cout << tab_tache[lol].contraintes[lol2];
            }
        }
        cout << endl;
    }

    int cpt_arc=0;


    for(int cpt_parcours_contraintes=0; cpt_parcours_contraintes < taille; cpt_parcours_contraintes++) // parcours ligne par ligne des tableaux de contraintes
    {
        if((tab_tache[cpt_parcours_contraintes].nb_contraintes == 0))
        {
            tab_arc[cpt_arc].initiale='*';
            tab_arc[cpt_arc].duree=0;
            tab_arc[cpt_arc].terminale=tab_tache[cpt_parcours_contraintes].task;
            cpt_arc++;
        }
    }

    for(int cpt_taille_tache=0; cpt_taille_tache < taille ; cpt_taille_tache++) // parcours ligne par ligne le tableau des taches
    {
        char tache_en_cours;
        bool traite_aumoins_une_fois=false;

        tache_en_cours=tab_tache[cpt_taille_tache].task; // stock la tache en cours lu ligne par ligne dans le tableau des taches

        for(int cpt_parcours_contraintes=0; cpt_parcours_contraintes < taille; cpt_parcours_contraintes++) // parcours ligne par ligne des tableaux de contraintes
        {
                for (int cpt_contraintes=0; cpt_contraintes < tab_tache[cpt_parcours_contraintes].nb_contraintes ; cpt_contraintes++) // parcours colonne par colonne les contraintes
                {
                    if ( tache_en_cours == tab_tache[cpt_parcours_contraintes].contraintes[cpt_contraintes])
                    {
                        tab_arc[cpt_arc].initiale=tache_en_cours;
                        tab_arc[cpt_arc].duree=tab_tache[cpt_taille_tache].duree;
                        tab_arc[cpt_arc].terminale=tab_tache[cpt_parcours_contraintes].task;
                        traite_aumoins_une_fois=true;
                        cpt_arc++;
                    }
                }
            }

        if(traite_aumoins_une_fois==false)
        {
                tab_arc[cpt_arc].initiale=tache_en_cours;
                tab_arc[cpt_arc].duree=tab_tache[cpt_taille_tache].duree;
                tab_arc[cpt_arc].terminale='@';
                traite_aumoins_une_fois=true;
                cpt_arc++;

        }


    }

    cout << endl<<endl;
    for (int lol=0; lol < cpt_arc ; lol++)
    {
        cout << "Ini:" <<tab_arc[lol].initiale << " "<< "Dur:" <<tab_arc[lol].duree << " " << "Ter:" << tab_arc[lol].terminale;
        cout << endl;
    }

    Date tab_date[taille+1]; // +1 pour stocker les n tache +apha + terminale
    int cpt_tab_date=0;

    //initialisation d'aplha
    tab_date[cpt_tab_date].task='*';
    tab_date[cpt_tab_date].tot=0;
    tab_date[cpt_tab_date].tard=0;
    cpt_tab_date++;

    //initialisation des nom de taches
    for(int cptx=1;cptx < taille+1; cptx++)
    {
        tab_date[cptx].task=tab_tache[cptx-1].task;
        tab_date[cptx].tot=0;
        tab_date[cptx].tard=0;
    }
     tab_date[taille+1].task='@';
     tab_date[taille+1].tot=0;

    //initialisation des taches sans contraintes
    for(int cpt_parcours_contraintes=0; cpt_parcours_contraintes < taille; cpt_parcours_contraintes++) // parcours ligne par ligne des tableaux de contraintes
    {
        if((tab_tache[cpt_parcours_contraintes].nb_contraintes == 0))
        {
            tab_date[cpt_tab_date].tot=0;

            cpt_tab_date++;
        }
    }


// DEBUT   Calcul DATE AU PLUS TOT
do
{
    for(int cpt_tab_arc_term=0; cpt_tab_arc_term < cpt_arc ; cpt_tab_arc_term++)
    {
        if(tab_arc[cpt_tab_arc_term].terminale == tab_date[cpt_tab_date].task)
        {
            int ascii=tab_arc[cpt_tab_arc_term].initiale;
            int ascii2='A'; // Comme le fichier est écrit par nous même on peut se permettre ceci

            if( tab_date[cpt_tab_date].tot < ((tab_date[(ascii - ascii2)+1].tot)+tab_arc[cpt_tab_arc_term].duree) )
            {
                tab_date[cpt_tab_date].tot = ((tab_date[(ascii - ascii2)+1].tot)+tab_arc[cpt_tab_arc_term].duree);
            }
        }
    }
    cpt_tab_date++;

}while(cpt_tab_date != taille+2);

//   FIN    Calcul DATE AU PLUS TOT

    //initialisation des nom de taches
    for(int cptx=1;cptx < taille+1; cptx++)
    {
        tab_date[cptx].tard=tab_date[taille+1].tot+3;
    }



//  DEBUT   Calcul DATE AU PLUS TARD

    tab_date[taille+1].tard=tab_date[taille+1].tot+3; // RETARD DE 3
    tab_date[0].tard=3;// RETARD DE 3

cpt_tab_date=taille;
do
{
    for(int cpt_tab_arc_term=cpt_arc; cpt_tab_arc_term > 0; cpt_tab_arc_term--)
    {
        if(tab_arc[cpt_tab_arc_term].initiale == tab_date[cpt_tab_date].task)
        {
            int asci=tab_arc[cpt_tab_arc_term].terminale;

            int ascii=tab_arc[cpt_tab_arc_term].initiale;
            //int ascii2='A'; // Comme le fichier est écrit par nous même on peut se permettre ceci
            //int ascii3= ascii - ascii2+1;
            int asci2;

            if(asci==64)
            {
                asci2=taille+1;
            }

            else
            {
                asci2= (tab_arc[cpt_tab_arc_term].terminale) -'A'+1;
            }

            if( tab_date[cpt_tab_date].tard > (tab_date[asci2].tard)-tab_arc[cpt_tab_arc_term].duree )
            {
                tab_date[cpt_tab_date].tard = ((tab_date[asci2].tard)-tab_arc[cpt_tab_arc_term].duree);
            }
        }
    }
    cpt_tab_date--;

}while(cpt_tab_date > 0 );

// Marge totale
for(int cptt=0;cptt <taille+2;cptt++)
{
    tab_date[cptt].libre=tab_date[cptt].tard-tab_date[cptt].tot;
}
//

//Marge libre
cpt_tab_date=1;

tab_date[0].libre=0;


do
{
    int min=999999;
    int duree;

    for(int cpt_tab_arc_init=0; cpt_tab_arc_init < cpt_arc ; cpt_tab_arc_init++)
    {

        if(tab_arc[cpt_tab_arc_init].initiale == tab_date[cpt_tab_date].task)
        {

            for(int cptlol=1; cptlol<taille+2;cptlol++)
            {
                if((tab_arc[cpt_tab_arc_init].terminale) == tab_date[cptlol].task)
                {
                    if (min > tab_date[cptlol].tot)
                    {
                        cout << " " << tab_date[cptlol].task<<" tot= " <<tab_date[cptlol].tot<<endl;
                        min=tab_date[cptlol].tot;
                        duree=tab_arc[cpt_tab_arc_init].duree;

                    }
                }
            }
        }

    }
    tab_date[cpt_tab_date].libre=min-duree-tab_date[cpt_tab_date].tot;
    cpt_tab_date++;

}while(cpt_tab_date != taille+1);

//

//Affichage
    cout << endl<< endl;
    for (int lol=0; lol < taille+1 ; lol++)
    {
        cout << "task:" <<tab_date[lol].task << " "<< "tot: " <<tab_date[lol].tot << " "<< "tard: " <<tab_date[lol].tard << " "<< "Marge totale: " <<tab_date[lol].libre ;
        cout << endl;
    }
    cout << "task:" <<tab_date[taille+1].task << " "<< "tot: " <<tab_date[taille+1].tot << " "<< "tard: " <<tab_date[taille+1].tard << " "<< "Marge totale:  "  ;
    cout << endl;


    cout << "\t| *";
    for (int lol=0; lol < taille+1 ; lol++)
    {
        cout << "\t| " << tab_tache[lol].task;

    }
    cout << endl;
    cout << " +tot  ";
    for (int lol=0; lol < taille+1 ; lol++)
    {
        cout << "\t| " << tab_date[lol].tot;

    }
        cout << endl;
    cout << " +tard ";
    for (int lol=0; lol < taille+1 ; lol++)
    {
        cout << "\t| " << tab_date[lol].tard;

    }
    cout << endl;
    cout << " Mlibre";
    for (int lol=0; lol < taille+1 ; lol++)
    {
        cout << "\t| " << tab_date[lol].libre;

    }


    cout << endl<< endl;

    system("pause");

    return 0;
}
