/**
 * \file 	specification1.h
 * \brief 	Mise en place des structures et des fonctions associées
 * \authors LAVERGNE Rémi ; DELINAC Inès ; RAYNAUD Camille
 * \date 	12 janvier 2024
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#define MAX_LENGTH 30

//~~~~~~~~~~~~~~~~~~~~~~~~~~~STRUCTURES~~~~~~~~~~~~~~~~~~~~~~~~~~~

typedef struct
{
	int numero;
	char rue[30];
	int codePostal;
	char ville[30];
} Adresse;

typedef struct
{
	char entreprise[MAX_LENGTH];
	Adresse adresse;
	int capital;
	int duree;
	int cout;
} Devis;

typedef struct maillonDevis
{
	Devis devis;
	struct maillonDevis *suiv;
} MaillonDevis, *ListeDevis;

typedef struct
{
	char travaux[MAX_LENGTH];
	ListeDevis ldevis;
} Offre, *TabTravaux;

// = Structure pour les tâches =

typedef struct maillonsucc
{
    char nomSucc[20];
    struct maillonsucc *suiv;
} MaillonSucc, *Liste;

typedef struct
{
    char tache[20];
    int duree;
    int nbPred;
    Liste succ;
    int dateDebut;
    bool traite;
} Tache;

// = Structure pour la File d'attente =

typedef struct maillonfile
{
    Tache *tache;
    struct maillonfile *suiv;
} MaillonFile;

typedef struct
{
    MaillonFile *debut;
    MaillonFile *fin;
} FileAttente;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~FONCTIONS~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// == Affichage ==

void afficherDevis(Devis devis);
void afficherListeDevis(ListeDevis l);
void afficherDevisEntreprise(TabTravaux tabTravaux, int tLog, char entreprise[], char typeTravaux[]);
void afficherDevisTravaux(ListeDevis l, char travaux[]);
void selectionEntreprisesRetenues(ListeDevis* ldevis);
void afficherEntreprisesRetenues(TabTravaux tab, int tLog);

// == Chargement ==

int chargement(TabTravaux *tab, int *tLog, char fichier[]);
void lireDevis(FILE *flot, Devis *devis, char *typeTravaux);
void insererDevis(Devis d, TabTravaux *tab, int *tLog, char typeTravaux[]);

// == Precedences ==

Tache* initialiserTache(char *nom, int duree);
Tache** chargementTaches(TabTravaux *tab, int tLog, int *nbTaches, char fichier[]);
int recupererDuree(TabTravaux tabTravaux, int tLog, char typeTravaux[]);
void ajouterSuccesseur(Tache *tache, char nomSucc[]);

// == Recherche dichotomique ==

int rechercheDichotomique(TabTravaux tab, int tLog, char typeTravaux[]);
int rechercheDichotomiqueTaches(Tache **tabTaches, int nbTaches, char nomTache[]);

// == Tris ==

void trierListeDevis(ListeDevis *ldevis);
void insererDevisTriee(ListeDevis *ldevis, MaillonDevis *maillon);
void triEchange(ListeDevis *ldevis);
int comparer(const Devis* d1, const Devis* d2);
void inverser(Devis* d1, Devis* d2);

// == Free ==

void libererTabTravaux(TabTravaux *tab, int tLog);
void libererOffre(Offre *offre);
void libererListeDevis(ListeDevis liste);
void libererListeSucc(Liste succ);
void libererTache(Tache *tache);
void libererTabTaches(Tache **tabTaches, int nbTaches);

// == Sauvegarde ==

void sauvegardeTaches(Tache **tabTaches, int nbTaches, char fichier[]);
void sauvegardeDevis(TabTravaux tab, int tLog, char fichier[]);
void ecrireDevis(FILE *flot, char typeTravaux[], Devis devis);
void sauvegardeDevisBinaire(TabTravaux tab, int tLog, char fichier[]);
void sauvegardeTachesBinaire(Tache **tabTaches, int nbTaches, char fichier[]);

// == File ==

FileAttente initialiserFileAttente();
bool estVide(FileAttente *file);
void enfiler(FileAttente *file, Tache *tache);
Tache* tete(FileAttente *file);
void defiler(FileAttente *file);
int longueur(FileAttente *file);
void afficherFile(FileAttente *file);
void detruireFile(FileAttente *file);